MyBatis笔记02 实现CRUD
coconutnut

https://www.bilibili.com/video/av47952553
p21~27, 44

用户的持久层接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface IUserDao {
// 增
void saveUser(User user);

// 删
void deleteUser(Integer userId);

// 改
void updateUser(User user);

// 查
List<User> findAll();
User findById(Integer userId);
List<User> findByName(String username);
int findTotal();
}

配置与测试(以查所有为例)

查询操作的映射

1
2
3
4
<!-- 查询所有 -->
<select id="findAll" resultType="com.itheima.domain.User">
select * from user;
</select>

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class MybatisTest {

private InputStream in;
private SqlSession sqlSession;
private IUserDao userDao;

@Before // 用于在测试方法执行之前执行
public void init() throws Exception{
// 1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
// 3.获取SqlSession对象
sqlSession = factory.openSession();
// 4.获取dao的代理对象
userDao = sqlSession.getMapper(IUserDao.class);
}

@After // 用于在测试方法执行之后执行
public void destroy() throws Exception{
// 5.提交事务
sqlSession.commit();
// 6.释放资源
sqlSession.close();
in.close();
}

/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<User> users = userDao.findAll();
for(User user : users){
System.out.println(user);
}

}
}

CRUD

1
2
3
4
5
6
7
8
<!-- 保存用户 -->
<insert id="saveUser" parameterType="com.itheima.domain.User">
<!-- 配置插入操作后,获取插入数据的id -->
<selectKey keyProperty="userId" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,address,sex,birthday)values(#{userName},#{userAddress},#{userSex},#{userBirthday});
</insert>
1
2
3
4
5
6
User user = new User();
user.setUserName("AAA");
user.setUserAddress("北京市顺义区");
user.setUserSex("男");
user.setUserBirthday(new Date());
userDao.saveUser(user);

可以在新增用户后获取id

在saveUser前后打印user,可以发现id从null变为值

1
2
3
4
<!-- 删除用户-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{uid}
</delete>

这里uid,传基本类型或基本类型包装类时,占位符可以随便写

1
userDao.deleteUser(48);

1
2
3
4
<!-- 更新用户 -->
<update id="updateUser" parameterType="com.itheima.domain.User">
update user set username=#{userName},address=#{userAddress},sex=#{userAex},birthday=#{userBirthday} where id=#{userId}
</update>
1
2
3
4
5
6
7
User user = new User();
user.setUserId(50);
user.setUserName("BBB");
user.setUserAddress("北京市顺义区");
user.setUserSex("女");
user.setUserBirthday(new Date());
userDao.updateUser(user);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 根据id查询用户 -->
<select id="findById" parameterType="int" resultType="com.itheima.domain.User">
select * from user where id = #{uid}
</select>

<!-- 根据名称模糊查询 -->
<select id="findByName" parameterType="string" resultType="com.itheima.domain.User">
select * from user where username like #{name}
</select>

<!-- 获取用户的总记录条数 -->
<select id="findTotal" resultType="int">
select count(id) from user;
</select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void testFindOne(){
User user = userDao.findById(50);
}

@Test
public void testFindByName(){
List<User> users = userDao.findByName("%王%");
}

@Test
public void testFindTotal(){
int count = userDao.findTotal();
}

根据名称查询时,可以有两种方式

  1. select * from user where username like #{name}

  2. select * from user where username like ‘%${value}%’

前者用的是PrepareStatement的参数占位符(更好),而后者用的是字符串拼接

事务

MyBatis通过sqlsession对象的commit和rollback方法实现事务的提交和回滚

最终用到的都是connection.commit()和connection.rollback()

自动提交

创建SqlSession时可以设置自动提交

1
sqlSession = factory.openSession(true);

这样后面就不用手动提交了

1
// sqlSession.commit();

但是实际上能这样用不多

如转账操作,还是需要手动控制提交时间