在前面的篇章中,我们通过入门案例 以及 Mybatis 核心配置文件的标签说明,已经大概了解了一下 Mybatis 的基础使用。
那么下面我们再来看看如何使用 Mybatis 来完成数据库的增删改查等操作。
创建用户表,使用MyBatis完成下面的SQL操作
create table user (
id int primary key auto_increment,
username varchar(20) not null,
birthday date,
sex char(1) default '男',
address varchar(50)
);
insert into user values (null, '孙悟空','1980-10-24','男','花果山水帘洞');
insert into user values (null, '白骨精','1992-11-12','女','白虎岭白骨洞');
insert into user values (null, '猪八戒','1983-05-20','男','福临山云栈洞');
insert into user values (null, '玉面狐','1995-03-22','女','积雷山摩云洞');
insert into user values (null, '玉兔精','2010-02-12','女','天竺国皇宫');
insert into user values (null, '豹子精','2008-05-03','男','隐雾山折岳洞');
MyBatis事务管理如果选择JDBC方式,那么增加、删除、修改数据库时需要手动提交事务
事务的提交有如下2种方式
自动提交事务
factory.openSession(true);
手动提交事务
session.commit();
说明:如果在同一个方法中,有多个数据库操作,需要使用手动提交的方式,可以提高执行效率
参考我之前的篇章《MyBatis入门案例》,搭建完毕之后的项目结构如下:
在完成了项目搭建之后,下面我们来实现增删查改等操作。
首先需要在接口定义一个执行SQL的接口方法,后续使用该方法进行查询。
public interface UserMapper {
/**
查询所有的用户
*/
List<User> findAllUsers();
/**
* 查询用户总数
*/
int findSum();
}
在 UserMapper.xml 文件中编写映射 findSum()
接口方法的查询 SQL。
<!--
查询语句: 查询用户的总数
id: 接口中方法的名字
resultType:返回的实体类的类型,类全名
-->
<select id="findSum" resultType="int">
select count(*) from user
</select>
// 测试查询用户总数 count(*)
@Test
public void test02() throws IOException {
//1. 得到输入流对象
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//2. 创建会话工厂建造类
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3. 通过建造类得到会话工厂类
SqlSessionFactory factory = builder.build(inputStream);
//4. 通过会话工厂得到会话对象
SqlSession session = factory.openSession();
//5. 会话对象得到UserMapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
//6. 执行查询用户总数
System.out.println("用户总数: " + userMapper.findSum());
//7. 关闭会话
session.close();
}
从上面的操作中,我们成功执行SQL,查询出了用户总数。
上面我们已经成功查询出了用户总数,下面来看看如何新增插入用户信息。而新增查询用户信息是需要传递参数的,下面我们来看看如何操作。
public interface UserMapper {
/*
* # 增加一个用户
* sql :
* insert into user values(null,?,?,?,?);
*
* 参数: 4个参数封装一个user对象
* 返回值: 被影响的行数 ( int类型 )
* */
int addUser(User user);
}
通过直接传递一个 user 对象作为插入的数据参数,进行数据插入。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
实体类的映射文件
namespace 指定接口的类全名
-->
<mapper namespace="com.lijw.dao.UserMapper">
<!--
insert,update,delete标签的默认返回值就是int
# 标签内的sql语句要引用参数的话
占位符 #{变量名}
1). 如果参数是一个javabean, 那么使用其属性 -> #{变量名}
2). 如果参数是一个简单类型 -> #{变量名}
-->
<insert id="addUser">
insert into user values(null,#{username},#{birthday},#{sex},#{address});
</insert>
</mapper>
在上面的参数传递中,我们因为传递的是一个 user 对象,也就是 javabean,那么直接使用其属性即可 #{变量名}
或者 #{user.username}
// 测试插入数据
@Test
public void test03() throws Exception {
//1. 得到输入流对象
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//2. 创建会话工厂建造类
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3. 通过建造类得到会话工厂类
SqlSessionFactory factory = builder.build(inputStream);
//4. 通过会话工厂得到会话对象
//4.1 自动提交事务 factory.openSession(true);
//4.2 手动提交事务 session.commit();
SqlSession session = factory.openSession(true);
//5. 会话对象得到UserMapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
//6. 执行插入一个user对象
//6.1 创建user对象
User user = new User();
//6.1.1 设置username
user.setUsername("李小白");
//6.1.2 设置字符串的日期
String str = "2021-03-13";
// 使用SimpleDateFormat将其解析为 Date 对象
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date date = simpleDateFormat.parse(str);
// 再将date设置为 java.sql.Date
java.sql.Date date1 = new java.sql.Date(date.getTime());
// System.out.println(date1);
// 设置user的生日
user.setBirthday(date1);
// 6.1.3 设置 sex
user.setSex("男");
// 6.1.4 设置 address
user.setAddress("湖南嚼槟榔的那嘎达地方");
// 6.2 调用插入数据的方法
int i = userMapper.addUser(user);
System.out.println("插入数据的行数: " + i);
//7. 关闭会话
session.close();
}
package com.lijw.dao;
import com.lijw.entity.User;
import java.util.List;
/**
* 数据访问层方法
*
* @author Aron.li
* @date 2021/3/9 0:09
*/
public interface UserMapper {
/**
* # 根据id查询用户
* sql :
* select * from user where id = ?
* 参数 : int id
* 返回值:user对象
*/
User findUserById(int id);
}
<!--
根据id查询用户
-->
<select id="findUserById" resultType="user">
select * from user where id = #{id}
</select>
// 测试根据id查询用户
@Test
public void test04() throws Exception {
//1. 得到输入流对象
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//2. 创建会话工厂建造类
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3. 通过建造类得到会话工厂类
SqlSessionFactory factory = builder.build(inputStream);
//4. 通过会话工厂得到会话对象
//4.1 自动提交事务 factory.openSession(true);
//4.2 手动提交事务 session.commit();
SqlSession session = factory.openSession(true);
//5. 会话对象得到UserMapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
//6. 根据ID查询用户user对象
User user = userMapper.findUserById(3);
System.out.println("查询id=3的user: " + user);
//7. 关闭会话
session.close();
}
/*
# 修改一个用户
sql:
update user set
username=?,birthday=?,sex=?,address=?
where id = ?
参数: 一个user对象
返回值: int
*/
int updateUserById(User user);
<!-- 根据id修改用户信息 -->
<update id="updateUserById">
update user set
username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id = #{id}
</update>
// 测试根据id更新用户信息
@Test
public void test05() throws Exception {
//1. 得到输入流对象
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//2. 创建会话工厂建造类
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3. 通过建造类得到会话工厂类
SqlSessionFactory factory = builder.build(inputStream);
//4. 通过会话工厂得到会话对象
//4.1 自动提交事务 factory.openSession(true);
//4.2 手动提交事务 session.commit();
SqlSession session = factory.openSession(true);
//5. 会话对象得到UserMapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
//6. 设置修改 id = 2 的 user对象
//6.1 创建user对象
User user = new User();
// 设置id
user.setId(2);
//设置username
user.setUsername("杜甫");
// 设置字符串的日期
String str = "2021-03-13";
// 使用SimpleDateFormat将其解析为 Date 对象
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date date = simpleDateFormat.parse(str);
// 再将date设置为 java.sql.Date
java.sql.Date date1 = new java.sql.Date(date.getTime());
// System.out.println(date1);
// 设置user的生日
user.setBirthday(date1);
// 设置 sex
user.setSex("男");
// 设置 address
user.setAddress("湖南嚼槟榔的那嘎达地方");
// 6.2 调用根据id更新用户数据的方法
int i = userMapper.updateUserById(user);
System.out.println("更新的行数: " + i);
//7. 关闭会话
session.close();
}
package com.lijw.dao;
import com.lijw.entity.User;
import java.util.List;
/**
* 数据访问层方法
*
* @author Aron.li
* @date 2021/3/9 0:09
*/
public interface UserMapper {
/*
* # 删除一个用户
* sql :
* delete from user where id = ?
*
* 参数: 就一个int
* 返回值: int
* */
int deleteUserById(int id);
}
<!-- 根据id删除用户信息 -->
<delete id="deleteUserById">
delete from user where id = #{id}
</delete>
// 测试根据id删除用户信息
@Test
public void test06() throws Exception {
//1. 得到输入流对象
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//2. 创建会话工厂建造类
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3. 通过建造类得到会话工厂类
SqlSessionFactory factory = builder.build(inputStream);
//4. 通过会话工厂得到会话对象
//4.1 自动提交事务 factory.openSession(true);
//4.2 手动提交事务 session.commit();
SqlSession session = factory.openSession(true);
//5. 会话对象得到UserMapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
//6. 删除 id = 1 的 user对象
int i = userMapper.deleteUserById(1);
System.out.println("删除的行数: " + i);
//7. 关闭会话
session.close();
}
在上面写的增删查改的操作中,我们可以发现有很多重复的代码,如下:
下面我们可以将重复的部分抽为一个工具类。另外,我们在结束的时候还可以设置手动提交事务,以及事务的回滚操作。
创建 utils 包,创建 MyBatisUtil.java 如下:
package com.lijw.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/**
*
* MyBatis工具类
*
* @author Aron.li
* @date 2021/3/14 7:43
*/
public class MyBatisUtil {
// 定义获取sqlSession的工厂
static SqlSessionFactory factory;
// 静态代码块:读取核心配置文件获取工厂
static{
try {
//1. 加载核心配置文件
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//2. 创建会话工厂建造类
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3. 通过建造类得到会话工厂类
factory = builder.build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取sqlsession,用一次调用一次
public static SqlSession getSqlSession(){
//4. 创建连接会话
SqlSession sqlSession = factory.openSession();
return sqlSession;
}
//提交并释放
public static void commitAndClose(SqlSession sqlSession){
if(sqlSession != null){
sqlSession.commit();
sqlSession.close();
}
}
//回滚并释放
public static void rollbackAndClose(SqlSession sqlSession){
if(sqlSession != null){
sqlSession.rollback();
sqlSession.close();
}
}
}
// 使用MyBatisUtil工具类
@Test
public void test07() throws IOException {
// 1. 获取 sqlSession 数据库连接会话
MyBatisUtil myBatisUtil = new MyBatisUtil();
SqlSession sqlSession = myBatisUtil.getSqlSession();
// 2. 执行查询操作
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> allUsers = mapper.findAllUsers();
for (User user : allUsers) {
System.out.println(user);
}
// 3. 关闭会话
myBatisUtil.commitAndClose(sqlSession);
}