MybatisPlus 官方文档:https://baomidou.com/guide/page.html
Mybatis Plus 使用流程 导入依赖: 1 2 3 4 5 <dependency > <groupId > com.baomidou</groupId > <artifactId > mybatis-plus</artifactId > <version > 3.4.3.2</version > </dependency >
实现映射: 1.对象名称与表的名称一一对应。 2.对象的属性与表中的字段一一对应。
注解: @TableName
表名注解
属性
类型
必须指定
默认值
描述
value
String
否
“”
表名
schema
String
否
“”
schema
keepGlobalPrefix
boolean
否
false
是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值)
resultMap
String
否
“”
xml 中 resultMap 的 id
autoResultMap
boolean
否
false
是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)
excludeProperty
String[]
否
{}
需要排除的属性名(@since 3.3.1)
@TableId
主键注解
属性
类型
必须指定
默认值
描述
value
String
否
“”
主键字段名
type
Enum
否
IdType.NONE
主键类型
@TableField
字段注解,非主键
属性
类型
必须指定
默认值
描述
value
String
否
“”
数据库字段名
el
String
否
“”
映射为原生 #{ … } 逻辑,相当于写在 xml 里的 #{ … } 部分
exist
boolean
否
true
是否为数据库表字段
condition
String
否
“”
字段 where 实体查询比较条件,有值设置则按设置的值为准,参考(opens new window)
update
String
否
“”
字段 update set 部分注入, 例如:update=”%s+1”:表示更新时会 set version=version+1(该属性优先级高于 el 属性)
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Data @Accessors(chain = true) @TableName("demo_user") @Component public class User implements Serializable { @TableId(type = IdType.AUTO, value = "id") private Integer id; @TableField("name") private String name; @TableField("age") private Integer age; @TableField("sex") private String sex; }
继承特定接口,实现 CRUD 操作 Myatis Plus 内部准备了一个 BaseMapper 接口,BamsMapper 接口将几乎所有的表操作进行了编写,用户只需要用自己编写的接口继承,即可使用 BaseMapper 接口所提供所有功能。
规则:继承 BaseMapper 接口必须添加泛型对象,否则映射表报错 自己创建的接口不要与接口方法重名
代码:
1 2 3 4 5 6 7 @Mapper public interface UserMapper extends BaseMapper <User > {}
在 yml 中配置 Mybatis Plus 1 2 3 4 5 6 7 8 mybatis-plus: #别名 type-aliases-package: com.jt.pojo #指定映射文件的位置 mapper-locations: classpath:mappers/*.xml #开启驼峰规则 configuration: map-underscore-to-camel-case: true
测试 其中查询方法 UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件。
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 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void insert () { User user = new User().setName("阿富汗" ).setAge(40 ).setSex("厉害" ); try { userMapper.insert(user); System.out.println("成功" ); } catch (Exception e) { System.out.println("失败" ); } } @Test public void select () { try { List<User> users = userMapper.selectList(null ); System.out.println("成功" ); for (User user : users) { System.out.println(user); } } catch (Exception e) { System.out.println("失败" ); } } }
Mybatis Plus 的操作原理 例如:
1 2 3 4 5 6 7 8 9 10 @Test public void insert () { User user = new User().setName("阿富汗" ).setAge(40 ).setSex("厉害" ); try { userMapper.insert(user); System.out.println("成功" ); } catch (Exception e) { System.out.println("失败" ); } }
上述代码相当于 SQL 语句:insert into 表名(字段名称) values(属性的值)
其核心为:Mybatis Plus 将常规的操作进行了抽取,并采用公共的接口进行了定义,然后只需要通过接收用户传递的参数进行动态的 SQL 拼接。
理论流程
用户调用接口方法,完成 CRUD 操作。userMapper.insert(user);
Mybatis Plus 根据用户传递的对象使用反射获取 User 类。Class userClass = user.getClass();
根据获取的 User 类,使用反射获取 User 类的指定注解,_TableName _tableName = (_TableName_) userClass.getAnnotation(_TableName_._class_);
通过获取的注解来动态的获取注解中的参数,从中获取数据表的表名。String name = tableName.value();
通过 User 类可以获取 User 类的属性,Field[] fields = userClass.getDeclaredFields();
获取到 User 类的属性后就可以使用反射获取 User 类属性的注解,Field[] fields = userClass.getDeclaredFields();
因为属性为封装后的私有属性,所以需要使用暴力反射。获取到属性的注解后即可得到表中的字段名。
将获取到的表名与字段名与用户传递的参数进行 SQL 拼接,insert into demo_user(id,age,name,sex) value (user.getId()…)
。
将拼接的 SQL 交由 Mybatis 进行执行,以实现 CRUD 操作。
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Class userClass = user.getClass(); TableName tableName = (TableName) userClass.getAnnotation(TableName.class); String name = tableName.value(); Field[] fields = userClass.getDeclaredFields(); String[] tableFields = new String[fields.length]; for (int i = 0 ; i < fields.length; i++) { TableField annotation = fields[i].getAnnotation(TableField.class); tableFields[i] = annotation.value(); }
使用 Mybatis Plus 进行查询操作 主键查询,使用 id 进行查询 查询所用方法selectById(int id);
参数为需要查询的信息的主键 id。
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void selectById () { int id = 232 ; User user = userMapper.selectById(id); System.out.println(user); } }
使用条件构造器进行全部数据查询 查询方法:userMapper.selectList(QueryWrapper queryWrapper)
;其中 queryWapper 为条件构造器,可为 null,为 null 将会查询表中所有数据。
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void select () { try { List<User> users = userMapper.selectList(null ); System.out.println("成功" ); for (User user : users) { System.out.println(user); } } catch (Exception e) { System.out.println("失败" ); } } }
条件构造器—对象封装 查询 name=”小乔”,sex=“女”的信息。
QueryWrapper 为条件构造器,用于生成 where 条件。
流程:
使用对象封装数据
User user = new User().setName(“小乔”).setSex(“女”);
构建条件触发器并使用,使用对象中不为 null 的属性作为 where 查询条件,默认链接符为 and
where name = '小乔' and sex = '女'
此时参数即为封装的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void selectByNameAndBySex () { QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(new User().setName("小乔" ).setSex("女" )); List<User> users = userMapper.selectList(userQueryWrapper); for (User user : users) { System.out.println(user); } } }
条件构造器—逻辑运算符查询
普通运算符
MybatisPlus 中的运算符
例子
=
eq
eq(“name”, “老王”)—>name = ‘老王’
>
gt
gt(“age”, 18)—>age > 18
<
lt
lt(“age”, 18)—>age < 18
>=
ge
ge(“age”, 18)—>age >= 18
<=
le
le(“age”, 18)—>age <= 18
!=
ne
ne(“name”, “老王”)—>name <> ‘老王’
eq(R column, Object val)
,lt(R column, Object val)
column 为字段名,val 为查询所需要的参数。
查询 name=”小乔”,sex=“女”的信息,查询 age<18,name = “女“
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void selectAgeAndSex () { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("name" , "小乔" ).eq("sex" , "女" ); List<User> users = userMapper.selectList(queryWrapper); for (User user : users) { System.out.println(user); } QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); userQueryWrapper.eq("sex" , "女" ).lt("age" , 18 ); List<User> users1 = userMapper.selectList(userQueryWrapper); for (User user : users1) { System.out.println(user); } } }
条件构造器—Like 关键字 like(R column, Object val)
,column 为字段名,val 为模糊查询所需要的参数。
例: like("name", "王")
—>name like '%王%'
查询 name 中包含“君”字的数据
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void selectLike () { QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); userQueryWrapper.like("name" , "君" ); List<User> users = userMapper.selectList(userQueryWrapper); for (User user : users) { System.out.println(user); } } }
条件构造器—排序
orderByAsc 升序排序:orderByAsc(R... columns)
,参数为需要排序的字段名。
例: orderByAsc("id", "name")
—>order by id ASC,name ASC
orderByDesc 降序排序:orderByDesc(R... columns)
,参数为需要排序的字段名。
例:orderByDesc("id", "name")
—>order by id DESC,name DESC
orderBy:orderBy(boolean condition, boolean isAsc, R... columns)
,condition 字段表示是否拼接 where 条件,isAsc 表示是否使用升序排序,columns 为需要排序的字段。
例:orderBy(true, true, "id", "name")
—>order by id ASC,name ASC
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void selectOrderBy () { QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); userQueryWrapper.eq("sex" , "女" ).orderByDesc("age" ); List<User> users = userMapper.selectList(userQueryWrapper); for (User user : users) { System.out.println(user); } } }
条件构造器—动态 SQL 当我们进行条件查询时,又是需要先进行判断,判断字段值是否存在或者是否符合条件,当不存在或者不符合条件时就会出错或查询不到数据。此时需要进行动态的 where 条件拼接,使用条件构造器中的各种方法提供的 condition 参数就可以实现是否拼接 SQL。
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void selectIsNull () { String name = "貂蝉" ; int age = 0 ; boolean nameFlag = name != null ; boolean ageFlag = age != 0 ; QueryWrapper<User> queryWrapper = new QueryWrapper<User>().eq(nameFlag, "name" , name).eq(ageFlag, "age" , age); List<User> users = userMapper.selectList(queryWrapper); System.out.println(users); } }
条件构造器—in 关键字 in(R column, Collection<?> value)
,value 为查询条件的参数。
in 关键字的两种使用方式:
IN (value.get(0), value.get(1), …)
in("age",{1,2,3})
—>age in (1,2,3)
IN (v0, v1, …)
in("age", 1, 2, 3)
—>age in (1,2,3)
查询 id=1,4,5,6·····的数据
代码实现:
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 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void selectIn () { QueryWrapper<User> idQueryWrapper = new QueryWrapper<User>().in("id" , 1 , 4 , 5 , 6 ); List<User> users = userMapper.selectList(idQueryWrapper); for (User user : users) { System.out.println(user); } ArrayList<Integer> ids = new ArrayList<>(); ids.add(1 ); ids.add(4 ); ids.add(5 ); ids.add(6 ); QueryWrapper<User> idQueryWrapper1 = new QueryWrapper<User>().in("id" , ids); List<User> users1 = userMapper.selectList(idQueryWrapper1); for (User user : users1) { System.out.println(user); } } }
条件构造器—查询第一个字段的记录 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
查询性别为男的数据,只查询 id 字段
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void selectObjs () { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("sex" , "男" ); List<Object> ids = userMapper.selectObjs(queryWrapper); System.out.println(ids); } }
Mybatis Plus 更新操作 使用主键进行更新 int updateById(@Param(Constants.ENTITY) T entity);
方法为updateById()
其中参数为实体对象,即 set 条件。
将 id 为 234 的数据改为”车臣“,age=10,sex=男。
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void testUpdate () { User user = new User().setId(234 ).setName("车臣" ).setAge(10 ).setSex("男" ); userMapper.updateById(user); } }
根据条件选择器条件进行更新 方法为update()
,int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
有两个参数,第一个参数为 set 条件,第二个参数为条件选择器,根据条件选择器的 where 条件进行数据更新。
将 name=”阿富汗“ 改为 塔利班,age=40,sex=”911”
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @SpringBootTest public class TestMP { @Autowired private UserMapper userMapper; @Test public void testUpdate1 () { User user = new User().setName("塔利班" ).setAge(40 ).setSex("911" ); UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.eq("name" , "阿富汗" ); userMapper.update(user, wrapper); } }
Mybatis Plus 分页查询 Mybatis Plus 分页查询需要定义分页对象,IPage<User> page=new Page<>();
其中 Page<>需要传递两个参数,第一个参数为需要查询的记录起始条数,第二个参数为需要查询的记录条数。例如使用 sql 语句进行分页查询时,第一个参数为查询的起始记录,第二个参数为查询的记录数量。
使用selectPage()
进行分页查询,其参数为分页对象。
代码实现: pojo
1 2 3 4 5 6 7 8 9 10 11 12 @Data @Accessors(chain = true) @TableName("user") public class User extends BasePojo { @TableId(type = IdType.AUTO) private Integer id; private String username; private String password; private String phone; private String email; private Boolean status; }
PageResult 类
1 2 3 4 5 6 7 8 9 @Data @Accessors(chain = true) public class PageResult implements Serializable { private String query; private Integer pageNum; private Integer pageSize; private Long total; private Object rows; }
service 类
1 2 3 4 5 6 7 8 9 10 11 @Override public PageResult getUserList (PageResult pageResult) { IPage<User> page = new Page<>(pageResult.getPageNum(), pageResult.getPageSize()); QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq(StringUtils.hasLength(pageResult.getQuery()), "username" , pageResult.getQuery()); page = userMapper.selectPage(page, queryWrapper); pageResult.setTotal(page.getTotal()).setRows(page.getRecords()); return pageResult; }
Mybatis Plus 自动填充功能 Mybatis Plus 可以对数据表中的属性进行自动填充,例如入库时间,更新时间等
使用 Mybatis Plus 的自动填充功能需要在 pojo 中需要使用自动填充的字段索映射的属性中添加注解,@TableField(fill = FieldFill.INSERT)
,其中 fill 有 4 个属性分别为DEFAULT
(默认不处理),INSERT
(插入填充字段),UPDATE
(更新填充字段),INSERT_UPDATE
(插入和更新填充字段)。
1 2 3 4 5 6 7 8 @Data @Accessors(chain=true) public class BasePojo implements Serializable { @TableField(fill = FieldFill.INSERT) private Date created; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updated; }
定义配置类,实现**MetaObjectHandler**
接口,使得@TableField
属性中的配置生效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill (MetaObject metaObject) { this .setFieldValByName("created" , new Date(), metaObject); this .setFieldValByName("updated" , new Date(), metaObject); } @Override public void updateFill (MetaObject metaObject) { this .setFieldValByName("updated" , new Date(), metaObject); } }