当前位置: 首页 > news >正文

MyBatis-Plus IService 接口全量方法实现与测试(续)

上一篇我们实现了 IService 的核心方法,本文将补充剩余方法的实现与测试,涵盖批量操作、链式查询、复杂查询等场景,基于User实体类完成全部 40 + 方法的实战案例。

六、批量操作扩展方法

1. 带批次大小的批量新增

@Test

public void testSaveBatchWithSize() {

List<User> userList = new ArrayList<>();

for (int i = 0; i < 1500; i++) { // 超过默认1000条

userList.add(new User(null, "批量用户" + i, 20 + i % 10, "batch" + i + "@qq.com"));

}

// 指定批次大小为500

boolean result = userService.saveBatch(userList, 500);

assertTrue(result);

}

2. 批量新增或修改(saveOrUpdateBatch)

@Test

public void testSaveOrUpdateBatch() {

List<User> userList = new ArrayList<>();

// 已存在的用户(ID存在则更新)

userList.add(new User(1L, "张三更新", 22, "zhangsan_new@qq.com"));

// 新用户(ID不存在则新增)

userList.add(new User(null, "赵六", 28, "zhaoliu@qq.com"));

boolean result = userService.saveOrUpdateBatch(userList);

assertTrue(result);

}

@Test

public void testSaveOrUpdateBatchWithSize() {

List<User> userList = new ArrayList<>();

for (int i = 0; i < 1200; i++) {

// 模拟部分已有ID的用户

User user = new User(i < 500 ? (long)i : null, "用户" + i, 20 + i % 10, "user" + i + "@qq.com");

userList.add(user);

}

// 指定批次大小为300

boolean result = userService.saveOrUpdateBatch(userList, 300);

assertTrue(result);

}

3. 带填充的删除操作

@Test

public void testRemoveByIdWithFill() {

// 注意:需要实体类配置逻辑删除字段并开启自动填充

boolean result = userService.removeById(1L, true);

System.out.println("带填充删除结果:" + result);

}

@Test

public void testRemoveBatchByIdsWithFill() {

List<Long> ids = Arrays.asList(2L, 3L);

boolean result = userService.removeBatchByIds(ids, true);

System.out.println("带填充批量删除结果:" + result);

}

@Test

public void testRemoveBatchByIdsWithSize() {

List<Long> ids = new ArrayList<>();

for (long i = 4; i < 1004; i++) {

ids.add(i);

}

// 指定批次大小为200

boolean result = userService.removeBatchByIds(ids, 200);

assertTrue(result);

}

@Test

public void testRemoveBatchByIdsWithSizeAndFill() {

List<Long> ids = new ArrayList<>();

for (long i = 1004; i < 2004; i++) {

ids.add(i);

}

boolean result = userService.removeBatchByIds(ids, 200, true);

assertTrue(result);

}

七、修改操作扩展

1. 条件修改(无实体参数)

@Test

public void testUpdateWithoutEntity() {

// 将所有年龄>30的用户邮箱后缀改为@163.com

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.gt("age", 30);

queryWrapper.set("email", "update@163.com"); // 直接在条件中设置修改内容

boolean result = userService.update(queryWrapper);

assertTrue(result);

}

2. 批量修改

@Test

public void testUpdateBatchById() {

List<User> userList = new ArrayList<>();

userList.add(new User(1L, "张三批量更新", 23, "zhangsan_batch@qq.com"));

userList.add(new User(2L, "李四批量更新", 24, "lisi_batch@qq.com"));

boolean result = userService.updateBatchById(userList);

assertTrue(result);

}

@Test

public void testUpdateBatchByIdWithSize() {

List<User> userList = new ArrayList<>();

for (long i = 1; i < 1001; i++) {

userList.add(new User(i, "批量更新用户" + i, 25, "batch_update" + i + "@qq.com"));

}

// 指定批次大小为300

boolean result = userService.updateBatchById(userList, 300);

assertTrue(result);

}

3. 新增或修改(带条件)

@Test

public void testSaveOrUpdateWithWrapper() {

User user = new User();

user.setName("条件新增或修改");

user.setAge(30);

user.setEmail("condition@qq.com");

// 按name作为查询条件

QueryWrapper<User> updateWrapper = new QueryWrapper<>();

updateWrapper.eq("name", "条件新增或修改");

boolean result = userService.saveOrUpdate(user, updateWrapper);

assertTrue(result);

}

八、查询操作扩展

1. 复杂查询(getOne 带异常控制)

@Test

public void testGetOneWithException() {

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.gt("age", 20);

// 当查询结果超过1条时,是否抛出异常

try {

User user = userService.getOne(queryWrapper, false); // 不抛出异常,返回第一条

System.out.println("查询结果:" + user);

} catch (Exception e) {

e.printStackTrace();

}

}

2. 地图查询与对象转换

@Test

public void testGetMap() {

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.eq("id", 1L);

Map<String, Object> userMap = userService.getMap(queryWrapper);

System.out.println("Map查询结果:" + userMap);

assertNotNull(userMap);

}

@Test

public void testGetObj() {

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.eq("id", 1L);

// 将查询结果转换为String类型(获取name字段)

String userName = userService.getObj(queryWrapper, obj -> {

if (obj instanceof User) {

return ((User) obj).getName();

}

return null;

});

System.out.println("转换结果:" + userName);

}

3. 批量查询扩展

@Test

public void testListMaps() {

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.lt("age", 25);

List<Map<String, Object>> mapList = userService.listMaps(queryWrapper);

System.out.println("Map列表大小:" + mapList.size());

assertFalse(mapList.isEmpty());

}

@Test

public void testListObjs() {

// 查询所有用户的ID并转换为Long类型

List<Long> idList = userService.listObjs((obj) -> {

if (obj instanceof User) {

return ((User) obj).getId();

}

return null;

});

idList.forEach(id -> System.out.println("用户ID:" + id));

}

@Test

public void testListObjsWithWrapper() {

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.gt("age", 22);

// 获取符合条件的用户邮箱

List<String> emailList = userService.listObjs(queryWrapper, obj -> {

if (obj instanceof User) {

return ((User) obj).getEmail();

}

return null;

});

emailList.forEach(email -> System.out.println("用户邮箱:" + email));

}

4. 分页查询扩展

@Test

public void testPageMaps() {

Page<Map<String, Object>> page = new Page<>(1, 5);

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.orderByAsc("age");

IPage<Map<String, Object>> mapIPage = userService.pageMaps(page, queryWrapper);

System.out.println("总页数:" + mapIPage.getPages());

System.out.println("当前页数据:" + mapIPage.getRecords());

}

九、链式查询与更新

1. 普通链式查询

@Test

public void testQueryChain() {

// 链式查询:年龄>20且邮箱包含qq.com的用户

List<User> userList = userService.query()

.gt("age", 20)

.like("email", "qq.com")

.list();

userList.forEach(System.out::println);

}

@Test

public void testLambdaQueryChain() {

// Lambda链式查询(类型安全)

List<User> userList = userService.lambdaQuery()

.gt(User::getAge, 20)

.like(User::getEmail, "qq.com")

.list();

userList.forEach(System.out::println);

}

2. 链式更新

@Test

public void testUpdateChain() {

// 链式更新:将name为"张三"的用户年龄改为25

boolean result = userService.update()

.eq("name", "张三")

.set("age", 25)

.update();

assertTrue(result);

}

@Test

public void testLambdaUpdateChain() {

// Lambda链式更新(类型安全)

boolean result = userService.lambdaUpdate()

.eq(User::getName, "李四")

.set(User::getAge, 26)

.update();

assertTrue(result);

}

3. Kotlin 链式操作(Java 中使用示例)

@Test

public void testKtQuery() {

// Kotlin风格链式查询(需引入Kotlin依赖)

List<User> userList = userService.ktQuery()

.gt(User::getAge, 20)

.list();

userList.forEach(System.out::println);

}

@Test

public void testKtUpdate() {

boolean result = userService.ktUpdate()

.eq(User::getName, "王五")

.set(User::getAge, 27)

.update();

assertTrue(result);

}

十、方法分类与使用场景总结

方法类型

核心方法

适用场景

基础 CRUD

save()、updateById()、removeById()、getById()

单条数据的增删改查

批量操作

saveBatch()、updateBatchById()、removeBatchByIds()

大量数据的批量处理

条件操作

update()、remove()、list()

带查询条件的操作

分页查询

page()、pageMaps()

大数据量分页展示

链式操作

lambdaQuery()、lambdaUpdate()

复杂条件的类型安全查询

转换操作

getMap()、getObj()、listObjs()

结果集的格式转换

十一、注意事项

  1. 事务控制:批量操作方法默认添加@Transactional注解,支持事务回滚
  1. 批次大小:默认批次大小为 1000,可根据数据库性能调整
  1. 逻辑删除:带useFill参数的方法用于逻辑删除,需配合实体类注解@TableLogic使用
  1. 类型安全:Lambda 表达式的链式操作可避免字符串硬编码,推荐使用
  1. 异常处理:getOne方法当结果集大于 1 时,需指定是否抛出异常

http://www.dtcms.com/a/301530.html

相关文章:

  • 【c++】从 “勉强能用” 到 “真正好用”:中文问答系统的 200 行关键优化——关于我用AI编写了一个聊天机器人……(16)
  • 中级全栈工程师笔试题
  • DP之背包基础
  • 详解力扣高频SQL50题之180. 连续出现的数字【困难】
  • CPA会计-5- 投资性房地产
  • 逆向入门(42)程序逆向篇-riijj_cm_20041121
  • 生态环境大数据技术专业的深度解析
  • 物理实验仿真平台设计与实现(抛体运动与电磁场交互)
  • 构建可扩展的状态系统:基于 ArkTS 的模块化状态管理设计与实现
  • MPI环形AllReduce算法实现与深度解析
  • lombok插件@NoArgsConstructor、@AllArgsConstructor、@RequiredArgsConstructor的区别
  • RS485 半双工系统中 DE 控制端默认 0 的技术原理与工程实践
  • (实用教程)Linux操作系统(二)
  • 零基础 “入坑” Java--- 十五、字符串String
  • 【I】题目解析
  • Spring MVC设计精粹:源码级架构解析与实践指南
  • 发布 VS Code 扩展的流程:以颜色主题为例
  • Python学习-----1.认识Python
  • 墨者:X-Forwarded-For注入漏洞实战
  • 解决ubantu系统下matplotlib中文乱码问题
  • MySQL进阶学习与初阶复习第四天
  • 数据库连接操作详解:左连接、右连接、全连接与内连接
  • ABP VNext + Elastic APM:微服务性能监控
  • 【优选算法】BFS解决最短路问题(单源)
  • 初始Redis:概念、特性、使用场景、安装教程
  • 六、搭建springCloudAlibaba2021.1版本分布式微服务-admin监控中心
  • IPv6的多级地址层次的理解
  • 设计模式(五)创建型:原型模式详解
  • 【ELasticsearch】节点角色分离最佳实践
  • 【LeetCode 热题 100】35. 搜索插入位置——二分查找(左闭右开)