MybatisPlus怎么拓展自定义BaseMapper

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: 通过扩展Mybatis-Plus的`BaseMapper`,可以自定义SQL模板以满足特定业务需求。例如,当遇到唯一键冲突而不希望抛出异常时,可使用`INSERT IGNORE`语法。首先,创建`InsertIgnore`类继承`AbstractMethod`并定义`insertIgnore`方法及其SQL模板。接着,在自定义的`UltraBaseMapper`接口中声明`insertIgnore`方法,并让业务Mapper继承此接口。最后,通过`UltraSqlInjector`类将`InsertIgnore`方法注册到Mybatis-Plus插件中。

前言

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

编写SQL模板

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

kotlin

代码解读

复制代码

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,改为继承UltraBaseMapper

kotlin

代码解读

复制代码

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

相关文章
|
5月前
|
SQL Java 数据库连接
|
5月前
|
SQL Java 数据库连接
mybatis常见分页技术和自定义分页原理实战
mybatis常见分页技术和自定义分页原理实战
202 0
|
5月前
|
SQL XML Java
Mybatis Plus自定义全局SQL注入
Mybatis Plus自定义全局SQL注入
175 0
|
3月前
|
SQL Java 数据库连接
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
74 3
|
3月前
|
Java 数据库连接 Maven
文本,使用SpringBoot工程创建一个Mybatis-plus项目,Mybatis-plus在编写数据层接口,用extends BaseMapper<User>继承实体类
文本,使用SpringBoot工程创建一个Mybatis-plus项目,Mybatis-plus在编写数据层接口,用extends BaseMapper<User>继承实体类
|
3月前
|
SQL
自定义SQL,可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,如何自定义SQL呢?利用MyBatisPlus的Wrapper来构建Wh,在mapper方法参数中用Param注
自定义SQL,可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,如何自定义SQL呢?利用MyBatisPlus的Wrapper来构建Wh,在mapper方法参数中用Param注
|
5月前
|
SQL Oracle 关系型数据库
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
整合Mybatis-Plus高级,Oracle 主键Sequence,Sql 注入器实现自定义全局操作
132 0
|
5月前
|
SQL 数据库
在mybatis-plus怎么使用自定义的sql语句
在mybatis-plus怎么使用自定义的sql语句
437 0
|
4月前
|
Java 数据库连接 数据库
MyBatis TypeHandler详解:原理与自定义实践
MyBatis TypeHandler详解:原理与自定义实践
|
4月前
|
Java 数据库连接 mybatis
mybatis自定义插件实现日期自动注入
mybatis自定义插件实现日期自动注入
174 0