MyBatis-Plus(Ⅲ)IService详解

目录

一、逐一演示

1.save(插入一条)

结果

断言(引入概念)

2.saveBatch(批量插入)

结果

3.saveOrUpdateBatch(批量插入&更新)

结果

4.removeById(通过id删除)

 结果

5.removeByMap(通过集合里的信息删除)

结果

 6.remove(通过条件删除)

解析

结果

 7.removeByIds(通过id批量删除)

结果

 8.updateById(通过id修改)

结果

9.update(通过条件修改)

 结果

10.updateBatchById(根据id批量更新)

 结果

11.saveOrUpdate(插入或修改)

 结果

12.getById(通过id查找)

结果

13.listByIds(查找多个id)

 结果

14.listByMap(通过集合信息查找)

 结果

15. getOne(判断获得是不是一条数据)

结果

 16.getMap(返回一条数据的内容)

结果 

 17.count(返回数量)

结果

加上判断

结果

​编辑 18. list(查找所有对象)

结果

加入条件 

 结果

19.page(分页)

结果

 20.listMaps(获取所有数据)

结果

list和listMaps的区别

21.listObjs(获取某字段-不指定默认是主键id)

结果

QueryWrapper

 22.其他

 二、源码展示


在前面两篇文章中已经对MyBatis-Plus有关Dao层的封装文件BaseMapper,这篇文章就它封装的service层IService进行解读和使用演示。

一、逐一演示

上面在源码上简单标注了一下每段代码功能,现在test中测试一下每段的具体使用和展示结果,这里测试用的数据库信息仍旧是MyBatis-Plus详解Ⅰ(请点击查看)里的数据信息。

1.save(插入一条)

/*** 测试插入单个实体对象* 验证:插入成功后返回 true,并且实体对象的主键不为 null*/@Testpublic void testSave() {User user = new User();user.setName("张三");user.setAge(20);boolean result = userService.save(user);
//        assertTrue(result);   //断言
//        assertNotNull(user.getId());System.out.println(result);}

结果

影响一条,插入成功(返回true)

断言(引入概念)

一般来说,在代码中插入断言语句,可以用来检查程序运行时的某些条件是否为真。如果条件为真,则程序继续运行;如果条件为假,则会抛出AssertionError异常。

当然在这里用到的并不是Java内置的断言机制,而是用的Assertions,即测试断言。

方法名称用法
assertEquals检查两个值是否相等
assertNotEquals检查两个值是否不相等
assertTrue检查某个条件是否为 true
assertFalse检查某个条件是否为 false
assertNull检查某个对象是否为 null
assertNotNull检查某个对象是否不为 null
assertThrows检查某个代码块是否抛出预期的异常
assertDoesNotThrow检查某个代码块是否不抛出异常
assertArrayEquals检查两个数组是否相等
assertSame检查两个对象是否是同一个实例
assertNotSame检查两个对象是否不是同一个实例
fail强制测试失败

上面这些方法同样遵循:如果条件不符合预期,方法会抛出一个 AssertionError(或其他具体的异常类型),导致测试失败。

为了代码可以顺利执行,我这里把断言注释掉了,用工作台的打印查看结果,下面同理。(一目了然,而且看起来也比较赏心悦目)

2.saveBatch(批量插入)

/*** 测试批量插入实体对象* 验证:批量插入成功后返回 true*/@Testpublic void testSaveBatch() {List<User> users = new ArrayList<>();User user1 = new User();user1.setName("李四");user1.setAge(22);User user2 = new User();user2.setName("王五");user2.setAge(23);users.add(user1);users.add(user2);boolean result = userService.saveBatch(users);System.out.println(result);}

结果

3.saveOrUpdateBatch(批量插入&更新)

 即存在定义的id值则是修改数据信息,不存在则是插入

   /*** 测试批量插入或更新实体对象* 验证:批量插入或更新成功后返回 true*/@Testpublic void testSaveOrUpdateBatch() {List<User> users = new ArrayList<>();User user1 = new User();user1.setName("赵六");user1.setAge(24);User user2 = new User();user2.setId(1L); // 假设数据库中已存在id为1的用户user2.setName("更新后的名字");user2.setAge(25);users.add(user1);users.add(user2);boolean result = userService.saveOrUpdateBatch(users);System.out.println(result);}

结果

4.removeById(通过id删除)

    /*** 测试根据主键id删除实体对象* 验证:删除成功后返回 true*/@Testpublic void testRemoveById() {Long id = 1L; // 假设数据库中存在id为1的用户boolean result = userService.removeById(id);System.out.println(result);}

 结果

注:这里返回false也无伤大雅,说明我的数据库中没有id是1的数据了(如果我用的是断言,那么这里就会报红色,代表测试不通过,所以我只用打印一下就知道我这里false是因为没有这一条数据而不报红) 

5.removeByMap(通过集合里的信息删除)

/*** 测试根据字段值删除实体对象* 验证:删除成功后返回 true*/@Testpublic void testRemoveByMap() {Map<String, Object> columnMap = new HashMap<>();columnMap.put("name", "张三");columnMap.put("age", 20);boolean result = userService.removeByMap(columnMap);System.out.println(result);}

这里表示代码要找到我的数据库中一条name叫张三,同时龄是20岁的数据进行删除。

结果

很显然,我的数据库中并不存在这么一条数据(false)

 6.remove(通过条件删除)

 /*** 测试根据条件删除实体对象* 验证:删除成功后返回 true*/@Testpublic void testRemove() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "李四").eq("age", 22);boolean result = userService.remove(queryWrapper);System.out.println(result);}

解析

QueryWrapper 是 MyBatis-Plus 提供的一个条件构造器,用于构建 SQL 查询条件;它会将这些条件翻译为 SQL 的 WHERE 子句,即:WHERE name = '李四' AND age = 22;

结果

 7.removeByIds(通过id批量删除)

/*** 测试根据主键列表批量删除实体对象* 验证:删除成功后返回 true*/@Testpublic void testRemoveByIds() {List<Long> ids = Arrays.asList(1L, 2L); // 假设数据库中存在id为1和2的用户boolean result = userService.removeByIds(ids);System.out.println(result);}

结果

很显然我的数据库中已经不存在这两个id了

 8.updateById(通过id修改)

    /*** 测试根据主键更新实体对象* 验证:更新成功后返回 true*/@Testpublic void testUpdateById() {User user = new User();user.setId(1L); // 假设数据库中存在id为1的用户user.setName("更新后的名字");user.setAge(26);boolean result = userService.updateById(user);System.out.println(result);}

结果

看来不存在id为1的数据了

9.update(通过条件修改)

/*** 测试根据条件更新实体对象* 验证:更新成功后返回 true*/@Testpublic void testUpdate() {UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.eq("name", "张三").set("age", 27);boolean result = userService.update(updateWrapper);System.out.println(result);}

 结果

看来不存在符合这个条件的

10.updateBatchById(根据id批量更新)

/*** 测试批量更新实体对象* 验证:批量更新成功后返回 true*/@Testpublic void testUpdateBatchById() {List<User> users = new ArrayList<>();User user1 = new User();user1.setId(1L); // 假设数据库中存在id为1的用户user1.setName("更新后的名字1");user1.setAge(28);User user2 = new User();user2.setId(2L); // 假设数据库中存在id为2的用户user2.setName("更新后的名字2");user2.setAge(29);users.add(user1);users.add(user2);boolean result = userService.updateBatchById(users);System.out.println(result);}

 结果

11.saveOrUpdate(插入或修改)

/*** 测试插入或更新单个实体对象* 验证:插入或更新成功后返回 true*/@Testpublic void testSaveOrUpdate() {User user = new User();user.setId(1L); // 假设数据库中存在id为1的用户user.setName("更新后的名字");user.setAge(30);boolean result = userService.saveOrUpdate(user);System.out.println(result);}

存在则修改,不存在则插入。 

 结果

12.getById(通过id查找)

/*** 测试根据主键获取实体对象* 验证:获取成功后返回的实体对象不为 null*/@Testpublic void testGetById() {Long id = 1L; // 假设数据库中存在id为1的用户User user = userService.getById(id);System.out.println(user);System.out.println(user.getName());}

结果

13.listByIds(查找多个id)

/*** 测试根据主键列表批量获取实体对象* 验证:返回的实体对象列表不为 null,且大小与主键列表一致*/@Testpublic void testListByIds() {List<Long> ids = Arrays.asList(1L, 2L); // 假设数据库中存在id为1和2的用户List<User> users = userService.listByIds(ids);System.out.println(users);System.out.println(users.size());}

 结果

14.listByMap(通过集合信息查找)

    /*** 测试根据字段值获取实体对象列表* 验证:返回的实体对象列表不为 null,且所有对象的字段值符合条件*/@Testpublic void testListByMap() {Map<String, Object> columnMap = new HashMap<>();columnMap.put("age", 20);List<User> users = userService.listByMap(columnMap);System.out.println(users);}

 结果

15. getOne(判断获得是不是一条数据)

    /*** 测试根据条件获取单个实体对象* 验证:获取成功后返回的实体对象不为 null*/@Testpublic void testGetOne() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "张三");User user = userService.getOne(queryWrapper);System.out.println(user);}

结果

超出一条或是没有都会异常(如果用断言的话)

①如果查询结果 恰好有一个 符合条件的记录,getOne 会返回这个记录对应的实体对象。

②如果查询结果 没有符合条件的记录getOne 的行为取决于是否启用异常抛出(由 throwEx 参数决定):

  • 如果 throwExtrue,会抛出异常(通常是 NullPointerException 或类似的异常)。

  • 如果 throwExfalse,返回 null

③如果查询结果 多于一个 符合条件的记录,getOne 会抛出异常(通常是 TooManyResultsException 或类似的异常),因为它的预期是查询结果 最多只有一个

 16.getMap(返回一条数据的内容)

 /*** 测试根据条件获取单个字段值(只能是一条数据,否则就报错)* 验证:获取成功后返回的字段值不为 null*/@Testpublic void testGetMap() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "张三");Map<String, Object> map = userService.getMap(queryWrapper);System.out.println(map);}

结果 

 17.count(返回数量)

/*** 测试统计实体对象数量* 验证:返回的数量大于等于 0*/@Testpublic void testCount() {long count = userService.count();assertTrue(count >= 0);System.out.println(count);}

结果

加上判断

/*** 测试根据条件统计实体对象数量* 验证:返回的数量大于等于 0*/@Testpublic void testCountWithQueryWrapper() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("age", 20);long count = userService.count(queryWrapper);assertTrue(count >= 0);System.out.println(count);}

结果

 18. list(查找所有对象)

    /*** 获取实体对象列表* 验证:返回的实体对象列表不为 null*/@Testpublic void testList() {List<User> users = userService.list();assertNotNull(users);System.out.println(users);}

结果

加入条件 

  1. 查询结果不为 null:确保查询返回的用户列表不为 null

  2. 所有用户的 age 字段不为 null:确保查询结果中的每个用户对象的 age 字段都有值(即不为 null

 /*** 测试根据条件获取实体对象列表* 验证:返回的实体对象列表不为 null,且所有对象符合条件*/@Testpublic void testListWithQueryWrapper() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.orderByAsc("age");List<User> users = userService.list(queryWrapper);assertNotNull(users);assertTrue(users.stream().allMatch(user -> user.getAge() != null));}

 结果

19.page(分页)

    /*** 测试分页查询实体对象* 验证:返回的分页对象不为 null,且分页数据正确*/@Testpublic void testPage() {// 创建 QueryWrapper 对象QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.orderByAsc("age"); // 按年龄升序排序// 创建分页对象Page<User> page = new Page<>(1, 3); // 第1页,每页3条// 执行分页查询Page<User> resultPage = userService.page(page, queryWrapper);// 打印分页结果System.out.println("===== 分页查询结果 =====");System.out.println("当前页码: " + resultPage.getCurrent());System.out.println("每页大小: " + resultPage.getSize());System.out.println("总记录数: " + resultPage.getTotal());System.out.println("总页数: " + resultPage.getPages());System.out.println("分页结果: ");for (User user : resultPage.getRecords()) { // 当前页的查询结果System.out.println("用户ID: " + user.getId() + ", 用户名: " + user.getName() + ", 年龄: " + user.getAge());}}

结果

如果结果不符合预期,可能是page插件未导入正确,需要手动配置一个配置类:

package com.example.mybatisplus.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;/*** 此配置类的作用是向 Spring 容器注册一个 MybatisPlusInterceptor 拦截器,* 该拦截器会在执行 SQL 时拦截分页查询语句,* 并自动处理分页逻辑,包含计算总记录数、总页数等。* */
@Configuration
public class MyBatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}

 20.listMaps(获取所有数据)

 /*** 测试获取实体对象的字段值列表* 验证:返回的字段值列表不为 null,且所有字段值符合条件*/@Testpublic void testListMaps() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.orderByAsc("age");List<Map<String, Object>> maps = userService.listMaps(queryWrapper);System.out.println(maps);}

结果

list和listMaps的区别

list 方法(数据信息封装在实体类):

  • 返回类型:List<T>,其中 T 是实体类类型。

  • 用途:返回一个包含实体对象的列表,每个实体对象代表一条记录。

listMaps 方法(数据信息封装在map集合中):

  • 返回类型:List<Map<String, Object>>

  • 用途:返回一个包含 Map 的列表,每个 Map 表示一条记录,键是字段名,值是字段值。

21.listObjs(获取某字段-不指定默认是主键id)

/*** 测试获取实体对象的字段值列表* 验证:返回的字段值列表不为 null,且所有字段值符合条件*/@Testpublic void testListObjs() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();// 指定要查询的列queryWrapper.select("name");// 使用 listObjs 方法获取 name 列的值List<Object> objNames = userService.listObjs(queryWrapper);System.out.println(objNames);}

结果

QueryWrapper

前面已经提到了QueryWrapper,现在来说一下QueryWrapper的常用方法:

方法描述示例
eq(String column, Object val)等于(=)queryWrapper.eq("age", 20);
ne(String column, Object val)不等于(<>)queryWrapper.ne("age", 20);
gt(String column, Object val)大于(>)queryWrapper.gt("age", 20);
ge(String column, Object val)大于等于(>=)queryWrapper.ge("age", 20);
lt(String column, Object val)小于(<)queryWrapper.lt("age", 20);
le(String column, Object val)小于等于(<=)queryWrapper.le("age", 20);
like(String column, Object val)模糊查询(LIKE)queryWrapper.like("name", "张%");
notLike(String column, Object val)模糊查询(NOT LIKE)queryWrapper.notLike("name", "张%");
in(String column, Collection<?> coll)IN 查询queryWrapper.in("age", Arrays.asList(20, 22, 24));
notIn(String column, Collection<?> coll)NOT IN 查询queryWrapper.notIn("age", Arrays.asList(20, 22, 24));
between(String column, Object val1, Object val2)BETWEEN 查询queryWrapper.between("age", 20, 24);
notBetween(String column, Object val1, Object val2)NOT BETWEEN 查询queryWrapper.notBetween("age", 20, 24);
orderByAsc(String column)按字段升序排序(ASC)queryWrapper.orderByAsc("age");
orderByDesc(String column)按字段降序排序(DESC)queryWrapper.orderByDesc("age");
and(Consumer<QueryWrapper<T>> consumer)AND 条件嵌套queryWrapper.and(wrapper -> wrapper.eq("age", 20).eq("name", "张三"));
or(Consumer<QueryWrapper<T>> consumer)OR 条件嵌套queryWrapper.or(wrapper -> wrapper.eq("age", 20).eq("name", "张三"));
isNotNull(String column)判断字段不为 NULLqueryWrapper.isNotNull("name");
isNull(String column)判断字段为 NULLqueryWrapper.isNull("name");

 22.其他

/*** 测试使用 QueryChainWrapper 查询实体对象(并且只有一个)* 验证:查询成功后返回的实体对象不为 null*/@Testpublic void testQueryChainWrapper() {User user = userService.query().eq("name", "张三").one();assertNotNull(user);assertEquals("张三", user.getName());}/*** 测试使用 LambdaQueryChainWrapper 查询实体对象(并且符合的只有一个)* 验证:查询成功后返回的实体对象不为 null*/@Testpublic void testLambdaQueryChainWrapper() {User user = userService.lambdaQuery().eq(User::getName, "张三").one();assertNotNull(user);assertEquals("张三", user.getName());}/*** 测试使用 UpdateChainWrapper 更新实体对象* 验证:更新成功后返回 true*/@Testpublic void testUpdateChainWrapper() {boolean result = userService.update().eq("name", "张三").set("age", 30).update();assertTrue(result);}/*** 测试使用 LambdaUpdateChainWrapper 更新实体对象* 验证:更新成功后返回 true*/@Testpublic void testLambdaUpdateChainWrapper() {boolean result = userService.lambdaUpdate().eq(User::getName, "张三").set(User::getAge, 31).update();assertTrue(result);}/*** 测试保存或更新实体对象,并指定更新条件* 验证:保存或更新成功后返回 true*/@Testpublic void testSaveOrUpdateWithUpdateWrapper() {User user = new User();user.setId(1L); // 假设数据库中存在id为1的用户user.setName("更新后的名字");user.setAge(32);UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.eq("id", user.getId());boolean result = userService.saveOrUpdate(user, updateWrapper);assertTrue(result);}

 二、源码展示

当然,可以看一下上面这些方法的源码,在此注释中会详细介绍每个方法的概念和功能。

package com.baomidou.mybatisplus.extension.service;import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.kotlin.KtQueryChainWrapper;
import com.baomidou.mybatisplus.extension.kotlin.KtUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.springframework.transaction.annotation.Transactional;/*** 通用服务接口,提供基础的CRUD操作* @param <T> 实体类类型*/
public interface IService<T> {int DEFAULT_BATCH_SIZE = 1000;/*** 保存实体对象* @param entity 实体对象* @return 是否保存成功*/default boolean save(T entity) {return SqlHelper.retBool(this.getBaseMapper().insert(entity));}/*** 批量保存实体列表* @param entityList 实体列表* @return 是否保存成功*/@Transactional(rollbackFor = {Exception.class})default boolean saveBatch(Collection<T> entityList) {return this.saveBatch(entityList, 1000);}/*** 批量保存实体列表,可指定批量大小* @param entityList 实体列表* @param batchSize 批量大小* @return 是否保存成功*/boolean saveBatch(Collection<T> entityList, int batchSize);/*** 批量保存或更新实体列表* @param entityList 实体列表* @return 是否保存成功*/@Transactional(rollbackFor = {Exception.class})default boolean saveOrUpdateBatch(Collection<T> entityList) {return this.saveOrUpdateBatch(entityList, 1000);}/*** 批量保存或更新实体列表,可指定批量大小* @param entityList 实体列表* @param batchSize 批量大小* @return 是否保存成功*/boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);/*** 根据ID删除实体对象* @param id 实体ID* @return 是否删除成功*/default boolean removeById(Serializable id) {return SqlHelper.retBool(this.getBaseMapper().deleteById(id));}/*** 根据ID删除实体对象,可指定是否使用填充策略* @param id 实体ID* @param useFill 是否使用填充策略* @return 是否删除成功*/default boolean removeById(Serializable id, boolean useFill) {throw new UnsupportedOperationException("不支持的方法!");}/*** 根据实体对象删除* @param entity 实体对象* @return 是否删除成功*/default boolean removeById(T entity) {return SqlHelper.retBool(this.getBaseMapper().deleteById(entity));}/*** 根据条件Map删除* @param columnMap 条件Map* @return 是否删除成功*/default boolean removeByMap(Map<String, Object> columnMap) {Assert.notEmpty(columnMap, "error: columnMap must not be empty", new Object[0]);return SqlHelper.retBool(this.getBaseMapper().deleteByMap(columnMap));}/*** 根据条件删除* @param queryWrapper 条件* @return 是否删除成功*/default boolean remove(Wrapper<T> queryWrapper) {return SqlHelper.retBool(this.getBaseMapper().delete(queryWrapper));}/*** 根据ID列表批量删除* @param list ID列表* @return 是否删除成功*/default boolean removeByIds(Collection<?> list) {return CollectionUtils.isEmpty(list) ? false : SqlHelper.retBool(this.getBaseMapper().deleteBatchIds(list));}/*** 根据ID列表批量删除,可指定是否使用填充策略* @param list ID列表* @param useFill 是否使用填充策略* @return 是否删除成功*/@Transactional(rollbackFor = {Exception.class})default boolean removeByIds(Collection<?> list, boolean useFill) {if (CollectionUtils.isEmpty(list)) {return false;} else {return useFill ? this.removeBatchByIds(list, true) : SqlHelper.retBool(this.getBaseMapper().deleteBatchIds(list));}}/*** 根据ID列表批量删除,可指定批量大小* @param list ID列表* @return 是否删除成功*/@Transactional(rollbackFor = {Exception.class})default boolean removeBatchByIds(Collection<?> list) {return this.removeBatchByIds(list, 1000);}/*** 根据ID列表批量删除,可指定批量大小和是否使用填充策略* @param list ID列表* @param useFill 是否使用填充策略* @return 是否删除成功*/@Transactional(rollbackFor = {Exception.class})default boolean removeBatchByIds(Collection<?> list, boolean useFill) {return this.removeBatchByIds(list, 1000, useFill);}/*** 根据ID列表批量删除,可指定批量大小和是否使用填充策略* @param list ID列表* @param batchSize 批量大小* @return 是否删除成功*/default boolean removeBatchByIds(Collection<?> list, int batchSize) {throw new UnsupportedOperationException("不支持的方法!");}/*** 根据ID列表批量删除,可指定批量大小和是否使用填充策略* @param list ID列表* @param batchSize 批量大小* @param useFill 是否使用填充策略* @return 是否删除成功*/default boolean removeBatchByIds(Collection<?> list, int batchSize, boolean useFill) {throw new UnsupportedOperationException("不支持的方法!");}/*** 根据ID更新实体对象* @param entity 实体对象* @return 是否更新成功*/default boolean updateById(T entity) {return SqlHelper.retBool(this.getBaseMapper().updateById(entity));}/*** 根据条件更新* @param updateWrapper 条件* @return 是否更新成功*/default boolean update(Wrapper<T> updateWrapper) {return this.update((Object)null, updateWrapper);}/*** 根据条件更新实体对象* @param entity 实体对象* @param updateWrapper 条件* @return 是否更新成功*/default boolean update(T entity, Wrapper<T> updateWrapper) {return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));}/*** 根据ID列表批量更新* @param entityList 实体列表* @return 是否更新成功*/@Transactional(rollbackFor = {Exception.class})default boolean updateBatchById(Collection<T> entityList) {return this.updateBatchById(entityList, 1000);}/*** 根据ID列表批量更新,可指定批量大小* @param entityList 实体列表* @param batchSize 批量大小* @return 是否更新成功*/boolean updateBatchById(Collection<T> entityList, int batchSize);/*** 保存或更新实体对象* @param entity 实体对象* @return 是否保存成功*/boolean saveOrUpdate(T entity);/*** 根据ID获取实体对象* @param id 实体ID* @return 实体对象*/default T getById(Serializable id) {return this.getBaseMapper().selectById(id);}/*** 根据ID列表批量获取实体列表* @param idList ID列表* @return 实体列表*/default List<T> listByIds(Collection<? extends Serializable> idList) {return this.getBaseMapper().selectBatchIds(idList);}/*** 根据条件Map获取实体列表* @param columnMap 条件Map* @return 实体列表*/default List<T> listByMap(Map<String, Object> columnMap) {return this.getBaseMapper().selectByMap(columnMap);}/*** 根据条件获取单个实体对象* @param queryWrapper 条件* @return 实体对象*/default T getOne(Wrapper<T> queryWrapper) {return this.getOne(queryWrapper, true);}/*** 根据条件获取单个实体对象,可指定是否抛出异常* @param queryWrapper 条件* @param throwEx 是否抛出异常* @return 实体对象*/T getOne(Wrapper<T> queryWrapper, boolean throwEx);/*** 根据条件获取Map* @param queryWrapper 条件* @return Map*/Map<String, Object> getMap(Wrapper<T> queryWrapper);/*** 根据条件获取单个字段值* @param queryWrapper 条件* @param mapper 映射函数* @param <V> 字段值类型* @return 字段值*/<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);/*** 获取记录总数* @return 记录总数*/default long count() {return this.count(Wrappers.emptyWrapper());}/*** 根据条件获取记录总数* @param queryWrapper 条件* @return 记录总数*/default long count(Wrapper<T> queryWrapper) {return SqlHelper.retCount(this.getBaseMapper().selectCount(queryWrapper));}/*** 根据条件获取实体列表* @param queryWrapper 条件* @return 实体列表*/default List<T> list(Wrapper<T> queryWrapper) {return this.getBaseMapper().selectList(queryWrapper);}/*** 获取所有实体列表* @return 实体列表*/default List<T> list() {return this.list(Wrappers.emptyWrapper());}/*** 分页查询* @param page 分页参数* @param queryWrapper 条件* @param <E> 分页类型* @return 分页结果*/default <E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper) {return this.getBaseMapper().selectPage(page, queryWrapper);}/*** 分页查询* @param page 分页参数* @param <E> 分页类型* @return 分页结果*/default <E extends IPage<T>> E page(E page) {return this.page(page, Wrappers.emptyWrapper());}/*** 根据条件获取Map列表* @param queryWrapper 条件* @return Map列表*/default List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper) {return this.getBaseMapper().selectMaps(queryWrapper);}/*** 获取所有Map列表* @return Map列表*/default List<Map<String, Object>> listMaps() {return this.listMaps(Wrappers.emptyWrapper());}/*** 获取单个字段值列表* @return 字段值列表*/default List<Object> listObjs() {return this.listObjs(Function.identity());}/*** 根据条件获取单个字段值列表* @param mapper 映射函数* @param <V> 字段值类型* @return 字段值列表*/default <V> List<V> listObjs(Function<? super Object, V> mapper) {return this.listObjs(Wrappers.emptyWrapper(), mapper);}/*** 根据条件获取单个字段值列表* @param queryWrapper 条件* @return 字段值列表*/default List<Object> listObjs(Wrapper<T> queryWrapper) {return this.listObjs(queryWrapper, Function.identity());}/*** 根据条件获取单个字段值列表* @param queryWrapper 条件* @param mapper 映射函数* @param <V> 字段值类型* @return 字段值列表*/default <V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {return (List)this.getBaseMapper().selectObjs(queryWrapper).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList());}/*** 分页查询Map* @param page 分页参数* @param queryWrapper 条件* @param <E> 分页类型* @return 分页结果*/default <E extends IPage<Map<String, Object>>> E pageMaps(E page, Wrapper<T> queryWrapper) {return this.getBaseMapper().selectMapsPage(page, queryWrapper);}/*** 分页查询Map* @param page 分页参数* @param <E> 分页类型* @return 分页结果*/default <E extends IPage<Map<String, Object>>> E pageMaps(E page) {return this.pageMaps(page, Wrappers.emptyWrapper());}/*** 获取基础Mapper* @return 基础Mapper*/BaseMapper<T> getBaseMapper();/*** 获取实体类类型* @return 实体类类型*/Class<T> getEntityClass();/*** 获取查询链式操作* @return 查询链式操作*/default QueryChainWrapper<T> query() {return ChainWrappers.queryChain(this.getBaseMapper());}/*** 获取Lambda查询链式操作* @return Lambda查询链式操作*/default LambdaQueryChainWrapper<T> lambdaQuery() {return ChainWrappers.lambdaQueryChain(this.getBaseMapper());}/*** 获取Kotlin查询链式操作* @return Kotlin查询链式操作*/default KtQueryChainWrapper<T> ktQuery() {return ChainWrappers.ktQueryChain(this.getBaseMapper(), this.getEntityClass());}/*** 获取Kotlin更新链式操作* @return Kotlin更新链式操作*/default KtUpdateChainWrapper<T> ktUpdate() {return ChainWrappers.ktUpdateChain(this.getBaseMapper(), this.getEntityClass());}/*** 获取更新链式操作* @return 更新链式操作*/default UpdateChainWrapper<T> update() {return ChainWrappers.updateChain(this.getBaseMapper());}/*** 获取Lambda更新链式操作* @return Lambda更新链式操作*/default LambdaUpdateChainWrapper<T> lambdaUpdate() {return ChainWrappers.lambdaUpdateChain(this.getBaseMapper());}/*** 保存或更新实体对象,可指定更新条件* @param entity 实体对象* @param updateWrapper 更新条件* @return 是否保存成功*/default boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper) {return this.update(entity, updateWrapper) || this.saveOrUpdate(entity);}
}

 想参考的可以看一下这个源码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/42033.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

可视化图解算法:删除有序(排序)链表中重复的元素-II

1. 题目 描述 给出一个升序排序的链表&#xff0c;删除链表中的所有重复出现的元素&#xff0c;只保留原链表中只出现一次的元素。 例如&#xff1a; 给出的链表为1→2→3→3→4→4→5, 返回1→2→5. 给出的链表为1→1→1→2→3 返回2→3. 数据范围&#xff1a;链表长度 0≤…

23种设计模式-中介者(Mediator)设计模式

中介者设计模式 &#x1f6a9;什么是中介者设计模式&#xff1f;&#x1f6a9;中介者设计模式的特点&#x1f6a9;中介者设计模式的结构&#x1f6a9;中介者设计模式的优缺点&#x1f6a9;中介者设计模式的Java实现&#x1f6a9;代码总结&#x1f6a9;总结 &#x1f6a9;什么是…

基于云服务器的数仓搭建-hive/spark安装

mysql本地安装 安装流程&#xff08;内存占用200M&#xff0c;升至2.1G&#xff09; # 将资料里mysql文件夹及里面所有内容上传到/opt/software/mysql目录下 mkdir /opt/software/mysql cd /opt/software/mysql/ # 待上传文件 install_mysql.sh mysql-community-client-8.0.3…

华为配置篇-ISIS基础实验

ISIS 一、简述二、常用命令总结三、实验 一、简述 一、基本定义与历史背景 IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是一种链路状态路由协议&#xff0c;最初由ISO设计用于OSI&#xff08;开放系统互联&#…

Python 练习项目:MBTI 命令行测试工具

在当今数字化的时代,心理测试工具越来越受到欢迎,它们帮助人们更好地了解自己,做出更明智的职业选择,甚至改善人际关系。MBTI(迈尔斯-布里格斯性格分类法)是其中一种广为人知的人格测试,通过评估个人在四个维度上的偏好(外向-内向、实感-直觉、理智-情感、判断-理解),…

github使用

登录github&#xff0c;创建仓库&#xff08;repository&#xff09; 如创建一个ADXL345名字的私有仓库 git下载安装 打开git&#xff1a;鼠标右键&#xff0c;选择“Open Git Bash here”&#xff0c;进入 ⭐Git 和 GitHub 绑定 Git 获取SSH keys $ cd ~/.ssh #查看 …

如何在Windows上下载并配置GO语言环境变量

本章教程,主要介绍如何在Windows操作系统上,下载并配置GO语言环境变量。 Go(又称为Golang)是一种开源的编程语言,由Google开发,于2009年首次公开发布。它旨在提供简洁、高效、可靠的软件开发解决方案。Golang是一种静态强类型、编译型语言,Golang具有很强的表达能力,得…

【Linux网络(五)】传输层协议

目录 1、UDP协议 1.1、UDP报头 2、TCP协议 2.1、tcp协议段格式 2.2、TCP三次握手的过程 2.3、TCP四次挥手的过程 2.4、流量控制 2.5、滑动窗口 2.6、延迟应答 2.7、拥塞控制 2.8、面向字节流 2.9、数据粘包 2.10、TCP连接异常问题 1、UDP协议 学习目标&#xff1a…

第十二:josn 传递参数 shouldBindJSON 和结构体的 db字段

链接&#xff1a; Golang教程三&#xff08;结构体、自定义数据类型&#xff0c;接口&#xff09;_golang 自定义数据类型-CSDN博客 结构体指向 json 和数据库的 db type User struct { ID int json:"id" db:"user_id" Name string json:…

Retinexformer:基于 Retinex 的单阶段 Transformer 低光照图像增强方法

开头发点牢骚&#xff1a;本来做的好好都都要中期了&#xff0c;导师怎么突然给我换题目啊。真是绷不住了......又要从头开始学了&#xff0c;唉&#xff01; 原论文链接&#xff1a;Retinexformer: One-stage Retinex-based Transformer for Low-light Image Enhancement 低光…

游戏引擎学习第182天

回顾和今天的计划 昨天的进展令人惊喜&#xff0c;原本的调试系统已经被一个新的系统完全替换&#xff0c;新系统不仅能完成原有的所有功能&#xff0c;还能捕获完整的调试信息&#xff0c;包括时间戳等关键数据。这次的替换非常顺利&#xff0c;效果很好。 今天的重点是在此基…

关于我对接了deepseek之后部署到本地将数据存储到mysql的过程

写在前面 今天写一下使用nodejs作为服务端&#xff0c;vue作为客户端&#xff0c;mysql的数据库&#xff0c;对接deepseek的全过程&#xff0c;要实现一个很简单的效果就是&#xff0c;可以自由的询问&#xff0c;然后可以将询问的过程存储到mysql的数据库中。 文档对接 deeps…

Git 提示 “LF will be replaced by CRLF“ 的原因及解决方案

遇到的问题: warning: in the working copy of build/build.js, LF will be replaced by CRLF the next time Git touches it warning: in the working copy of build/check-versions.js, LF will be replaced by CRLF the next time Git touches it warning: in the worki…

Axure设计之中继器表格——拖动列调整位置教程(中继器)

一、原理介绍 实现表格列的拖动排序&#xff0c;主要依赖Axure的动态面板和中继器两大核心功能&#xff1a; 动态面板交互控制 将表格的列标题封装在动态面板中&#xff0c;通过拖拽事件&#xff08;开始、移动、结束&#xff09;捕捉用户操作 在拖拽过程中实时计算鼠标位置&…

IDEA工具使用之启动项目失败且无日志打印

IDEA工具使用之启动项目失败且无日志打印 问题描述原因分析解决方案方案一&#xff1a;使用类路径缩短方案&#xff08;推荐&#xff09;方案二&#xff1a;修改启动配置 总结 问题描述 概述 新拉取的项目&#xff0c;基于IDEA本地调试启动失败&#xff0c;控制台也没有跳转打…

GC overhead limit exceeded---Java 虚拟机 (JVM) 在进行垃圾回收内存量非常少解决

背景&#xff1a; 我正在跑一个数据处理较为复杂的程序。然后调试了很多遍&#xff0c;出现了GC问题&#xff0c;如下图bug. GC overhead limit exceeded-这个bug错误通常表示 Java 虚拟机 (JVM) 在进行垃圾回收时花费了过多的时间&#xff0c;并且回收的内存量非常少。…

SAP GUI Script for C# SAP脚本开发快速指南与默认主题问题

SAP GUI Script for C# 快速指南 SAP 脚本的快速使用与设置. 解决使用SAP脚本执行后,默认打开的SAP是经典主题的问题 1. 解决默认主题问题 如果您使用的是SAP GUI 740,并遇到无法打开对话框的问题,请先将主题设置为经典主题(Classic Theme),应用更改后重新打开SAP GUI …

测试用例`

1.什么是测试用例 测试⽤例&#xff08;Test Case&#xff09;是为了实施测试⽽向被测试的系统提供的⼀组集合&#xff0c;这组集合包含&#xff1a;测试环境、操作步骤、测试数据、预期结果等要素. 2.测试用例的万能公式(重点) 设计测试⽤例的万能公式&#xff1a; 功能测试界…

【深度学习】【目标检测】【OnnxRuntime】【C++】YOLOV5模型部署

【深度学习】【目标检测】【OnnxRuntime】【C】YOLOV5模型部署 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】【目标检测】【OnnxRuntime】【C】YOLOV5模型部署前言Windows平台搭建依赖环境模型转换--pytorch转onnxONNXRuntime推…

Qt:QWebEngineView显示网页失败

今天在新电脑搭建qt开发环境&#xff0c;在运行程序时发现通过QWebEngineView显示的html失败&#xff0c;同样的代码在旧电脑上没有这个问题 分析过程 &#xff08;1&#xff09;qt出现如下信息提示 [21296:12076:0325/161831.084:ERROR:platform_handle_in_transit.cc(34)] …