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

设计模式扩展 MyBatis Plus BaseMapper接口

pom

<dependency>
	<groupId>com.github.yulichang</groupId>
	<artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 -->
</dependency>

java


/**
 1. 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力
 2.  3. 1. {@link BaseMapper} 为 MyBatis Plus 的基础接口,提供基础的 CRUD 能力
 4. 2. {@link MPJBaseMapper} 为 MyBatis Plus Join 的基础接口,提供连表 Join 能力
 */
public interface BaseMapperX<T> extends MPJBaseMapper<T> {

    default PageResult<T> selectPage(SortablePageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
        return selectPage(pageParam, pageParam.getSortingFields(), queryWrapper);
    }

    default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
        return selectPage(pageParam, null, queryWrapper);
    }

    default PageResult<T> selectPage(PageParam pageParam, Collection<SortingField> sortingFields, @Param("ew") Wrapper<T> queryWrapper) {
        // 特殊:不分页,直接查询全部
        if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
            List<T> list = selectList(queryWrapper);
            return new PageResult<>(list, (long) list.size());
        }

        // MyBatis Plus 查询
        IPage<T> mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);
        selectPage(mpPage, queryWrapper);
        // 转换返回
        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
    }

    default <D> PageResult<D> selectJoinPage(PageParam pageParam, Class<D> clazz, MPJLambdaWrapper<T> lambdaWrapper) {
        // 特殊:不分页,直接查询全部
        if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
            List<D> list = selectJoinList(clazz, lambdaWrapper);
            return new PageResult<>(list, (long) list.size());
        }

        // MyBatis Plus Join 查询
        IPage<D> mpPage = MyBatisUtils.buildPage(pageParam);
        mpPage = selectJoinPage(mpPage, clazz, lambdaWrapper);
        // 转换返回
        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
    }

    default <DTO> PageResult<DTO> selectJoinPage(PageParam pageParam, Class<DTO> resultTypeClass, MPJBaseJoin<T> joinQueryWrapper) {
        IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam);
        selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper);
        // 转换返回
        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
    }

    default T selectOne(String field, Object value) {
        return selectOne(new QueryWrapper<T>().eq(field, value));
    }



    default T selectOne(SFunction<T, ?> field, Object value) {
        return selectOne(new LambdaQueryWrapper<T>().eq(field, value));
    }





    default T selectOne(String field1, Object value1, String field2, Object value2) {
        return selectOne(new QueryWrapper<T>().eq(field1, value1).eq(field2, value2));
    }

    default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
        return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
    }

    default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2,
                        SFunction<T, ?> field3, Object value3) {
        return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2)
                .eq(field3, value3));
    }

    default Long selectCount() {
        return selectCount(new QueryWrapper<>());
    }

    default Long selectCount(String field, Object value) {
        return selectCount(new QueryWrapper<T>().eq(field, value));
    }

    default Long selectCount(SFunction<T, ?> field, Object value) {
        return selectCount(new LambdaQueryWrapper<T>().eq(field, value));
    }

    default List<T> selectList() {
        return selectList(new QueryWrapper<>());
    }

    default List<T> selectList(String field, Object value) {
        return selectList(new QueryWrapper<T>().eq(field, value));
    }

    default List<T> selectList(SFunction<T, ?> field, Object value) {
        return selectList(new LambdaQueryWrapper<T>().eq(field, value));
    }

    default List<T> selectList(String field, Collection<?> values) {
        if (CollUtil.isEmpty(values)) {
            return CollUtil.newArrayList();
        }
        return selectList(new QueryWrapper<T>().in(field, values));
    }

    default List<T> selectList(SFunction<T, ?> field, Collection<?> values) {
        if (CollUtil.isEmpty(values)) {
            return CollUtil.newArrayList();
        }
        return selectList(new LambdaQueryWrapper<T>().in(field, values));
    }

    default List<T> selectList(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
        return selectList(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
    }

    /**
     * 批量插入,适合大量数据插入
     *
     * @param entities 实体们
     */
    default Boolean insertBatch(Collection<T> entities) {
        // 特殊:SQL Server 批量插入后,获取 id 会报错,因此通过循环处理
        DbType dbType = JdbcUtils.getDbType();
        if (JdbcUtils.isSQLServer(dbType)) {
            entities.forEach(this::insert);
            return CollUtil.isNotEmpty(entities);
        }
        return Db.saveBatch(entities);
    }

    /**
     * 批量插入,适合大量数据插入
     *
     * @param entities 实体们
     * @param size     插入数量 Db.saveBatch 默认为 1000
     */
    default Boolean insertBatch(Collection<T> entities, int size) {
        // 特殊:SQL Server 批量插入后,获取 id 会报错,因此通过循环处理
        DbType dbType = JdbcUtils.getDbType();
        if (JdbcUtils.isSQLServer(dbType)) {
            entities.forEach(this::insert);
            return CollUtil.isNotEmpty(entities);
        }
        return Db.saveBatch(entities, size);
    }

    default int updateBatch(T update) {
        return update(update, new QueryWrapper<>());
    }

    default Boolean updateBatch(Collection<T> entities) {
        return Db.updateBatchById(entities);
    }

    default Boolean updateBatch(Collection<T> entities, int size) {
        return Db.updateBatchById(entities, size);
    }

    default int delete(String field, String value) {
        return delete(new QueryWrapper<T>().eq(field, value));
    }

    default int delete(SFunction<T, ?> field, Object value) {
        return delete(new LambdaQueryWrapper<T>().eq(field, value));
    }
}

一、核心定位

BaseMapperX 是 MyBatis Plus BaseMapper 的增强扩展接口,通过 统一封装高频操作 和 联表查询支持,解决以下痛点:

  1. 减少样板代码:内置分页、单字段查询等高频方法
  2. 类型安全:通过 Lambda 表达式避免字段名硬编码
  3. 多表联查简化:集成 MyBatis Plus Join 能力
  4. 数据库兼容:处理 SQL Server 等特殊批量插入场景

二、关键增强功能

1. 分页查询统一封装

// 原生 MyBatis Plus 分页
IPage<UserDO> page = new Page<>(1, 10);
mapper.selectPage(page, queryWrapper);
PageResult<UserDO> result = new PageResult<>(page.getRecords(), page.getTotal());

// 使用 BaseMapperX 简化后
PageResult<UserDO> result = mapper.selectPage(pageParam, queryWrapper);

2. 联表分页查询

PageResult<UserDeptVO> result = mapper.selectJoinPage(
    pageParam, UserDeptVO.class, 
    new MPJLambdaWrapperX<UserDO>()
        .selectAll(UserDO.class)
        .leftJoin(DepartmentDO.class, ...)
);

3. 高频单表操作

// 根据单个字段查询
UserDO user = mapper.selectOne(UserDO::getUsername, "yudaoyuanma");

// 根据多个字段查询
UserDO user = mapper.selectOne(
    UserDO::getUsername, "yudaoyuanma",
    UserDO::getStatus, 0
);

// 批量插入(自动处理 SQL Server 兼容)
mapper.insertBatch(users);

三、设计模式解析

1. 模板方法模式(Template Method)

  • 体现:selectPage 方法统一分页处理流程
public default PageResult<T> selectPage(PageParam pageParam, Wrapper<T> queryWrapper) {
    // 1. 构建分页参数(模板步骤)
    IPage<T> mpPage = MyBatisUtils.buildPage(pageParam);
    // 2. 执行查询(具体实现由 MyBatis Plus 提供)
    selectPage(mpPage, queryWrapper);
    // 3. 结果转换(模板步骤)
    return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
}

2. 门面模式(Facade)

  • 体现:对复杂联表查询进行高层抽象
public default <D> PageResult<D> selectJoinPage(...) {
    // 隐藏联表查询的复杂性
    IPage<D> mpPage = MyBatisUtils.buildPage(pageParam);
    selectJoinPage(mpPage, clazz, lambdaWrapper);
    return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
}

3. 策略模式(Strategy)

  • 体现:根据数据库类型切换批量插入策略
default Boolean insertBatch(Collection<T> entities) {
    if (JdbcUtils.isSQLServer()) { // SQL Server 策略
        entities.forEach(this::insert);
    } else { // 通用策略
        Db.saveBatch(entities);
    }
    return true;
}

四、与原生 API 对比

功能MyBatis Plus BaseMapperBaseMapperX
分页封装需手动处理 IPage 对象直接返回 PageResult 统一结构
联表查询不支持支持连表分页查询与 VO 映射
字段条件方法需手动写 QueryWrapper提供 selectOne(field, value) 等快捷方法
批量插入兼容性需自行处理数据库差异内置 SQL Server 特殊逻辑

相关文章:

  • java学习笔记10——集合框架
  • 蚂蚁集团主导的ISO密码学国际标准立项,纳入国产算法
  • AI赋能股票:流通股本与总股本:定义、区别及投资意义解析
  • 【STM32单片机】#4 OLED调试外部中断
  • StarRocks的执行计划和Profile
  • 微软 GraphRAG 项目学习总结
  • ubuntu的ubuntu--vg-ubuntu--lv磁盘扩容
  • 黑盒测试、白盒测试、集成测试和系统测试的区别与联系
  • 在 Windows 中使用 DeepSeek 和 Milvus 搭建个人知识库
  • 新加坡国立大学张阳团队开发第二代RNA结构预测算法,多项基准测试超越SOTA
  • 【橘子大模型】使用LangChain和LLM交互
  • 为AI聊天工具添加一个知识系统 之157: Firstness,Secondness和Thirdness
  • Odoo/OpenERP 和 psql 命令行的快速参考总结
  • 51单片机总结
  • mac m 芯片 动态切换 jdk 版本jdk8.jdk11.jdk17
  • 食品计算—Ingredient-Guided RGB-D Fusion Network for Nutritional Assessment
  • 低代码平台,智慧城市建设的加速器
  • Docker学习--容器生命周期管理相关命令--docker pause/unpause 命令
  • 物联网开发项目:AS608+ESP32S3+Vue构建指纹识别系统(二)——ESP32部分
  • Vue React
  • 做区域分析的地图网站/响应式网站模板的应用
  • 美食网站建设策划书/网络营销服务商有哪些
  • 区块链网站建设/分销渠道
  • 河北建设行业信息网站/鼓楼网站seo搜索引擎优化
  • 个人求职网站如何做/新媒体销售好做吗
  • 吉安市网站制作/购物网站制作