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

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
     */
    @Test
    public 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
   */
    @Test
    public 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
     */
    @Test
    public 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
     */
    @Test
    public void testRemoveById() {
        Long id = 1L; // 假设数据库中存在id为1的用户
        boolean result = userService.removeById(id);
        System.out.println(result);
    }

 结果

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

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

/**
     * 测试根据字段值删除实体对象
     * 验证:删除成功后返回 true
     */
    @Test
    public 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
     */
    @Test
    public 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
     */
    @Test
    public 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
     */
    @Test
    public 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
     */
    @Test
    public 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
     */
    @Test
    public 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
     */
    @Test
    public 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
     */
    @Test
    public 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,且大小与主键列表一致
     */
    @Test
    public 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,且所有对象的字段值符合条件
     */
    @Test
    public 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
     */
    @Test
    public 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
     */
    @Test
    public void testGetMap() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", "张三");
        Map<String, Object> map = userService.getMap(queryWrapper);
        System.out.println(map);
    }

结果 

 17.count(返回数量)

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

结果

加上判断

/**
     * 测试根据条件统计实体对象数量
     * 验证:返回的数量大于等于 0
     */
    @Test
    public 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
     */
    @Test
    public void testList() {
        List<User> users = userService.list();
        assertNotNull(users);
        System.out.println(users);
    }

结果

加入条件 

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

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

 /**
     * 测试根据条件获取实体对象列表
     * 验证:返回的实体对象列表不为 null,且所有对象符合条件
     */
    @Test
    public 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,且分页数据正确
     */
    @Test
    public 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 {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

 20.listMaps(获取所有数据)

 /**
     * 测试获取实体对象的字段值列表
     * 验证:返回的字段值列表不为 null,且所有字段值符合条件
     */
    @Test
    public 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,且所有字段值符合条件
     */
    @Test
    public 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
     */
    @Test
    public void testQueryChainWrapper() {
        User user = userService.query().eq("name", "张三").one();
        assertNotNull(user);
        assertEquals("张三", user.getName());
    }

    /**
     * 测试使用 LambdaQueryChainWrapper 查询实体对象(并且符合的只有一个)
     * 验证:查询成功后返回的实体对象不为 null
     */
    @Test
    public void testLambdaQueryChainWrapper() {
        User user = userService.lambdaQuery().eq(User::getName, "张三").one();
        assertNotNull(user);
        assertEquals("张三", user.getName());
    }

    /**
     * 测试使用 UpdateChainWrapper 更新实体对象
     * 验证:更新成功后返回 true
     */
    @Test
    public void testUpdateChainWrapper() {
        boolean result = userService.update().eq("name", "张三").set("age", 30).update();
        assertTrue(result);
    }

    /**
     * 测试使用 LambdaUpdateChainWrapper 更新实体对象
     * 验证:更新成功后返回 true
     */
    @Test
    public void testLambdaUpdateChainWrapper() {
        boolean result = userService.lambdaUpdate().eq(User::getName, "张三").set(User::getAge, 31).update();
        assertTrue(result);
    }

    /**
     * 测试保存或更新实体对象,并指定更新条件
     * 验证:保存或更新成功后返回 true
     */
    @Test
    public 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.kler.cn/a/612337.html

相关文章:

  • python蓝桥杯刷题的重难点知识笔记
  • 【RHCE】LVS-NAT模式负载均衡实验
  • Flask接口开发--POST接口
  • 数据仓库 - 转转 - 一面凉经
  • 算力盒子VS边缘计算盒子
  • 脉冲编码器:精准定位与高效控制的科技先锋
  • 创建login.api.js步骤和方法
  • 【蓝桥杯】重点冲刺
  • ubuntu24.04.2 NVIDIA GeForce RTX 4060笔记本安装驱动
  • Milvus 与 Spring Boot 集成
  • SpringMVC 拦截器详解与实战
  • GAUSSDB 分布式存储机制深度解析
  • sortablejs el-table 树结构拖拽
  • PHP中yield关键字的使用
  • RestTemplate远程调用接口方式
  • 什么是视图,数据库的视图本质上就是个提前写好的sql语句,创建的一个虚拟表
  • C语言中把函数声明为inline是什么意思?
  • Nginx RTMP 处理模块 (ngx_rtmp_handler.c) 详细分析
  • Go语言分布式锁实战:dlock助力构建高并发稳定系统
  • 工作流引擎Flowable介绍及SpringBoot整合使用实例