目录
1. Insert 操作 -> Create
1.1: @TableId 的 id策略
1.2: @TableField
2. Update 操作 -> Update
2.1: 根据 ID 更新
2.2: 根据条件更新
3. Delete 操作 -> Delete
3.1: deleteById
3.2: deleteByMap
3.3: delete
3.4: deleteBatchIds
4. Select 操作 -> Read
4.1: selectById
4.2: selectBatchIds
4.3: selectOne
4.4: selectCount
4.5: selectList
4.6: selectByMap
4.7: selectMaps
4.8: selectPage
4.9: selectMapsPage
4,10: exists (3.5.0版本新增的判断是否存在的API)
通过前面两章的练习理解, 了解到自定义的接口通过继承 BaseMapper 就可以获取到各种各样的单表操作, 接下来就对这些常用的 API 做个练习使用
1. Insert 操作 -> Create
方法定义
/**
* 插入一条记录
*
* @param entity 实体对象
*/
int insert(T entity);
测试用例
@Test
public void testInsert(){
User user = new User();
user.setAge(18);
user.setEmail("sunshangxiang@163.com");
user.setName("孙尚香");
user.setUserName("xiangxiang");
user.setPassword("123321");
// 返回的 res 是受影响的行数, 并不是自增后的 id
int res = userMapper.insert(user);
System.out.println("res = " + res);
// 自增后的 id 会填到对象中
System.out.println("user.getId() = " + user.getId());
}
测试结果
[main] [indi.darylz.mapper.UserMapper.insert]-[DEBUG] ==> Preparing: INSERT INTO tb_user ( id, password, name, user_name, email, age ) VALUES ( ?, ?, ?, ?, ?, ? )
[main] [indi.darylz.mapper.UserMapper.insert]-[DEBUG] ==> Parameters: 1657763426766651394(Long), 123321(String), 孙尚香(String), xiangxiang(String), sunshangxiang@163.com(String), 18(Integer)
[main] [indi.darylz.mapper.UserMapper.insert]-[DEBUG] <== Updates: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@faa3fed]
res = 1
user.getId() = 1657763426766651394
可以看到,数据已经写入到了数据库,但是 id 的值不正确, 期望的是 数据库自增长, 实际是 MybatisPlus生成了 id 的值写入到了数据库
1.1: @TableId 的 id策略
默认id策略
/**
* 表主键标识
*
* @author hubin
* @since 2016-01-23
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TableId {
/**
* 字段值(驼峰命名方式,该值可无)
*/
String value() default "";
/**
* 主键ID
* {@link IdType}
*/
IdType type() default IdType.NONE;
}
MybatisPlus支持以下 id 策略:
package com.baomidou.mybatisplus.annotation;
import lombok.Getter;
/**
* 生成ID类型枚举类
*
* @author hubin
* @since 2015-11-10
*/
@Getter
public enum IdType {
/**
* 数据库ID自增
*/
AUTO(0),
/**
* 该类型为未设置主键类型(将跟随全局)
*/
NONE(1),
/**
* 用户输入ID
* <p>该类型可以通过自己注册自动填充插件进行填充</p>
*/
INPUT(2),
/* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
/**
* 全局唯一ID (idWorker)
*/
ID_WORKER(3),
/**
* 全局唯一ID (UUID)
*/
UUID(4),
/**
* 字符串全局唯一ID (idWorker 的字符串表示)
*/
ID_WORKER_STR(5);
private final int key;
IdType(int key) {
this.key = key;
}
}
想插入数据到数据库时为自增效果则需要去把实体类的 id 策略指定为 自增长
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User {
// 指定 id 为自增长
@TableId(type = IdType.AUTO)
private Long id;
private String userName;
private String password;
private String name;
private Integer age;
private String email;
}
删除刚刚插入的数据再次进行测试
数据插入成功
1.2: @TableField
/**
* 表字段标识
*
* @author hubin sjy tantan
* @since 2016-09-09
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TableField {
/**
* 字段值(驼峰命名方式,该值可无)
*/
String value() default "";
/**
* 是否为数据库表字段
* 默认 true 存在,false 不存在
*/
boolean exist() default true;
/**
* 字段 where 实体查询比较条件
* 默认 `=` 等值
*/
String condition() default "";
/**
* 字段 update set 部分注入, 该注解优于 el 注解使用
* <p>
* 例1:@TableField(.. , update="%s+1") 其中 %s 会填充为字段
* 输出 SQL 为:update 表 set 字段=字段+1 where ...
* <p>
* 例2:@TableField(.. , update="now()") 使用数据库时间
* 输出 SQL 为:update 表 set 字段=now() where ...
*/
String update() default "";
/**
* 字段验证策略之 insert: 当insert操作时,该字段拼接insert语句时的策略
* IGNORED: 直接拼接 insert into table_a(column) values (#{columnProperty});
* NOT_NULL: insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)
* NOT_EMPTY: insert into table_a(<if test="columnProperty != null and columnProperty!=''">column</if>) values (<if test="columnProperty != null and columnProperty!=''">#{columnProperty}</if>)
*
* @since 3.1.2
*/
FieldStrategy insertStrategy() default FieldStrategy.DEFAULT;
/**
* 字段验证策略之 update: 当更新操作时,该字段拼接set语句时的策略
* IGNORED: 直接拼接 update table_a set column=#{columnProperty}, 属性为null/空string都会被set进去
* NOT_NULL: update table_a set <if test="columnProperty != null">column=#{columnProperty}</if>
* NOT_EMPTY: update table_a set <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
*
* @since 3.1.2
*/
FieldStrategy updateStrategy() default FieldStrategy.DEFAULT;
/**
* 字段验证策略之 where: 表示该字段在拼接where条件时的策略
* IGNORED: 直接拼接 column=#{columnProperty}
* NOT_NULL: <if test="columnProperty != null">column=#{columnProperty}</if>
* NOT_EMPTY: <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
*
* @since 3.1.2
*/
FieldStrategy whereStrategy() default FieldStrategy.DEFAULT;
/**
* 字段自动填充策略
*/
FieldFill fill() default FieldFill.DEFAULT;
/**
* 是否进行 select 查询
* <p>大字段可设置为 false 不加入 select 查询范围</p>
*/
boolean select() default true;
/**
* 是否保持使用全局的 Format 的值
* <p> 只生效于 既设置了全局的 Format 也设置了上面 {@link #value()} 的值 </p>
* <li> 如果是 false , 全局的 Format 不生效 </li>
*
* @since 3.1.1
*/
boolean keepGlobalFormat() default false;
/**
* JDBC类型 (该默认值不代表会按照该值生效)
* <p>
* {@link ResultMapping#jdbcType} and {@link ParameterMapping#jdbcType}
*
* @since 3.1.2
*/
JdbcType jdbcType() default JdbcType.UNDEFINED;
/**
* 类型处理器 (该默认值不代表会按照该值生效)
* <p>
* {@link ResultMapping#typeHandler} and {@link ParameterMapping#typeHandler}
*
* @since 3.1.2
*/
Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
/**
* 指定小数点后保留的位数
* <p>
* {@link ParameterMapping#numericScale}
*
* @since 3.1.2
*/
String numericScale() default "";
}
在 MybatisPlus中通过 @TableField 注解可以指定字段的一些属性,常常解决的问题有以下两个
1. 对象中的属性名和字段不一致的问题 (非驼峰)
2. 对象中的属性字段在表中不存在的问题
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User {
// 指定 id 为自增长
@TableId(type = IdType.AUTO)
private Long id;
private String userName;
private String password;
private String name;
private Integer age;
// 如 数据库中字段是 email, 而实体中的字段是 mail
// 这时候就可以使用 @TableFiled 的属性来指定数据库中的那个列的数据映射到此字段
@TableField(value = "email")
private String mail;
// 该字段在数据库表中不存在就可以用 exist 属性指定. 默认为 true
@TableField(exist = false)
private String address;
}
其他用法: 比如
// 不将敏感数据 参与到查询中
@TableField(select = false)
private String password;
官方注解文档: https://mybatis.plus/guide/annotation.html
2. Update 操作 -> Update
2.1: 根据 ID 更新
方法定义
/**
* 根据 ID 修改
*
* @param entity 实体对象
*/
int updateById(@Param(Constants.ENTITY) T entity);
测试用例
@Test
public void testUpdateById() {
User user = new User();
user.setId(1L); // 主键id
user.setAge(101); // 更新的字段
// 根据 id 更新,更新为null 的字段
int res = userMapper.updateById(user);
System.out.println("影响行数 = " + res);
}
测试结果
2.2: 根据条件更新
方法定义
/**
* 根据 whereEntity 条件,更新记录
*
* @param entity 实体对象 (set 条件值,可以为 null)
* @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
*/
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
测试用例
// 方式1:
@Test
public void testUpdate() {
User user = new User();
user.setEmail("88888@qq.com");
// 更新的条件
QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("user_name", "sunqi");
System.out.println("影响行数 = " + userMapper.update(user, wrapper));
}
// 方式2:
@Test
public void testUpdate2() {
// 更新的条件以及字段
UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
.eq("email", "test2@163.cn").set("age", 88);
// 执行更新
System.out.println("影响行数 = " + userMapper.update(null, wrapper));
}
方式1方式2 均可达到 更新的效果
测试结果
3. Delete 操作 -> Delete
3.1: deleteById
方法定义
/**
* 根据 ID 删除
*
* @param id 主键ID
*/
int deleteById(Serializable id);
/**
* 根据实体(ID)删除
*
* @param entity 实体对象
* @since 3.4.4
*/
int deleteById(T entity);
测试用例:
@Test
public void testDeleteById(){
int res = userMapper.deleteById(7L);
System.out.println("影响行数 = " + res);
}
测试结果:
数据被删除
3.2: deleteByMap
方法定义
/**
* 根据 columnMap 条件,删除记录
*
* @param columnMap 表字段 map 对象
*/
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
测试用例
@Test
public void testDeleteByMap(){
HashMap<String, Object> columnMap = new HashMap<>();
/* 键: 数据库列名
* 值: 具体的值
* */
columnMap.put("user_name","sunqi");
columnMap.put("age",24);
int res = userMapper.deleteByMap(columnMap);
System.out.println("影响行数 = " + res);
}
测试结果
数据删除成功
3.3: delete
方法定义
/**
* 根据 entity 条件,删除记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
*/
int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
测试用例
@Test
public void testDelete(){
User user = new User();
user.setPassword("123456");
user.setEmail("test1@163.cn");
int res = userMapper.delete(new QueryWrapper<>(user));
System.out.println("影响行数 = " + res);
}
测试结果
删除数据成功
3.4: deleteBatchIds
方法定义:
/**
* 删除(根据ID或实体 批量删除)
*
* @param idList 主键ID列表或实体列表(不能为 null 以及 empty)
*/
int deleteBatchIds(@Param(Constants.COLL) Collection<?> idList);
测试用例:
@Test
public void testDeleteBatchIds(){
int res = userMapper.deleteBatchIds(Arrays.asList(1L, 3L, 10L, 88L, 99L));
System.out.println("影响行数 = " + res);
}
测试结果:
删除数据成功
4. Select 操作 -> Read
Mybatis-Plus提供了多种查询操作, 包括根据 id 查询,批量查询,查询单条数据,查询列表,分页查询等操作
新增几条数据
4.1: selectById
方法定义
/**
* 根据 ID 查询
*
* @param id 主键ID
*/
T selectById(Serializable id);
测试用例
@Test
public void testSelectById(){
System.out.println("用户信息 = " + userMapper.selectById(13));
}
测试结果
[indi.darylz.mapper.UserMapper.selectById]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE id=?
[main] [indi.darylz.mapper.UserMapper.selectById]-[DEBUG] ==> Parameters: 13(Integer)
[main] [indi.darylz.mapper.UserMapper.selectById]-[DEBUG] <== Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e6ba49a]
用户信息 = User(id=13, userName=zhangfei, password=3451523, name=张飞, age=88, email=zhangfei@aliyun.com, address=null)
4.2: selectBatchIds
方法定义
/**
* 查询(根据ID 批量查询)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
List<T> selectBatchIds(@Param(Constants.COLL) Collection<? extends Serializable> idList);
测试用例
@Test
public void testSelectBatchIds() {
// 只会查询匹配的 id
List<User> users = userMapper.selectBatchIds(Arrays.asList(2L, 4L, 5L, 11L, 13L, 51L));
users.forEach(System.out::println);
}
测试结果
[main] [indi.darylz.mapper.UserMapper.selectBatchIds]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE id IN ( ? , ? , ? , ? , ? , ? )
[main] [indi.darylz.mapper.UserMapper.selectBatchIds]-[DEBUG] ==> Parameters: 2(Long), 4(Long), 5(Long), 11(Long), 13(Long), 51(Long)
[main] [indi.darylz.mapper.UserMapper.selectBatchIds]-[DEBUG] <== Total: 4
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7e0b9178]
User(id=2, userName=lisi, password=123456, name=李四, age=88, email=test2@163.cn, address=null)
User(id=4, userName=zhaoliu, password=123456, name=赵六, age=21, email=test4@163.cn, address=null)
User(id=11, userName=guanyu, password=888888, name=关羽, age=90, email=gaunyu@qq.com, address=null)
User(id=13, userName=zhangfei, password=3451523, name=张飞, age=88, email=zhangfei@aliyun.com, address=null)
4.3: selectOne
方法定义
/**
* 根据 entity 条件,查询一条记录
* <p>查询一条记录,例如 qw.last("limit 1") 限制取一条记录, 注意:多条数据会报异常</p>
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
default T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
List<T> list = this.selectList(queryWrapper);
// 抄自 DefaultSqlSession#selectOne
if (list.size() == 1) {
return list.get(0);
} else if (list.size() > 1) {
throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
} else {
return null;
}
}
测试用例
// 方式1
@Test
public void testSelectOne() {
User user = new User();
user.setEmail("huoqubing@sina.com");
System.out.println("用户信息 = " + userMapper.selectOne(new QueryWrapper<>(user)));
}
// 方式2
@Test
public void testSelectOne2() {
System.out.println("用户信息 = " +
userMapper.selectOne(
new QueryWrapper<User>()
.eq("user_name", "liubei")
.eq("age", 93)));
}
测试结果
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE email=?
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==> Parameters: huoqubing@sina.com(String)
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] <== Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@383f3558]
用户信息 = User(id=14, userName=huoqubing, password=1353341, name=霍去病, age=134, email=huoqubing@sina.com, address=null)
// ------------------------------------------------------
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE (user_name = ? AND age = ?)
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==> Parameters: liubei(String), 93(Integer)
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] <== Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@712ca57b]
用户信息 = User(id=12, userName=liubei, password=890878, name=刘备, age=93, email=liubei@gmail.com, address=null)
注意:多条数据会报异常
测试用例
@Test
public void testSelectOneIfException(){
System.out.println("用户信息 = " +
userMapper.selectOne(new QueryWrapper<User>().eq("password", "123456")));
}
测试结果
4.4: selectCount
方法定义
/**
* 根据 Wrapper 条件,查询总记录数
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
Long selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
测试用例
@Test
public void testSelectCount() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 查询年龄大于 60 (不包括60) , 如果需要包括使用
wrapper.gt("age", 90)
// 或者
.or()
// id 小于等于6的
.le("id", 6);
System.out.println("匹配 = " + userMapper.selectCount(wrapper) + " 条记录");
}
测试结果
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==> Preparing: SELECT COUNT( * ) AS total FROM tb_user WHERE (age > ? OR id <= ?)
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==> Parameters: 90(Integer), 6(Integer)
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] <== Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@294bdeb4]
匹配 = 6 条记录
4.5: selectList
方法定义
/**
* 根据 entity 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
测试用例
@Test
public void testSelectList() {
// 查询匹配条件的用户
/* 如果当前 selectList中的参数为null
或者 QueryWrapper对象为空对象(new new QueryWrapper<User>())
则是查询全部数据 */
userMapper.selectList(new QueryWrapper<User>()
.ge("age", 90).or()
.eq("password", "123456"))
.forEach(System.out::println);
}
测试结果
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE (age >= ? OR password = ?)
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] ==> Parameters: 90(Integer), 123456(String)
[main] [indi.darylz.mapper.UserMapper.selectList]-[DEBUG] <== Total: 6
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1f86099a]
User(id=2, userName=lisi, password=123456, name=李四, age=88, email=test2@163.cn, address=null)
User(id=4, userName=zhaoliu, password=123456, name=赵六, age=21, email=test4@163.cn, address=null)
User(id=11, userName=guanyu, password=888888, name=关羽, age=90, email=gaunyu@qq.com, address=null)
User(id=12, userName=liubei, password=890878, name=刘备, age=93, email=liubei@gmail.com, address=null)
User(id=14, userName=huoqubing, password=1353341, name=霍去病, age=134, email=huoqubing@sina.com, address=null)
User(id=15, userName=liubang, password=13413513, name=刘邦, age=151, email=hangaozu@han.com, address=null)
4.6: selectByMap
方法定义
/**
* 查询(根据 columnMap 条件)
*
* @param columnMap 表字段 map 对象
*/
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
测试用例
@Test
public void testSelectByMap(){
// 将 数据库列名和值封装在Map集合中,查询一个或 (多个实体(如果存在))
Map<String, Object> hashMap = new HashMap<String, Object>() {{
// put("user_name", "xiangxiang");
// put("email", "sunshangxiang@163.com");
put("password","123456");
}};
/* selectByMap(null) 则查询全部 */
userMapper.selectByMap(hashMap).forEach(System.out::println);
}
测试结果
[main] [indi.darylz.mapper.UserMapper.selectByMap]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE password = ?
[main] [indi.darylz.mapper.UserMapper.selectByMap]-[DEBUG] ==> Parameters: 123456(String)
[main] [indi.darylz.mapper.UserMapper.selectByMap]-[DEBUG] <== Total: 2
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@400d912a]
User(id=2, userName=lisi, password=123456, name=李四, age=88, email=test2@163.cn, address=null)
User(id=4, userName=zhaoliu, password=123456, name=赵六, age=21, email=test4@163.cn, address=null)
4.7: selectMaps
方法定义
/**
* 根据 Wrapper 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
测试用例
/**
* 查询指定条件的数据,并把表中数据对应的一个实体封装到Map中
* key: 数据库列名
* value: 对应列中的数据值
*/
@Test
public void testSelectMaps(){
// 参数1: 当前页
// 参数2: 当前页面大小
QueryWrapper<User> wrapper = new QueryWrapper<User>().le("age", 21);
List<Map<String, Object>> selectMaps = userMapper.selectMaps(wrapper);
for (Map<String, Object> selectMap : selectMaps) {
selectMap.keySet().forEach(s -> System.out.println(s.toUpperCase()));
selectMap.values().forEach(System.out::println);
System.out.println("-------");
}
}
测试结果
[main] [indi.darylz.mapper.UserMapper.selectMaps]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE (age <= ?)
[main] [indi.darylz.mapper.UserMapper.selectMaps]-[DEBUG] ==> Parameters: 21(Integer)
[main] [indi.darylz.mapper.UserMapper.selectMaps]-[DEBUG] <== Total: 2
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1f12e153]
PASSWORD
USER_NAME
NAME
ID
AGE
EMAIL
123456
zhaoliu
赵六
4
21
test4@163.cn
-------
PASSWORD
USER_NAME
NAME
ID
AGE
EMAIL
123321
xiangxiang
孙尚香
6
18
sunshangxiang@163.com
-------
4.8: selectPage
方法定义
/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
<P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
在SpringBoot项目中配置分页拦截器
3.1.2 版本 ~ 3.4.2 版本配置 (其中有些小版本没有)
PaginationInterceptor 在 3.4.0 ~ 3.4.2 版本可选
package indi.darylz.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author: daryl z
* @description: MybatisPlus 分页拦截器配置
*/
@Configuration
public class MybatisPlusConfig {
/**
* 3.1.2 版本 ~ 3.4.2 版本配置 (其中有些小版本没有)
* PaginationInterceptor 在 3.4.0 ~ 3.4.2 版本可选
* 配置MybatisPlus提供的 分页拦截器
* @return 将分页拦截器放入Spring容器中
*/
@Bean
public PaginationInterceptor paginationInnerInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作
/* true调回到首页 , false 继续请求 默认为 false */
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量, 默认 500 条, -1 不受限制
paginationInterceptor.setLimit(1000L);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
3.4.0 及以上版本配置 (这里测试用的 3.5.3.1 所以使用下面的配置)
package indi.darylz.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Collections;
/**
* @author: daryl z
* @description: MybatisPlus 分页拦截器配置
*/
@Configuration
public class MybatisPlusConfig {
/**
* MybatisPlus 3.4.0 及以上版本配置
*
* 配置MybatisPlus提供的 分页内部拦截器
*
* @return 将分页内部拦截器放入Spring容器中
*/
@Bean
public PaginationInnerInterceptor paginationInnerInterceptor() {
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
// 设置最大单页限制数量, 默认 500 条 , -1 不受限制
paginationInnerInterceptor.setMaxLimit(-1L);
// MYSQL("mysql", "MySql数据库"), (设置数据库类型)
paginationInnerInterceptor.setDbType(DbType.MYSQL);
// 开启 count 的 join 优化,只针对部分 left join
paginationInnerInterceptor.setOptimizeJoin(true);
return paginationInnerInterceptor;
}
/**
* MybatisPlus 3.4.0 及以上版本配置
*
* 配置MybatisPlus提供的 MybatisPlus 拦截器
* @return 将 MybatisPlus 拦截器放入 Spring 容器中
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
// 可以添加多个 分页内部拦截器
mybatisPlusInterceptor.setInterceptors(Collections.singletonList(paginationInnerInterceptor()));
return mybatisPlusInterceptor;
}
}
测试用例
@Test
public void testSelectPage() {
// 参数1: 当前页
// 参数2: 当前页面大小
Page<User> page = new Page<>(1, 3);
QueryWrapper<User> wrapper = new QueryWrapper<User>().le("age", 134);
print(page, wrapper);
// 打印出 第二页
page.setCurrent(2);
print(page, wrapper);
}
private void print(Page<User> page, QueryWrapper<User> wrapper) {
IPage<User> userPage = userMapper.selectPage(page, wrapper);
System.out.println("当前页数 = " + userPage.getCurrent());
System.out.println("总页数 = " + userPage.getPages());
System.out.println("数据总条数 = " + userPage.getTotal());
userPage.getRecords().forEach(System.out::println);
}
测试结果
[main] [com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize]-[DEBUG] JsqlParserCountOptimize sql=SELECT id,user_name,password,name,age,email FROM tb_user
WHERE age <= ?
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Preparing: SELECT COUNT(1) FROM tb_user WHERE age <= ?
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Parameters: 134(Integer)
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE age <= ? LIMIT ?,?
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Parameters: 134(Integer), 0(Long), 3(Long)
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] <== Total: 3
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7a7d1b47]
当前页数 = 1
总页数 = 3
数据总条数 = 7
User(id=2, userName=lisi, password=123456, name=李四, age=88, email=test2@163.cn, address=null)
User(id=4, userName=zhaoliu, password=123456, name=赵六, age=21, email=test4@163.cn, address=null)
User(id=6, userName=xiangxiang, password=123321, name=孙尚香, age=18, email=sunshangxiang@163.com, address=null)
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@72d0f2b4] was not registered for synchronization because synchronization is not active
[main] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Fetching JDBC Connection from DataSource
[main] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [HikariProxyConnection@1831717330 wrapping com.mysql.cj.jdbc.ConnectionImpl@75699e35] will not be managed by Spring
[main] [com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize]-[DEBUG] JsqlParserCountOptimize sql=SELECT id,user_name,password,name,age,email FROM tb_user
WHERE age <= ?
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Preparing: SELECT COUNT(1) FROM tb_user WHERE age <= ?
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Parameters: 134(Integer)
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE age <= ? LIMIT ?,?
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] ==> Parameters: 134(Integer), 3(Long), 3(Long)
[main] [indi.darylz.mapper.UserMapper.selectPage]-[DEBUG] <== Total: 3
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@72d0f2b4]
当前页数 = 2
总页数 = 3
数据总条数 = 7
User(id=11, userName=guanyu, password=888888, name=关羽, age=90, email=gaunyu@qq.com, address=null)
User(id=12, userName=liubei, password=890878, name=刘备, age=93, email=liubei@gmail.com, address=null)
User(id=13, userName=zhangfei, password=3451523, name=张飞, age=88, email=zhangfei@aliyun.com, address=null)
4.9: selectMapsPage
方法定义
/**
* 根据 Wrapper 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件
* @param queryWrapper 实体对象封装操作类
*/
<P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
测试用例
@Test
public void testSelectMapsPage() {
Page<Map<String, Object>> page = new Page<>(1, 2);
QueryWrapper<User> wrapper = new QueryWrapper<User>().le("age", 90);
printMap(page, wrapper);
page.setCurrent(2);
printMap(page, wrapper);
}
private void printMap(Page<Map<String, Object>> page, QueryWrapper<User> wrapper) {
Page<Map<String, Object>> mapPage = userMapper.selectMapsPage(page, wrapper);
System.out.println("当前页数 = " + mapPage.getCurrent());
System.out.println("总页数 = " + mapPage.getPages());
System.out.println("总条数 = " + mapPage.getTotal());
List<Map<String, Object>> records = mapPage.getRecords();
for (Map<String, Object> record : records) {
// key: 数据库列名
// value: 列名中对应的数据值
record.forEach((key, value) -> System.out.println("键 = " + key.toUpperCase() + " , 值 = " + value));
System.out.println("--------");
}
}
测试结果
[main] [com.zaxxer.hikari.HikariDataSource]-[INFO] HikariPool-1 - Starting...
[main] [com.zaxxer.hikari.pool.HikariPool]-[DEBUG] HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@8b91134
[main] [com.zaxxer.hikari.HikariDataSource]-[INFO] HikariPool-1 - Start completed.
[main] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [HikariProxyConnection@909786389 wrapping com.mysql.cj.jdbc.ConnectionImpl@8b91134] will not be managed by Spring
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] ==> Preparing: SELECT COUNT(*) AS total FROM tb_user WHERE (age <= ?)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] ==> Parameters: 90(Integer)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] <== Total: 1
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE (age <= ?) LIMIT ?
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] ==> Parameters: 90(Integer), 2(Long)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] <== Total: 2
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@13e698c7]
当前页数 = 1
总页数 = 3
总条数 = 5
键 = PASSWORD , 值 = 123456
键 = USER_NAME , 值 = lisi
键 = NAME , 值 = 李四
键 = ID , 值 = 2
键 = AGE , 值 = 88
键 = EMAIL , 值 = test2@163.cn
--------
键 = PASSWORD , 值 = 123456
键 = USER_NAME , 值 = zhaoliu
键 = NAME , 值 = 赵六
键 = ID , 值 = 4
键 = AGE , 值 = 21
键 = EMAIL , 值 = test4@163.cn
--------
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@67d86804] was not registered for synchronization because synchronization is not active
[main] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Fetching JDBC Connection from DataSource
[main] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [HikariProxyConnection@1169894049 wrapping com.mysql.cj.jdbc.ConnectionImpl@8b91134] will not be managed by Spring
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] ==> Preparing: SELECT COUNT(*) AS total FROM tb_user WHERE (age <= ?)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] ==> Parameters: 90(Integer)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage_mpCount]-[DEBUG] <== Total: 1
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] ==> Preparing: SELECT id,user_name,password,name,age,email FROM tb_user WHERE (age <= ?) LIMIT ?,?
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] ==> Parameters: 90(Integer), 2(Long), 2(Long)
[main] [indi.darylz.mapper.UserMapper.selectMapsPage]-[DEBUG] <== Total: 2
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@67d86804]
当前页数 = 2
总页数 = 3
总条数 = 5
键 = PASSWORD , 值 = 123321
键 = USER_NAME , 值 = xiangxiang
键 = NAME , 值 = 孙尚香
键 = ID , 值 = 6
键 = AGE , 值 = 18
键 = EMAIL , 值 = sunshangxiang@163.com
--------
键 = PASSWORD , 值 = 888888
键 = USER_NAME , 值 = guanyu
键 = NAME , 值 = 关羽
键 = ID , 值 = 11
键 = AGE , 值 = 90
键 = EMAIL , 值 = gaunyu@qq.com
--------
4,10: exists (3.5.0版本新增的判断是否存在的API)
方法定义
/**
* 根据 Wrapper 条件,判断是否存在记录
*
* @param queryWrapper 实体对象封装操作类
* @return 是否存在记录
*/
default boolean exists(Wrapper<T> queryWrapper) {
Long count = this.selectCount(queryWrapper);
return null != count && count > 0;
}
测试用例
@Test
public void testExists() {
User user = new User();
user.setAge(88);
user.setEmail("test2@163.cn");
user.setName("李四");
System.out.println("是否存在 = " + userMapper.exists(new QueryWrapper<>(user)));
}
@Test
public void testExists2() {
System.out.println("是否存在 = " + userMapper.exists(
new QueryWrapper<User>()
.eq("user_name", "sunqi")
.eq("age", 24)
.eq("email", "88888@qq.com")));
}
测试结果
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==> Preparing: SELECT COUNT( * ) AS total FROM tb_user WHERE name=? AND age=? AND email=?
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==> Parameters: 李四(String), 88(Integer), test2@163.cn(String)
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] <== Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@203dd56b]
是否存在 = true
---------------------
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==> Preparing: SELECT COUNT( * ) AS total FROM tb_user WHERE (user_name = ? AND age = ? AND email = ?)
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] ==> Parameters: sunqi(String), 24(Integer), 88888@qq.com(String)
[main] [indi.darylz.mapper.UserMapper.selectCount]-[DEBUG] <== Total: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1450078a]
是否存在 = false