MybatisPlus怎么拓展自定义BaseMapper

程序浅谈 后端 2024-08-05

MybatisPlus怎么拓展自定义BaseMapper

前言

Mybatis-plus提供的BaseMapper中已经有频繁要使用的增删改查方法,比如selectByIdinsert等,但是有时候业务经常要用到某个模板sql,BaseMapper中又没有,MybatisPlus提供了Plugin入口,我们可以自定义BaseMapper来实现。比如,在某些table中有唯一约束键,当insert时如果唯一键冲突会抛错,如果恰好此时我们又不想处理这个错误,那我们希望使用insert ignore into ... 的语法, 但是BaseMapper没有提供这个sql的模板方法,此时需要我们自己去实现.

编写SQL模板

首先我们创建class InsertIgnore,定义方法名称和对应生成SQL的模板,这里我使用kotlin编写,大家可以转成对应的java classkotlin

代码解读
复制代码
import com.baomidou.mybatisplus.annotation.IdType import com.baomidou.mybatisplus.core.injector.AbstractMethod import com.baomidou.mybatisplus.core.metadata.TableInfo import com.baomidou.mybatisplus.core.metadata.TableInfoHelper import com.baomidou.mybatisplus.core.toolkit.StringPool import com.baomidou.mybatisplus.core.toolkit.StringUtils import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator import org.apache.ibatis.executor.keygen.KeyGenerator import org.apache.ibatis.executor.keygen.NoKeyGenerator import org.apache.ibatis.mapping.MappedStatement /** * 实现insert ignore into sql模板 */ class InsertIgnore : AbstractMethod() { companion object { const val METHOD_NAME = "insertIgnore" const val SQL_TEMPLATE = """ <script> INSERT IGNORE INTO %s %s VALUES %s </script> """ } override fun injectMappedStatement( mapperClass: Class<*>?, modelClass: Class<*>?, tableInfo: TableInfo? ): MappedStatement { var keyGenerator: KeyGenerator = NoKeyGenerator() val columnScript = SqlScriptUtils.convertTrim( tableInfo!!.allInsertSqlColumnMaybeIf, StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET, null, StringPool.COMMA ) val valuesScript = SqlScriptUtils.convertTrim( tableInfo.getAllInsertSqlPropertyMaybeIf(null), StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET, null, StringPool.COMMA ) var keyProperty: String? = null var keyColumn: String? = null // 表包含主键处理逻辑,如果不包含主键当普通字段处理 if (StringUtils.isNotBlank(tableInfo.keyProperty)) { if (tableInfo.idType == IdType.AUTO) { /** 自增主键 */ keyGenerator = Jdbc3KeyGenerator() keyProperty = tableInfo.keyProperty keyColumn = tableInfo.keyColumn } else { if (null != tableInfo.keySequence) { keyGenerator = TableInfoHelper.genKeyGenerator(METHOD_NAME, tableInfo, builderAssistant) keyProperty = tableInfo.keyProperty keyColumn = tableInfo.keyColumn } } } val sql = String.format(SQL_TEMPLATE, tableInfo.tableName, columnScript, valuesScript) val sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass) return addInsertMappedStatement( mapperClass, modelClass, METHOD_NAME, sqlSource, keyGenerator, keyProperty, keyColumn ) } }

自定义Mapper

在自定义Mapper接口中添加insertIgnore方法kotlin

代码解读
复制代码
import com.baomidou.mybatisplus.core.mapper.BaseMapper interface UltraBaseMapper<T> : BaseMapper<T> { /** * 插入一条数据,如果插入报错(比如唯一约束冲突) 则忽略 */ fun insertIgnore(entity: T): Int }

业务Mapper原来需要继承BaseMapper,改为继承UltraBaseMapperkotlin

代码解读
复制代码
interface UserMapper : UltraBaseMapper<User>

这样UserMapper就拥有了insertIgnore方法,此时还缺少一项配置,那就是将我们的InsertIgnore这个class加入到MybatisPlus的插件中

配置插件kotlin

代码解读
复制代码
import com.baomidou.mybatisplus.core.injector.AbstractMethod import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector class UltraSqlInjector : DefaultSqlInjector() { override fun getMethodList(mapperClass: Class<*>?): MutableList<AbstractMethod> { val methodList = super.getMethodList(mapperClass) methodList.add(InsertIgnore()) return methodList } }

Spring配置kotlin

代码解读
复制代码
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @Configuration class MybatisPlusConfig { @Bean fun ultraSqlInjector(): UltraSqlInjector { return UltraSqlInjector() } }

总结

可以通过继承mybatis-plus提供的AbstractMethod来实现自定义SQL模板,比如本文中的示例InsertIgnore,我还实现了InsertBatchInsertIgnoreBatchSelectByIdForUpdate

转载来源:https://juejin.cn/post/7364698043911454731

Apipost 私有化火热进行中

评论