mybatis-plus-IService
本文与官网大多数一致,只是在示例中加入了一些实际验证的代码,日志可能和与官网略有出入(预估是因为版本原因)
本文测试代码中mybatis-plus依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
类中函数:
mybatis-plus 持久层接口一下几个:
- Service Interface:用于service层,封装了常见的 CRUD 操作
- Mapper Interface:一般集成后
- Chain:提供的一种链式编程风格:它允许实体类直接与数据库进行交互,实体类既是领域模型又是数据访问对象
- ActiveRecord:它允许实体类直接与数据库进行交互,实体类既是领域模型又是数据访问对象
- SimpleQuery:对 selectList 查询后的结果进行了封装,使其可以通过 Stream 流的方式进行处理,从而简化了 API 的调用。
- Db Kit:它允许开发者通过静态调用的方式执行 CRUD 操作,从而避免了在 Spring 环境下可能出现的 Service 循环注入问题
本文由于篇幅原因主要写Service Interface 部分,其他的单独文章写
Service Interface
IService 是 MyBatis-Plus 提供的一个通用 Service 层接口,它封装了常见的 CRUD 操作,包括插入、删除、查询和分页等。通过继承 IService 接口,可以快速实现对数据库的基本操作,同时保持代码的简洁性和可维护性。
IService 接口中的方法命名遵循了一定的规范,如 get 用于查询单行,remove 用于删除,list 用于查询集合,page 用于分页查询,这样可以避免与 Mapper 层的方法混淆。
save
插入记录
save常用函数定义
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);
- 功能描述: 插入记录,根据实体对象的字段进行策略性插入。
- 返回值: boolean,表示插入操作是否成功。
参数说明:
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 |
Collection<T> | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
示例代码
/*************************************************************************/
@Test
public void testSave() {
UserPO userPO = new UserPO();
userPO.setUsername("wang 100");
userPO.setAge(12);
userPO.setGender(1);
userPO.setEmail("177xxx@qq.com");
val isSave = userService.save(userPO);
log.info("testSave:保存结果:{}", isSave);
;
}
//插入日志
// ==> Preparing: INSERT INTO user ( username, age, gender, email ) VALUES ( ?, ?, ?, ? )
// ==> Parameters: wang 100(String), 12(Integer), 1(Integer), 177xxx@qq.com(String)
// <== Updates: 1
/*************************************************************************/
@Test
public void testSaveBatch() {
//1624,1207,1264,1242
List<UserPO> users = new ArrayList<>();
for (int i = 0; i < 5; i++) {
UserPO userPO = new UserPO();
userPO.setUsername("wang 100-" + i);
userPO.setAge(12 + i);
userPO.setGender(i % 2);
userPO.setEmail("177xxx" + i + "@qq.com");
users.add(userPO);
}
val isSave = userService.saveBatch(users);
log.info("testSave:保存结果:{}", isSave);
}
//插入日志
// ==> Preparing: INSERT INTO user ( username, age, gender, email ) VALUES ( ?, ?, ?, ? )
// ==> Parameters: wang 100-0(String), 12(Integer), 0(Integer), 177xxx0@qq.com(String)
// ==> Parameters: wang 100-1(String), 13(Integer), 1(Integer), 177xxx1@qq.com(String)
// ==> Parameters: wang 100-2(String), 14(Integer), 0(Integer), 177xxx2@qq.com(String)
// ==> Parameters: wang 100-3(String), 15(Integer), 1(Integer), 177xxx3@qq.com(String)
// ==> Parameters: wang 100-4(String), 16(Integer), 0(Integer), 177xxx4@qq.com(String)
/*************************************************************************/
@Test
public void testSaveBatch2() {
List<UserPO> users = new ArrayList<>();
for (int i = 0; i < 5; i++) {
UserPO userPO = new UserPO();
userPO.setUsername("wang 200" + i);
userPO.setAge(12 + i);
userPO.setGender(i % 2);
userPO.setEmail("177xxx" + i + "@qq.com");
users.add(userPO);
}
val isSave = userService.saveBatch(users,2);
log.info("testSave:保存结果:{}", isSave);
}
//插入日志
//-- 第一批次
// ==> Preparing: INSERT INTO user ( username, age, gender, email ) VALUES ( ?, ?, ?, ? )
// ==> Parameters: wang 2000(String), 12(Integer), 0(Integer), 177xxx0@qq.com(String)
// ==> Parameters: wang 2001(String), 13(Integer), 1(Integer), 177xxx1@qq.com(String)
//-- 第二批次
// ==> Preparing: INSERT INTO user ( username, age, gender, email ) VALUES ( ?, ?, ?, ? )
// ==> Parameters: wang 2002(String), 14(Integer), 0(Integer), 177xxx2@qq.com(String)
// ==> Parameters: wang 2003(String), 15(Integer), 1(Integer), 177xxx3@qq.com(String)
//-- 第三批次
// ==> Preparing: INSERT INTO user ( username, age, gender, email ) VALUES ( ?, ?, ?, ? )
// ==> Parameters: wang 2004(String), 16(Integer), 0(Integer), 177xxx4@qq.com(String)
/*************************************************************************/
//可以当有batchSize参数时插入是根据batchSize大小分批的批量插入,而没有batchSize参数的saveBatch函数是一次全部批量插入的
通过上述示例,我们可以看到 save 系列方法是如何在 Service 层进行批量插入操作的,以及它们对应的 SQL 语句。这些方法大大简化了插入操作的代码编写,提高了开发效率。
saveOrUpdate
TableId 注解属性值存在则更新记录,否插入一条记录
saveOrUpdate常用函数定义
// TableId 注解属性值存在则更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
参数说明
类型 | 参数名 | 描述 |
---|---|---|
类型 | 参数名 | 描述 |
T | entity | 实体对象 |
Wrapper<T> | updateWrapper | 实体对象封装操作类 UpdateWrapper |
Collection<T> | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
saveOrUpdate示例
//准备数据
// INSERT INTO user(username, age, gender, email, phone_number)
// values ('张三', 22, 1, 'zhangsan@email.com', '1890000001'),
// ('李四', 21, 1, 'lisi@email.com', '1890000002'),
// ('王五', 23, 1, 'wangwu@email.com', '1890000003'),
// ('王小红', 22, 0, 'wangxiaohong@email.com', '1890000004'),
// ('王麻子', 20, 1, 'wangmazi@email.com', '1890000005'),
// ('李小雨', 20, 0, 'lixiaoyu@email.com', '1890000007');
/*************************************************************************/
@Test
public void testSaveOrUpdate() {
UserPO userPO = new UserPO();
userPO.setId(10);
userPO.setUsername("wang m");
userPO.setAge(18);
userPO.setGender(12);
userPO.setEmail("177xxx1@qq.com");
userService.saveOrUpdate(userPO);
}
//上述代码当这条数据没有时会直接插入
//通过日志看看都做了什么操作
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE id=?
// ==> Parameters: 10(Integer)
// <== Total: 0
// Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f908bc0]
// Creating a new SqlSession
// SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@396f2724] was not registered for synchronization because synchronization is not active
// JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1eb85a47] will not be managed by Spring
// ==> Preparing: INSERT INTO user ( id, username, age, gender, email ) VALUES ( ?, ?, ?, ?, ? )
// ==> Parameters: 10(Integer), wang m(String), 18(Integer), 12(Integer), 177xxx1@qq.com(String)
// <== Updates: 1
//通过日志可以看出来上面先进行看了查询操作,得到结果是0条,然后直接执行插入操作
//上述代码当这条数据ID已经从在时没有时会直接插入
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE id=?
// ==> Parameters: 10(Integer)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 10, wang m, 18, 12, 177xxx1@qq.com, null
// <== Total: 1
// Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2f75a9b1]
// Creating a new SqlSession
// SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@199806aa] was not registered for synchronization because synchronization is not active
// JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@c9b5a99] will not be managed by Spring
// ==> Preparing: UPDATE user SET username=?, age=?, gender=?, email=? WHERE id=?
// ==> Parameters: wang m(String), 18(Integer), 12(Integer), 177xxx1@qq.com(String), 10(Integer)
// <== Updates: 1
//通过日志可以看出来上面先进行看了查询操作,得到结果是1条,然后直接执行更新操作
/*************************************************************************/
@Test
public void testSaveOrUpdate2() {
UserPO userPO = new UserPO();
userPO.setId(10);
userPO.setUsername("张三");
userPO.setAge(18);
userPO.setGender(12);
userPO.setEmail("177xxx1@qq.com");
UpdateWrapper<UserPO> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("age", 12);
userService.saveOrUpdate(userPO,updateWrapper);
}
//==> Preparing: UPDATE user SET username=?, age=?, gender=?, email=? WHERE (age = ?)
// ==> Parameters: 张三(String), 18(Integer), 12(Integer), 177xxx1@qq.com(String), 12(Integer)
// <== Updates: 0
// Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@45b8bbbf]
// Creating a new SqlSession
// SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@21e39b82] was not registered for synchronization because synchronization is not active
// JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@11c581a0] will not be managed by Spring
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE id=?
// ==> Parameters: 10(Integer)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 10, 张三, 18, 12, 177xxx1@qq.com, null
// <== Total: 1
// Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@21e39b82]
// Creating a new SqlSession
// SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@11c999da] was not registered for synchronization because synchronization is not active
// JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@11c581a0] will not be managed by Spring
// ==> Preparing: UPDATE user SET username=?, age=?, gender=?, email=? WHERE id=?
// ==> Parameters: 张三(String), 18(Integer), 12(Integer), 177xxx1@qq.com(String), 10(Integer)
// <== Updates: 1
//通过日志可以看出来执行了一下三个操作
// 1. 先通过updateWrapper条件去更新,(没有更新,执行第二步)
// 2. 使用saveOrUpdate(后面的两步就是saveOrUpdate)更行数据
//下面在看看当updateWrapper条件可以更新时的日志:(将updateWrapper.eq("age", 12);改为updateWrapper.eq("age", 18);)
// JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6f3bd37f] will not be managed by Spring
// ==> Preparing: UPDATE user SET age=?, gender=?, email=? WHERE (age = ?)
// ==> Parameters: 18(Integer), 12(Integer), 177xxx1@qq.com(String), 18(Integer)
// <== Updates: 3
//可以看出来直接使用updateWrapper更行,没有个后续操作
/*************************************************************************/
@Test
public void saveOrUpdateBatch() {
UserPO userPO1 = new UserPO();
userPO1.setId(1);//这个ID数据库中存在
userPO1.setUsername("0001");
userPO1.setAge(18);
userPO1.setGender(1);
userPO1.setEmail("177xxx1@qq.com");
UserPO userPO2 = new UserPO();
userPO2.setUsername("0002");
userPO2.setId(2);//这个ID数据库中存在
userPO2.setAge(12);
userPO2.setGender(1);
userPO2.setEmail("177xxx1@qq.com");
UserPO userPO3 = new UserPO();
userPO3.setUsername("0003");
userPO3.setId(11);//这个ID数据库中不存在
userPO3.setAge(14);
userPO3.setGender(1);
userPO3.setEmail("177xxx1@qq.com");
List<UserPO> users = new ArrayList<>();
users.add(userPO1);
users.add(userPO2);
users.add(userPO3);
userService.saveOrUpdateBatch(users);
}
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE id=?
// ==> Parameters: 1(Integer)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, wang x, 18, 12, 177xxx1@qq.com, 1890000001
// <== Total: 1
// ==> Preparing: UPDATE user SET username=?, age=?, gender=?, email=? WHERE id=?
// ==> Parameters: 0001(String), 18(Integer), 1(Integer), 177xxx1@qq.com(String), 1(Integer)
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE id=?
// ==> Parameters: 2(Integer)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 2, 李四, 21, 1, lisi@email.com, 1890000002
// <== Total: 1
// ==> Preparing: UPDATE user SET username=?, age=?, gender=?, email=? WHERE id=?
// ==> Parameters: 0002(String), 12(Integer), 1(Integer), 177xxx1@qq.com(String), 2(Integer)
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE id=?
// ==> Parameters: 11(Integer)
// <== Total: 0
// ==> Preparing: INSERT INTO user ( id, username, age, gender, email ) VALUES ( ?, ?, ?, ?, ? )
// ==> Parameters: 11(Integer), 0003(String), 14(Integer), 1(Integer), 177xxx1@qq.com(String)
//通过日志可以看出来上面的每一条都是一条执行的。
/*************************************************************************/
注:boolean saveOrUpdateBatch(Collection<T> entityList); boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);这两个函数通过日志分析暂时没有看出来有什么区别,都是sql一条一条执行的
remove
通过指定条件删除符合条件的记录。
remove常用函数定义
// 根据 queryWrapper 设置的条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);
- 功能描述: 通过指定条件删除符合条件的记录。
- 返回值: boolean,表示删除操作是否成功。
参数说明:
类型 | 参数名 | 描述 |
---|---|---|
Wrapper<T> | queryWrapper | 实体包装类 QueryWrapper |
Serializable | id | 主键 ID |
Map<String, Object> | columnMap | 表字段 map 对象 |
Collection<? extends Serializable> | idList | 主键 ID 列表 |
remove示例
//准备数据
// INSERT INTO user(username, age, gender, email, phone_number)
// values ('张三', 22, 1, 'zhangsan@email.com', '1890000001'),
// ('李四', 21, 1, 'lisi@email.com', '1890000002'),
// ('王五', 23, 1, 'wangwu@email.com', '1890000003'),
// ('王小红', 22, 0, 'wangxiaohong@email.com', '1890000004'),
// ('王麻子', 20, 1, 'wangmazi@email.com', '1890000005'),
// ('李小雨', 20, 0, 'lixiaoyu@email.com', '1890000007');
/*************************************************************************/
@Test
public void testRemove() {
QueryWrapper<UserPO> queryWrapper =new QueryWrapper<>();
queryWrapper.eq("age",22);
userService.remove(queryWrapper);
}
//日志
// ==> Preparing: DELETE FROM user WHERE (age = ?)
// ==> Parameters: 22(Integer)
// <== Updates: 2
/*************************************************************************/
@Test
public void testRemoveById() {
userService.removeById(2);
}
//日志
// ==> Preparing: DELETE FROM user WHERE id=?
// ==> Parameters: 2(Integer)
// <== Updates: 1
/*************************************************************************/
还有很多remove相关方法这里不在演示
get
根据指定条件查询符合条件的记录。
get常用函数定义
// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
功能描述: 根据指定条件查询符合条件的记录。
返回值: 查询结果,可能是实体对象、Map 对象或其他类型。
参数说明:
类型 | 参数名 | 描述 |
---|---|---|
Serializable | id | 主键 ID |
Wrapper<T> | queryWrapper | 实体对象封装操作类 QueryWrapper |
boolean | throwEx | 有多个 result 是否抛出异常 |
T | entity | 实体对象 |
Function<? super Object, V> | mapper | 转换函数 |
get 示例
//准备数据
// INSERT INTO user(username, age, gender, email, phone_number)
// values ('张三', 22, 1, 'zhangsan@email.com', '1890000001'),
// ('李四', 21, 1, 'lisi@email.com', '1890000002'),
// ('王五', 23, 1, 'wangwu@email.com', '1890000003'),
// ('王小红', 22, 0, 'wangxiaohong@email.com', '1890000004'),
// ('王麻子', 20, 1, 'wangmazi@email.com', '1890000005'),
// ('李小雨', 20, 0, 'lixiaoyu@email.com', '1890000007');
/*************************************************************************/
@Test
public void testGetById() {
userService.getById(2);
}
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE id=?
// ==> Parameters: 2(Integer)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 2, 李四, 21, 1, lisi@email.com, 1890000002
// <== Total: 1
//可以看出来这就是一个简单的通过id查询数据
/*************************************************************************/
@Test
public void testGetOne() {//不抛异常测试
QueryWrapper<UserPO> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("age",21);
val userPO = userService.getOne(queryWrapper);
log.info("user:{}",userPO);
}
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE (age = ?)
// ==> Parameters: 21(Integer)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 2, 李四, 21, 1, lisi@email.com, 1890000002
// <== Total: 1
//user:UserPO(id=2, username=李四, age=21, gender=1, email=lisi@email.com, phoneNumber=1890000002)
//可以看出也是直接通过queryWrapper条件查询,这里如果查出多条数据mybatis-plus会抛出异常
/*************************************************************************/
@Test
public void testGetOne2() {
QueryWrapper<UserPO> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("age",22);
val userPO = userService.getOne(queryWrapper,false);
log.info("user:{}",userPO);
}
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE (age = ?)
// ==> Parameters: 22(Integer)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, 张三, 22, 1, zhangsan@email.com, 1890000001
// <== Row: 4, 王小红, 22, 0, wangxiaohong@email.com, 1890000004
// <== Total: 2
//user:UserPO(id=1, username=张三, age=22, gender=1, email=zhangsan@email.com, phoneNumber=1890000001)
//可以看出来它实际上还是查询满足queryWrapper条件的所有数量,不过当throwEx=false时不会抛出异常并默认取第一条,如果throwEx=true时,查出多条记录回抛出异常
/*************************************************************************/
list
list常用函数定义
// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
- 功能描述: 查询符合条件的记录。
- 返回值: 查询结果,可能是实体对象、Map 对象或其他类型。
参数说明
类型 | 参数名 | 描述 |
---|---|---|
Wrapper<T> | queryWrapper | 实体对象封装操作类 QueryWrapper |
Collection<? extends Serializable> | idList | 主键 ID 列表 |
Map<String, Object> | columnMap | 表字段 map 对象 |
Function<? super Object, V> | mapper | 转换函数 |
list示例
//准备数据
// INSERT INTO user(username, age, gender, email, phone_number)
// values ('张三', 22, 1, 'zhangsan@email.com', '1890000001'),
// ('李四', 21, 1, 'lisi@email.com', '1890000002'),
// ('王五', 23, 1, 'wangwu@email.com', '1890000003'),
// ('王小红', 22, 0, 'wangxiaohong@email.com', '1890000004'),
// ('王麻子', 20, 1, 'wangmazi@email.com', '1890000005'),
// ('李小雨', 20, 0, 'lixiaoyu@email.com', '1890000007');
/*************************************************************************/
@Test
public void testList() {
val user = userService.list();
log.info("user:{}", user);
}
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user
// ==> Parameters:
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, 张三, 22, 1, zhangsan@email.com, 1890000001
// <== Row: 2, 李四, 21, 1, lisi@email.com, 1890000002
// <== Row: 3, 王五, 23, 1, wangwu@email.com, 1890000003
// <== Row: 4, 王小红, 22, 0, wangxiaohong@email.com, 1890000004
// <== Row: 5, 王麻子, 20, 1, wangmazi@email.com, 1890000005
// <== Row: 6, 李小雨, 20, 0, lixiaoyu@email.com, 1890000007
// <== Total: 6
/*************************************************************************/
@Test
public void testList2() {
QueryWrapper<UserPO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("age",22);
val user = userService.list(queryWrapper);
log.info("user :{}", user);
}
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE (age = ?)
// ==> Parameters: 22(Integer)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, 张三, 22, 1, zhangsan@email.com, 1890000001
// <== Row: 4, 王小红, 22, 0, wangxiaohong@email.com, 1890000004
// <== Total: 2
/*************************************************************************/
@Test
public void testListByIds() {
val user = userService.listByIds( Arrays.asList(1, 2, 3));
log.info("user :{}", user);
}
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE id IN ( ? , ? , ? )
// ==> Parameters: 1(Integer), 2(Integer), 3(Integer)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, 张三, 22, 1, zhangsan@email.com, 1890000001
// <== Row: 2, 李四, 21, 1, lisi@email.com, 1890000002
// <== Row: 3, 王五, 23, 1, wangwu@email.com, 1890000003
// <== Total: 3
/*************************************************************************/
@Test
public void testListByMap() {
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("age", 22);
val user = userService.listByMap(columnMap);
log.info("user :{}", user);
}
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE (age = ?)
// ==> Parameters: 22(Integer)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, 张三, 22, 1, zhangsan@email.com, 1890000001
// <== Row: 4, 王小红, 22, 0, wangxiaohong@email.com, 1890000004
// <== Total: 2
/*************************************************************************/
@Test
public void testListMaps() {
val user = userService.listMaps();
log.info("user :{}", user);
}
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user
// ==> Parameters:
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, 张三, 22, 1, zhangsan@email.com, 1890000001
// <== Row: 2, 李四, 21, 1, lisi@email.com, 1890000002
// <== Row: 3, 王五, 23, 1, wangwu@email.com, 1890000003
// <== Row: 4, 王小红, 22, 0, wangxiaohong@email.com, 1890000004
// <== Row: 5, 王麻子, 20, 1, wangmazi@email.com, 1890000005
// <== Row: 6, 李小雨, 20, 0, lixiaoyu@email.com, 1890000007
// <== Total: 6
//这里需要注意返回值是一个list集合里面套了个map(这个map就是字段(key)与值(value))
page
注入一个插件(如果没有MybatisPlusInterceptor则分页查询无效,每次都会查询所有的数据)。
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
page常用函数定义
// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
- 功能描述: 分页查询符合条件的记录。
- 返回值: 分页查询结果,包含记录列表和总记录数。
类型 | 参数名 | 描述 |
---|---|---|
IPage<T> | page | 翻页对象 |
Wrapper<T> | queryWrapper | 实体对象封装操作类 QueryWrapper |
page示例代码
//准备数据
// INSERT INTO user(username, age, gender, email, phone_number)
// values ('张三', 22, 1, 'zhangsan@email.com', '1890000001'),
// ('李四', 21, 1, 'lisi@email.com', '1890000002'),
// ('王五', 23, 1, 'wangwu@email.com', '1890000003'),
// ('王小红', 22, 0, 'wangxiaohong@email.com', '1890000004'),
// ('王麻子', 20, 1, 'wangmazi@email.com', '1890000005'),
// ('李小雨', 20, 0, 'lixiaoyu@email.com', '1890000007');
/*************************************************************************/
@Test
public void testPage() {
IPage<UserPO> page = new Page<>(1, 3);
IPage<UserPO> userPage = userService.page(page);
log.info("user :{}", userPage.getRecords());
}
// ==> Preparing: SELECT COUNT(*) AS total FROM user
// ==> Parameters:
// <== Columns: total
// <== Row: 6
// <== Total: 1
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user LIMIT ?
// ==> Parameters: 3(Long)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, 张三, 22, 1, zhangsan@email.com, 1890000001
// <== Row: 2, 李四, 21, 1, lisi@email.com, 1890000002
// <== Row: 3, 王五, 23, 1, wangwu@email.com, 1890000003
// <== Total: 3
//这里过两条sql查询实现,一个查询总数,一个分页查询
/*************************************************************************/
@Test
public void testPage2() {
QueryWrapper<UserPO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("age", 22);
IPage<UserPO> page = new Page<>(1, 3);
IPage<UserPO> userPage = userService.page(page,queryWrapper);
log.info("user :{}", userPage.getRecords());
}
// ==> Preparing: SELECT COUNT(*) AS total FROM user WHERE (age = ?)
// ==> Parameters: 22(Integer)
// <== Columns: total
// <== Row: 2
// <== Total: 1
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE (age = ?) LIMIT ?
// ==> Parameters: 22(Integer), 3(Long)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, 张三, 22, 1, zhangsan@email.com, 1890000001
// <== Row: 4, 王小红, 22, 0, wangxiaohong@email.com, 1890000004
// <== Total: 2
//多了个查询条件其他没有变
/*************************************************************************/
@Test
public void testPageMaps() {
IPage<Map<String,Object>> page = new Page<>(1, 3);
val mapIPage = userService.pageMaps(page);
log.info("user :{}", mapIPage.getRecords());
}
// ==> Preparing: SELECT COUNT(*) AS total FROM user WHERE (age = ?)
// ==> Parameters: 22(Integer)
// <== Columns: total
// <== Row: 2
// <== Total: 1
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE (age = ?) LIMIT ?
// ==> Parameters: 22(Integer), 3(Long)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, 张三, 22, 1, zhangsan@email.com, 1890000001
// <== Row: 4, 王小红, 22, 0, wangxiaohong@email.com, 1890000004
// <== Total: 2
//查询sql上没有什么不一样,但是注意IPage中的泛型类型
/*************************************************************************/
@Test
public void testPageMaps2() {
QueryWrapper<UserPO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("age", 22);
IPage<Map<String,Object>> page = new Page<>(1, 3);
val mapIPage = userService.pageMaps(page,queryWrapper);
log.info("user :{}", mapIPage.getRecords());
}
// ==> Preparing: SELECT COUNT(*) AS total FROM user WHERE (age = ?)
// ==> Parameters: 22(Integer)
// <== Columns: total
// <== Row: 2
// <== Total: 1
// ==> Preparing: SELECT id,username,age,gender,email,phone_number FROM user WHERE (age = ?) LIMIT ?
// ==> Parameters: 22(Integer), 3(Long)
// <== Columns: id, username, age, gender, email, phone_number
// <== Row: 1, 张三, 22, 1, zhangsan@email.com, 1890000001
// <== Row: 4, 王小红, 22, 0, wangxiaohong@email.com, 1890000004
// <== Total: 2
count
查询总数
// 查询总记录数
int count();//生成sql SELECT COUNT(*) FROM user
// 根据 Wrapper 条件,查询总记录数
int count(Wrapper<T> queryWrapper);
//自3.4.3.2开始,返回值修改为long
// 查询总记录数
long count();
// 根据 Wrapper 条件,查询总记录数
long count(Wrapper<T> queryWrapper);
这个函数比较简单这里就不在赘述了
评论区