一、增删查改操作🍭
下面操作会使用到Spring Boot单元测试,可以先看:
Spring Boot单元测试
1、查🍉
查询所有的用户:
Ⅰ、mapper接口:🍓
package com.example.ssmdemo1.mapper; import com.example.ssmdemo1.entity.Userinfo; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; @Mapper//需要添加 @Mapper 注解 public interface UserMapper { /** * 根据用户id查询用户信息 * @param id * @return */ Userinfo getUserById(@Param("id") Integer id); //查询所有的用户 List getAll(); }
Ⅱ、UserMapper.xml 查询所有用户的具体实现 SQL:🍓
使用$进行传递参数可能会SQL注入,所以大部分情况下是使用#的
"1.0" encoding="UTF-8"?> mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.ssmdemo1.mapper.UserMapper"> <select id="getUserById" resultType="com.example.ssmdemo1.entity.Userinfo"> select * from userinfo where id=${id} select> <select id="getAll" resultType="com.example.ssmdemo1.entity.Userinfo"> select * from userinfo select> mapper>
Ⅲ、进行单元测试🍓
在UserMapperTest中就有了getAll的测试代码:
添加单元测试业务逻辑
package com.example.ssmdemo1.mapper; import com.example.ssmdemo1.entity.Userinfo; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest//1、表明当前单元测试是运行在Spring Boot环境中的 class UserMapperTest { //2、注入测试对象 @Autowired private UserMapper userMapper; @Test void getUserById() { //3、添加单元测试的业务代码 Userinfo userinfo=userMapper.getUserById(1); System.out.println(userinfo); //判断1是否等于2 简单断言 Assertions.assertEquals("admin",userinfo.getUsername()); } @Test void getAll() { List list=userMapper.getAll(); Assertions.assertEquals(1,list.size());//断言判断list集合里面是否只有一条数据,即查询数据库中只有一个用户 } }
测试正确:
如果我们没有设置resultType,则 MyBatis无法自动将查询结果映射到Java对象,这就会导致单元测试失败并报错。
2、增、删、改操作🍉
与查询操作都是一样的,只是使用的标签不一样:
- insert标签:插入语句
- update标签:修改语句
- delete标签:删除语句
Ⅰ、增🍓
添加用户🍒
①、在接口(UserMapper)中声明方法
Integer add(Userinfo user);
②、UserService
public Integer getAdd(Userinfo user) {return userMapper.add(user);}
③、在xml中提供实现
<insert id="add"> insert into userinfo(username,password) values(#{username},#{password}) insert>
#{} 进行赋值使用的是对象中的属性。
注意:对应的不是数据库的字段,而是程序类中的属性。
④、controller 实现代码:
@RequestMapping(value = "/add",method = RequestMethod.POST) public Integer add(@RequestBody Userinfo user){ return userService.getAdd(user); }
⑤、单元测试
@Test void add() { //伪代码,构建对象并设置对应的值 //本来是前端传值过来 Userinfo userinfo=new Userinfo(); userinfo.setUsername("张三"); userinfo.setPassword("123456"); //调用mybatis 添加方法执行添加操作 int result=userMapper.add(userinfo); Assertions.assertEquals(1,result); }
单元测试成功,可以去看数据库也添加了一条数据
但是如果我们去获取这个用户的id,就会报空指针异常:
添加用户并且返回自增 id🍒
如果我们想在添加用户的时候同时去获取他的id,具体实现如下:
①、在接口(UserMapper)中声明方法
Integer addGetid(Userinfo user);
②、UserService
public Integer addGetid(Userinfo user) {return userMapper.addGetid(user);}
③、在xml中提供实现
<insert id="addGetid" useGeneratedKeys="true" keyProperty="id"> insert into userinfo(username,password) values(#{username},#{password}) insert>
- useGeneratedKeys:这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。
- keyColumn:设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列 不是表中的第⼀列的时候,是必须设置的。如果⽣成列不止⼀个,可以用逗号分隔多个属性 名称。
- keyProperty:指定能够唯⼀识别对象的属性,MyBatis会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)。如果生成列不止⼀个,可以⽤逗号分隔多个属性名称。
④、controller 实现代码:
@RequestMapping(value = "/add2", method = RequestMethod.POST) public Integer add2(@RequestBody Userinfo user) { userService.addGetid(user); return user.getId(); }
⑤、单元测试
@Test void addGetid() { //伪代码,构建对象并设置对应的值 //本来是前端传值过来 Userinfo userinfo=new Userinfo(); userinfo.setUsername("张三"); userinfo.setPassword("123456"); //调用MyBatis 添加方法执行添加操作 返回受影响的行数 int result=userMapper.addGetid(userinfo); int id=userinfo.getId();//得到自增id(MyBatis自动赋值) System.out.println("id:"+id); Assertions.assertEquals(1,result); }
一样的代码,就一行代码不同
Ⅱ、改🍓
根据id修改用户名🍒
①、在接口(UserMapper)中声明方法
/** * 修改用户 * @param userinfo * @return */ Integer upUserName(Userinfo userinfo);
②、在xml中提供实现
<update id="upUserName"> update userinfo set username=#{username} where id=#{id} update>
③、单元测试
将之前添加的张三修改成为李四
@Test void upUserName() { // 构建测试数据 Userinfo userinfo = new Userinfo(); userinfo.setId(9); userinfo.setUsername("李四"); int result = userMapper.upUserName(userinfo); System.out.println("修改:" + result); Assertions.assertEquals(1, result); }
修改成功:
如果我们需要在控制台看到SQL语句,需要去配置文件进行配置,因为这默认是隐藏MyBatic生成SQL语句的细节
开启 MyBatis sql 日志打印🍒
①、添加配置文件
# 开启 mybatis sql 日志打印 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl logging.level.com.example.demo=debug
②、重新运行单元测试
@Test void upUserName() { // 构建测试数据 Userinfo userinfo = new Userinfo(); userinfo.setId(9); userinfo.setUsername("张三"); int result = userMapper.upUserName(userinfo); System.out.println("修改:" + result); Assertions.assertEquals(1, result); }
执行成功:
结论: 可以看到这个就是jdbc链接,这个SQL写法也是jdbc的写法,也就是说mybatis是基于jdbc的,MyBatis使用了JDBC来与数据库进行交互,它也简化了JDBC的使用,提供了更方便的数据库访问方式。。
建议大家在开发阶段是开启SQL的打印,可以更好的帮助你找到错误。
Ⅲ、删🍓
①、在接口(UserMapper)中声明方法
int delById(@Param("id") Integer id);
②、在xml中提供实现
<delete id="delById"> delete from userinfo where id=#{id} delete>
③、单元测试
将id为9的用户删除:
@Test void delById() { int id=9; int result=userMapper.delById(id); System.out.println("删除:"+result); Assertions.assertEquals(1,result); }
删除成功:
二、在单元测试时不污染数据库🍭
在需要的地方添加注解:@Transactional(可以修饰方法也可以修饰类)
如下面,去修饰UserMapper整个类: