mybatis-plus之插件
Posted 晚安果汁
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis-plus之插件相关的知识,希望对你有一定的参考价值。
一、插件机制。
1、mybatis允许你在已映射语句执行过程中的某一点进行拦截调用,默认情况下,mybatis允许使用插件来拦截的方法调用包括:executor(update,query,commit,rollback)等,parameterhandler,resultsethandler,statementhandler。
总体概括为:拦截执行器的方法, 拦截参数的处理,拦截结果集的处理,拦截SQL语法构建的处理。
2、示例。
二、执行分析插件。
在MP中提供了对SQL执行的分析的插件,可用作阻断全表更新、删除的操作,注意:该插件仅适用于开发环境,不适用于生产环境。
1、配置springboot:SQL分析插件
2、测试。
SQL
三、性能分析插件。
性能分析拦截器,用于输出每条SQL语句及其执行时间,可以设置最大执行时间,超过时间会抛出异常,该插件只用于开发环境,不建议生产环境使用。
1、配置方式一
2、配置方式二
3、测试
SQL语句展示
时间展示
四、乐观锁插件。
当要更新一条记录的时候,希望这条记录没有被别人更新。
1、乐观锁实现方式。
取出记录时,获取当前version。
更新时,带上这个version。
执行更新时,set version = newVersion where version = oldVersion
如果执行version不对,就更新失败
2、配置
mybatis全局配置文件做配置。
3、在实体类添加version字段。
4、在数据库添加version字段
5、测试
SQL:乐观锁添加了version和id
避免同时做修改
数据库改了版本,是不可以改的,避免同时修改数据带来的不安全
特别说明:
1、支持的数据类型有:int、integer、long、Long、date、timestamp、LocalDateTime
2、整数类型下:newVersion = oldVersion + 1
3、newVersion会回写到entity中。
4、仅支持updateById(id)与update(entity,wrapper)方法。
5、在update(entity,wrapper)方法下,wrapper不能复用。
Mybatis插件之Mybatis-Plus的CRUD方法
使用Mybatis-plus进行基本的CRUD(增查改删)操作。
实体类(User)代码:
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; @Data @NoArgsConstructor @AllArgsConstructor @ToString @TableName("tb_user") public class User { @TableId(type = IdType.AUTO) // 需要指定,否则无法新增后拿到回调的id,以及进行删除等操作 // 查询的时候不需要查出来的字段,默认true,和@TableId作用在同一个字段上时失效 @TableField(select = false) private Integer uid; private String uname; // 用来解决数据库中的字段和实体类的字段不匹配问题 @TableField(value = "age",select = false) private Integer uage; // 数据库中的字段为age // 用来解决实体类中有的属性但是数据表中没有的字段 @TableField(exist = false) // 默认为true private String address; // 这是一个数据库中不存在的字段 public User(String uname, Integer age) { this.uname = uname; this.uage = age; } }
1、增加操作:
代码如下:直接传入一个实体即可完成
@Test public void test02(){ // 插入一条记录 // 1.构建要插入的对象 User user = new User(); user.setUname("zhangsan"); user.setUage(40); // 数据库中不存在的字段,通过@TableField(exist = false)排除之 user.setAddress("beijing"); // 2.执行添加 返回值为受影响的行数 int result = userMapper.insert(user); System.out.println("受影响的行数=" + result); System.out.println("拿到自增的id=" + user.getUid()); }
2、更新操作:
方法一:int updateById(T entity);
测试代码:
@Test public void test04(){ // 根据id进行更新 // 1.构建更新的对象 User user = new User(); // 2.根据id来进行更新 user.setUid(1007); // 3.更新的内容值 user.setUname("小莉"); user.setUage(17); // 4.执行更新 int result = userMapper.updateById(user); System.out.println("受影响的行数=" + result); }
方法二:
1-使用QueryWrapper,它只负责条件的匹配
测试代码:
@Test public void test05(){ // 第一种:使用QueryWrapper,根据条件进行更新 // 1.设置更新的内容值 User user = new User(); user.setUname("王五"); user.setUage(45); // 2.设置更新的匹配条件,可以叠加多个,类似于and QueryWrapper<User> wapper = new QueryWrapper<>(); // 参数1:数据库中的字段名 参数2:字段名的值(匹配的值) // 解读:把数据库中uid字段为1015和1016的值修改成user中的内容 wapper.eq("uid",1015); wapper.or(); // 在查询中拼接or wapper.eq("uid",1016); // 语句还原:UPDATE tb_user SET uname=\'王五\', age=45 WHERE uid = 1015 OR uid = 1016 // 3.开始更新,参数1:更新的内容 参数2:更新的匹配条件 int result = userMapper.update(user, wapper); System.out.println("受影响的行数=" + result); // 2 }
2-使用UpdateWrapper进行更新操作
测试代码:
@Test public void test06(){ // 第二种:使用UpdateWrapper,根据条件进行更新 // 1.定义一个UpdateWrapper对象 UpdateWrapper<User> wrapper = new UpdateWrapper<>(); // 2.设置参数 // set(String column, Object val),参数1:数据库中的字段名 参数2:修改后的值 // eq(String column, Object val),参数1:数据库中的字段名 参数2:修改条件 // or(),使查询条件变成用or拼接 wrapper.set("uname","第五人格").set("age",28) .eq("uid",1018).or().eq("uid",1019); // 3.执行修改,使用UpdateWrapper,参数1指定为 null int result = userMapper.update(null, wrapper); System.out.println("受影响的行数=" + result); // 2 // SQL:UPDATE tb_user SET uname=?,age=? WHERE uid = ? OR uid = ? }
注意两个条件直接如果要用OR拼接,则需要在两个条件之家插入or()方法。
3、删除操作:
1-根据id来删除
@Test public void test03(){ // 1.直接根据id进行删除 int result = userMapper.deleteById(1014); System.out.println("受影响的行数=" + result); // 1 }
2-根据map条件进行删除
@Test public void test07(){ // 根据Map来进行删除,多条件之间是and关系 // 1.构建删除条件map Map<String,Object> map = new HashMap<>(); // 2.设置删除条件的值,参数1:数据库中的字段名,参数2:条件值 map.put("uname","艾玛x"); map.put("age",80); // 3.执行删除 int result = userMapper.deleteByMap(map); System.out.println("受影响的行数=" + result); // 1 // SQL:DELETE FROM tb_user WHERE uname = ? AND age = ? }
3-根据查询条件Wrapper进行删除:delete(Wrapper<T> wrapper)
使用QueryWrapper进行删除,测试代码:
@Test public void test08(){ // 1.构建一个QueryWrapper对象 QueryWrapper<User> wrapper = new QueryWrapper<>(); // 2.为QueryWrapper对象设置条件 wrapper.eq("uid",1010).eq("uname","小柳") // 也可以设置OR条件 .or().eq("uid",1015); // 3.执行删除 int result = userMapper.delete(wrapper); System.out.println("受影响的行数=" + result); // 2 // SQL:DELETE FROM tb_user WHERE uid = ? AND uname = ? OR uid = ? }
4-根据id集合实现批量删除:deleteBatchIds(Collection idList)
测试代码:
@Test public void test09(){ // 根据集合进行删除(使用的是SQL中的in关键字) // 1.构建一个存放id列表的集合 List<Integer> idList = new ArrayList<>(); // 2.存放要进行删除的id,存放了3个id idList.add(1021); idList.add(1022); idList.add(1023); // 3.执行删除 int result = userMapper.deleteBatchIds(idList); System.out.println("受影响的行数=" + result); // 3 // SQL:DELETE FROM tb_user WHERE uid IN ( ? , ? , ? ) }
以上就是BaseMapper中增删改操作的方法。
接下来,介绍其查询方法,MybatisPlus(MP)提供了多种查询操作,包括根据id查询,批量查询、单挑记录查询、查询列表、分页查询等操作。
4、查询操作
1-根据id查询单个记录
测试代码:
@Test public void test01(){// 根据id进行查询 // 1.执行查询操作 User user = userMapper.selectById(1018); // 2.输出查询结果 System.out.println(user); }
如果出现以下情况,则需要指定@TableId
2-根据id集合列表查询多个记录:selectBatchIds(Collection idList)
测试代码:
@Test public void test02(){// 根据id集合进行批量查询 // 1.创建id列表并赋值 List<Integer> ids = new ArrayList<>(); ids.add(1016); ids.add(1017); ids.add(1018); // 2.执行查询 List<User> users = userMapper.selectBatchIds(ids); // 3.遍历查询结果集 for (User user : users) { // 4.打印查询结果 System.out.println(user); } // SQL:SELECT uid,uname FROM tb_user WHERE uid IN ( ? , ? , ? ) }
3-根据条件进行查询,用map来封装查询条件
测试代码:
@Test public void test03(){ // 1.构建查询条件 Map<String, Object> map = new HashMap<>(); map.put("uname","第五人格"); map.put("age",28); // 多个条件之间的SQL用and拼接 // 2.执行查询 List<User> users = userMapper.selectByMap(map); // 3.打印输出 printUsers(users); // SQL:SELECT uid,uname FROM tb_user WHERE uname = ? AND age = ? }
4-查询单挑记录,若返回加过大于一个,抛出异常MybatisSystemException
测试代码:
@Test public void test04(){ // 查询单条记录 // 1.定义查询条件对象 QueryWrapper<User> wrapper = new QueryWrapper<>(); // 2.设置查询条件 wrapper.eq("uname","第五人格"); // 查询的记录>1个时,抛出异常MyBatisSystemException User user = userMapper.selectOne(wrapper); // 3.打印结果 System.out.println(user); // SQL:SELECT uid,uname FROM tb_user WHERE uname = ? }
5-查询符合条件的记录数,Integer selectCount(Wrapper<User> queryWrapper)
测试代码:
@Test public void test05(){ // 查询记录数,类似于conut(*) // 若需要设置条件可使用Wrapper对象,null表示查询所有 Integer count = userMapper.selectCount(null); // 打印返回的记录数 System.out.println("记录数有 = " + count); // SQL:SELECT COUNT( 1 ) FROM tb_user }
6-查询符合条件的记录列表,List<User> selectList(Wrapper<User> queryWrapper)
若参数为null,则为查询所有
测试代码:
@Test public void test06(){//根据查询条件查询列表 // 1.构建一个QueryWrapper对象 QueryWrapper<User> wrapper = new QueryWrapper<>(); // 2.设置条件,参数1:数据库字段名,参数2:参数值 wrapper.eq("uname","第五人格"); // 3.执行查询 List<User> users = userMapper.selectList(wrapper); //List<User> users = userMapper.selectList(null);// 查询所有 // 4.打印结果 printUsers(users); }
7-根据条件把查询结果封装在Map和List中
List<Map<String, Object>> selectMaps(Wrapper<User> queryWrapper)
测试代码:
@Test public void test07(){ List<Map<String, Object>> maps = userMapper.selectMaps(null); for (Map<String, Object> map : maps) { // 一个map对应一条记录 // 每个map的key都为字段名 // 每个map的值都为字段具体值 System.out.println(map); } }
8-分页查询
首先定义一个新的类为配置类(MybatisPlusConfig)
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisPlusConfig { // 分页插件 @Bean // 注入Spring容器中 public PaginationInterceptor paginationInterceptor(){ return new PaginationInterceptor(); } }
之后开始测试,代码如下:
@Test public void test09(){ // 测试分页 // 1.查询条件,null则为查询所有 Wrapper<User> wrapper = null; // 1.1 使用其构造,参数1:当前页,参数2:每页的大小 Page<User> page = new Page<>(1,2); // 2.执行查询 // 参数1:为接口Ipage,其实现类只有一个Page,参数2:为查询条件,返回一个Ipage对象 IPage<User> userIPage = userMapper.selectPage(page, wrapper); // 3.打印重要参数 System.out.println("总页数= " + userIPage.getPages()); System.out.println("总记录数= " + userIPage.getTotal()); System.out.println("页面大小= " + userIPage.getSize()); System.out.println("当前页= " + userIPage.getCurrent()); System.out.println("查询结果如下:" ); // 4.打印分页结果 for (User user : userIPage.getRecords()) { System.out.println(user); } // SQL:SELECT uid,uname,age AS uage FROM tb_user LIMIT ?,? }
至此,关于BaseMapper接口中的所有方法都已经测试完成了!
以上是关于mybatis-plus之插件的主要内容,如果未能解决你的问题,请参考以下文章
Mybatis-Plus:插件(mybatis的插件机制执行分析插件性能分析插件乐观锁插件)