MyBatisMyBatis CRUD操作单元测试的使用${} 与 #{} 的区别

Posted Perceus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatisMyBatis CRUD操作单元测试的使用${} 与 #{} 的区别相关的知识,希望对你有一定的参考价值。

@TOC


1. MyBatis 增删改查

1.1 增添操作

  1. 在 mapper (interface) 添加增添方法声明
//添加用户,返回受影响的行数
    public int add(UserInfo userInfo);

  1. 在 xml 中添加 < insert > 标签和增添 sql 编写
<!-- 添加用户,返回受影响的行数 -->
    <insert id="add">
        insert into userinfo(username,password,photo) values(#username,#password,#photo)
    </insert>


  1. service 层
public int add(UserInfo userInfo)
        return userMapper.add(userInfo);
    

  1. controller 层
@RequestMapping("/add")
    public int add(UserInfo userInfo)
        userInfo.setUsername("张三");
        userInfo.setPassword("123");
        userInfo.setPhoto("default.png");
        return userService.add(userInfo);
    

  1. 测试


1.2 删除操作

1. 在 mapper(interface) 里面添加删除的代码声明

 // 删除方法
    public int del(@Param("id") Integer id);

2. 在 xml 中添加 < delete >标签和删除 sql 编写

<!-- 根据用户 id 删除用户 -->
    <delete id="del">
        delete from userinfo where id=#id
    </delete>

3. service 层

 public int del(Integer id)
        return userMapper.del(id);
    

4. controller 层

 @RequestMapping("/del")
    public int del(Integer id)
        return userService.del(id);
    

5. 测试


1.3 修改操作

1. 在 mapper(interface) 里面添加修改的代码声明

// 修改方法【根据id修改名称】
    public int update(@Param("id") Integer id,
                      @Param("username") String username);

2. 在 xml 中添加 < update >标签和修改 sql 编写

 <!-- 根据用户 id 修改用户名称 -->
    <update id="update">
        update userinfo set username=#username where id=#id
    </update>

3. service 层

public int update(Integer id,String username)
        return userMapper.update(id,username);
    

4. controller 层

@RequestMapping("/update")
    public int update(Integer id,String username)
        return userService.update(id,username);
    

5. 测试


1.4 查找操作

1. 在 mapper(interface) 里面添加查找的代码声明

// 根据用户名来查询用户
    public UserInfo getUserByUsername(@Param("username") String username);

2. 在 xml 中添加 < select >标签和查找 sql 编写

<!-- 根据用户名查询用户 -->
    <select id="getUserByUsername" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where username=#username
    </select>

3. service 层

public UserInfo getUserByUsername(String username)
        return userMapper.getUserByUsername(username);
    

4. controller 层

@RequestMapping("/getuserbyusername")
    public UserInfo getUserById(String username)
        if(username == null) return null;
        return userService.getUserByUsername(username);
    

5. 测试


2. SpringBoot单元测试

2.1 单元测试优点


2.2 单元测试的实现

2.2.1 准备工作: 确认项目中已经内置了测试框架


2.2.2 生成单元测试的类

在 mapper 包下:


2.2.3 配置单元测试的类添加 @SpringBootTest 注解,添加单元测试的业务代码

1. 添加注解@SpringBootTest

2.添加单元测试的业务代码


2.3 简单断言说明


2.4 添加 @Transactional 注解执行回滚事务

我现在的数据库

执行修改操作:

修改成功:

在观察原数据库并没发生改变:


执行删除操作:

删除成功:

观察原数据库也没发生改变:


相关代码:

import com.example.demo.model.UserInfo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class UserMapperTest 

    @Resource
    private UserMapper userMapper;

    @Test
    void getUserById() 
        UserInfo userInfo = userMapper.getUserById(1);
        System.out.println(userInfo);
    

    // 在单元测试中添加此注解,表示在方法执行完之后回滚事务
    @Transactional
    @Test
    void update() 
        int result = userMapper.update(2, "张三");
        Assertions.assertEquals(1, result);
    

    @Transactional
    @Test
    void del() 
        int result = userMapper.del(2);
        System.out.println("受影响的行数:" + result);
        Assertions.assertEquals(1, result);
    

    @Transactional
    @Test
    void add() 
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("王五");
        userInfo.setPassword("123");
        userInfo.setPhoto("default.png");
        int result = userMapper.add(userInfo);
        System.out.println("添加的结果:" + result);
        Assertions.assertEquals(1, result);
    


2.5 返回自增 id

我们不仅想看到受影响的行数,还想看到修改后的 id

1. mapper层接口:

// 添加用户,返回受影响的行数和自增 id
    public int addGetId(UserInfo userInfo);

2. XML 文件:

 <!-- 添加用户,返回受影响的行数和自增 id -->
    <insert id="addGetId" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into userinfo(username,password,photo) values(#username,#password,#photo)
    </insert>

3. 单元测试代码:

//    @Transactional
    @Test
    void addGetId() 
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("老六");
        userInfo.setPassword("123");
        userInfo.setPhoto("default.png");
        System.out.println("添加之前的 user id: "+userInfo.getId());
        int result = userMapper.addGetId(userInfo);
        System.out.println("受影响的行数: "+result);
        System.out.println("添加之后的 user id: "+userInfo.getId());
        Assertions.assertEquals(1,result);
    

注释掉了回滚:


2.6 一些查询操作

2.6.1 $ 和 # 的区别演示

① 根据 id 查找用户

先看 # 操作根据 id 查找用户

执行的 JDBC 代码:(针对 int 类型的参数)


接下来$,其他代码不变

执行的 JDBC 代码:(针对 int 类型)

前者体现的预处理(预查询),后者体现的即时查询


② 根据用户名查找用户

我们在看看针对 String 类型参数:

先使用 # 根据用户名查找 用户

执行的 JDBC 代码:(针对 String 类型)


接下来$,其他代码不变

执行的 JDBC 代码:(针对 String 类型)

报错了,他的sql语句相当于是:

==并没有加引号==


③ 排序功能

像一些商品基本都要有这个排序功能(按价格从高到低,从低到高)我这里就按 id 来排序

先看 #

报错了:

他的 sql 相当于:


再看 $


2.6.2 总结区别


以上是关于MyBatisMyBatis CRUD操作单元测试的使用${} 与 #{} 的区别的主要内容,如果未能解决你的问题,请参考以下文章

MybatisMyBatis对表执行CRUD操作

mybatisMyBatis的crud操作以及字段与属性不匹配的问题

MybatisMybatis简介以及CRUD的使用

MybatisMybatis简介以及CRUD的使用

应该如何设计执行 CRUD 操作的 bean 的单元测试?

MybatisMyBatis之动态SQL