前言
在第一篇整理笔记中,从mybatis-plus基本搭建,到通用mapper的基本使用,都做了一个介绍,也留下了不少坑。
有同事问我说,为啥要用Oracle 数据库来讲解Mybatis-plus,而不是用MySQL;两个原因:
- 日常开始中一直在用Oracle;
- 网站上很多讲解Mybatis-plus教程,大部分都是基于MySQL的,Oracle的占比很少,用Mybatis-plus连接MySQL 和连接Oracle,其实都是一样的操作,但是会存在不同之处,毕竟是趟过几个坑的菜鸟;
本篇博客中,将记录如下内容:
MyBatis-plus的ActiveRecord(AR)模式;
AR 模式
简介
ActiveRecord(AR)模式,是一种 领域模型模式,一个模型类就代表了一个表。AR模式可以帮我们通过操作一个实体,来完成对一个表的增删改查。AR模式并不是Mybatis-plus所独有的,java作为一种准动态语言,并没有对AR模式进行良好的探索,而Mybatis-plus,则在这一方面,走出了一大步。
实现AR模式
这里需要用到在第一篇文章中创建的数据表pub_users和实体类Users;不需要改变数据表,只需要针对实体类做改变。
import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @Data @EqualsAndHashCode(callSuper = false) @TableName("PUB_USERS") @ToString public class Users extends Model<Users> {
private static final long serialVersionUID = 1L; private Integer id;
@TableField(value = "code") private String code;
private String name;
private String pwd;
private String adminPwd; } |
Mybatis-plus 使用它自带的AR模式,需要做如下操作:
- 需要继承Model接口,并填写对应的泛型;
- 必须存在对应的原始mapper并继承baseMapper并且可以使用的前提下 才能使用此 AR 模式 (接口中不需要实现任何方法)
3. 对EqualsAndHashCode进行设置是否调用父类,可设置不调,设置属性callSuper为False;
当满足以上三点时,才可以使用AR模式;
当我们真正使用AR模式时,对象会成为我们操作数据库的主体,对象中的内容会成为我们增删改查的使用到的内容;
当我们继承了Model类之后,我们就拥有了Model对象中的增删改查方法;
AR模式新增
----- insert 方法
@RequestMapping("/ar/insert") public void insertAR(){ Users users = new Users(); users.setId(18); users.setName("钟馗"); users.setPwd("123"); users.setCode("111119"); users.setAdminPwd("456"); users.insert(); } |
-----insertOrUpdate
此方法不同于insert方法,insert方法会直接针对数据进行插入;insertOrUpdate 方法会根据操作id进行验证,如果当前id已经存在的情况下,就针对当前数据进行修改而不是新增;
如下代码所示,我针对已经存在的id(id=18)进行操作;
@RequestMapping("/ar/insertOrUpdate") public void insertOrUpdate(){ Users users = new Users(); users.setId(18); users.setName("钟馗"); users.setPwd("123"); users.setCode("111119"); users.setAdminPwd("789"); users.insertOrUpdate(); } |
可以看到,此方法会首先根据id执行查询操作;如果当前对应id的数据存在,则根据id,对当前数据的内容进行修改;
如果当前id不存在,则会执行insert方法;
如下所示:
@RequestMapping("/ar/insertOrUpdate") public void insertOrUpdate(){ Users users = new Users(); users.setId(19); users.setName("鲁班大师"); users.setPwd("124"); users.setCode("111120"); users.setAdminPwd("780"); users.insertOrUpdate(); } |
AR模式修改
-----updateById
根据id修改数据内容;
@RequestMapping("/ar/updateById") public void updateByIdAR(){ Users user = new Users(); user.setId(18); user.setName("高渐离"); // 需要修改的内容 user.updateById();// 设置内容 } |
这里我们通过user对象的方式进行修改,需要为user对象设置id值,并为user设置需要修改的内容;
----- update
自定义查询条件,修改数据;这里的条件,是我们在上一篇博文中提到过的
Wrapper<T> updateWrapper;
这里我们将id=18的数据的名字修改为“杨玉环”
@RequestMapping("/ar/update") public void updateAR(){ Users users = new Users(); users.setName("杨玉环"); QueryWrapper<Users> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("id",18); users.update(queryWrapper); } |
AR模式删除
----deleteById
AR模式下,deleteById 删除数据的操作有两种,一种是带参的deleteById(Serializable id),一种是不带参的deleteById();
无参的:
@RequestMapping("/ar/deleteById") public void deleteByIdAR(){ Users users = new Users(); users.setId(18); users.deleteById(); } |
带参的:
@RequestMapping("/ar/deleteByIds") public void deleteByIdARS(){ Users users = new Users(); users.setId(1); users.deleteById(10); } |
不带参数的deleteById会以user对象中id为删除条件,带参数的deleteById会以参数为删除条件;
----- delete
自定义删除条件;
@RequestMapping("/ar/delete") public void deleteAR(){ Users users = new Users(); QueryWrapper<Users> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("id",10);// 设置删除条件: 删除id为10的数据 users.delete(queryWrapper); } |
AR增删改后话
- AR模式下增加删除修改数据,得到的结果不再是Integer类型,而是Boolean 类型,操作成功,返回true;失败,则返回false;
- 带有Wrapper<T> updateWrapper 的方法,在执行结果中,会拼接操作条件;
- 所有的SQL都是经过预编译,然后才执行的;
AR查找操作
-----selectAll
查询全部内容:
@RequestMapping("/ar/selectAll") public void selectAllAR(){ Users user = new Users(); List<Users> users = user.selectAll(); users.forEach(System.out::println); } |
----- selectById
根据主键记性查询;同deleteById类似,存在带参查询和不带参查询;
@RequestMapping("/ar/selectById") public void selectByIdAR(){ Users users = new Users(); users.setId(2); Users users1 = users.selectById(); System.out.println(users1.toString()); } |
@RequestMapping("/ar/selectByIds") public void selectByIdsAR(){ Users users = new Users(); users.setId(2); Users users1 = users.selectById(7); System.out.println(users1.toString()); } |
带参的selectById,会根据参数来设置id查询条件,而不是在根据users对象中id来设置查询条件;
----- selectOne
自定义查询条件,返回查询结果,这里根据查询条件获取到的查询结果只有一个;
@RequestMapping("/ar/selectByOne") public void selectByOne(){ Users users = new Users(); QueryWrapper<Users> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("id",7); Users user = users.selectOne(queryWrapper); System.out.println(user); } |
----- selectList
自定义查询条件,返回查询结果,这里根据查询条件获取到的查询结果会封装成List集合;
@RequestMapping("/ar/selectByList") public void selectByList(){ Users users = new Users(); QueryWrapper<Users> queryWrapper = new QueryWrapper<>(); queryWrapper.like("code","1111"); List<Users> usersList = users.selectList(queryWrapper); usersList.stream().forEach(System.out::println); } |
----- selectCount
自定义查询条件,统计符合条件的数据的条数;
@RequestMapping("/ar/selectByCount") public void selectByCount(){ Users users = new Users(); QueryWrapper<Users> queryWrapper = new QueryWrapper<>(); queryWrapper.like("code","1111"); Integer count = users.selectCount(queryWrapper); System.out.println("统计查询条数:" + count); } |
------ 分页查询
自定义查询条件,对数据进行分页查询;
@RequestMapping("/ar/selectByPage") public void selectByPage(){ Users users = new Users(); QueryWrapper<Users> queryWrapper = new QueryWrapper<>(); queryWrapper.like("code","1111"); Page<Users> usersPage = users.selectPage(new Page<Users>(1, 2), queryWrapper); List<Users> userList = usersPage.getRecords(); userList.stream().forEach(System.out::println); } |
注意: 同第一篇博文中提到的selectPage效果一样,因为操作的数据库是oracle数据库,所以selectBypage方法并不能实现分页效果;