Data Access 之 MyBatis Plus(五)- 自定义 BaseMapper

简介: Data Access 之 MyBatis Plus(五)- 自定义 BaseMapper

一、自定义通用方法TeslaDeleteAll

MyBatis Plus支持自定义通用方法,自定义通用方法与MP自带的通用方法一样,都会在应用启动时将方法注入到全局中

自定义通用方法的步骤:

  1. 在XxxMapper中定义想要自定义的通用方法,XxxMapper要继承BaseMapper
  2. 创建一个类继承AbstractMethod,重写injectMappedStatement()方法,该方法中输入写自定义通用方法的SQL语句
  3. 创建一个XxxInjector类继承DefaultInjector,重写getMethodList()方法,该方法中将包含了自定义SQL语句的类的实例化对象添加到methodList中
  4. 在配置文件中通过bean标签配置自定义的XxxInjector,并在全局配置中通过属性sqlInjector引入

自定义 BaseMappper

1. 在TeslaMapper中定义deleteAll()方法

public interface TeslaMapper extends BaseMapper<Tesla> {
    int deleteAll();
}
复制代码

2. 创建TeslaDeleteAll类,继承AbstractMethod类,定义SQL语句

public class TeslaDeleteAll extends AbstractMethod {
    // 将deleteAll()处理成对应的MappedStatement对象,加入到configuration对象中
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        /* 执行 SQL ,动态 SQL 参考类 SqlMethod */
        String sql = "delete from " + tableInfo.getTableName();
        /* mapper 接口方法名一致 */
        String method = "deleteAll";
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return this.addDeleteMappedStatement(mapperClass, method, sqlSource);
    }
}
复制代码

3. 创建一个TeslaSqlInjector类,继承DefaultSqlInjector类

public class TeslaSqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
         List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
         methodList.add(new TeslaDeleteAll());
         return methodList;
    }
}
复制代码

4. 在全局配置文件中配置TeslaSqlInjector

<!--将DB配置注入全局配置-->
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
    <property name="dbConfig" ref="dbConfig"/> <!--  非必须  -->
    <!--配置自定义注入器-->
    <property name="sqlInjector" ref="teslaSqlInjector"></property>
</bean>
<!--&lt;!&ndash;定义自定义的注入器&ndash;&gt;-->
<bean id="teslaSqlInjector" class="com.lilith.injector.TeslaSqlInjector"></bean>
复制代码

5. 测试自定义通用方法

在TeslaMapperTest中增加testTeslaDeleteAll()方法

@Test
public void testTeslaDelteAll(){
    teslaMapper.deleteAll();
}
复制代码

image.png

自定义的通用方法生效

可以参考 MyBatis Plus 示例项目

二、MP逻辑删除注入器的使用

逻辑删除既假删除,并不是真正的从数据库中删除,而是将当前被删除的这条数据中的一个逻辑删除字段改为删除状态。

首先在t_tesla表增加logic_flag字段,并设置所有记录的logic_flag值为0,表示未删除;接着在Tesla实体类中增加logicFlag属性以及响应的getter/setter方法,并该字段属性上增加@TableLogic注解

在配置文件中配置逻辑删除字段、逻辑已删除值、逻辑未删除值

<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig">
    <!--全局配置主键策略,AUTO或者索引0-->
    <property name="idType" value="AUTO"></property>
    <!--配置统一表名前缀-->
    <property name="tablePrefix" value="t_" />
    <property name="logicDeleteField" value="logic_flag" />
    <!--逻辑已删除值-->
    <property name="logicDeleteValue" value="1" />
    <!--逻辑未删除值-->
    <property name="logicNotDeleteValue" value="0" />
</bean>
复制代码

在TeslaMapperTest中增加逻辑删除的测试方法

@Test
public void testLoginDelete(){
    int count = teslaMapper.deleteById(1166057520);
    System.out.println(count);
}
复制代码

执行测试

image.png

虽然执行的方法是删除方法,但实际执行的是UPDATE方法,将逻辑删除字段从0 改为 1,再次增加一个测试方法,查询已经逻辑删除的数据

@Test
public void testSelectByIdWithLogicDelete(){
    Tesla tesla = teslaMapper.selectById(1166057520);
    System.out.println("查询到的已经被逻辑删除的数据为:" + tesla);
}
复制代码

image.png

查询已经被逻辑删除的字段的查询结果为空,执行查询时带上逻辑删除字段作为查询条件,但仅限于BaseMapper中自带的方法

关于逻辑删除的使用也可以参考MP官网的 逻辑删除

三、MP 自动填充功能

在进行插入或者修改操作的时候,有些字段没有提供值的情况下,希望能有默认值进行填充,实现元对象处理器接口是com.baomidou.mybatisplus.core.handlers.MetaObjectHandler,该接口可以实现公共字段自动写入

metaObject:元对象,是MyBatis提供的一个用于更加方便优雅的访问对象的属性,给对象的属性设置一个对象,还可用于包装对象,支持Object、Map、Collection对象进行包装,本质上metaObject获取对象的属性值或者是给对象的属性设置值,最终是要通过Reflector获取到属性的对应方法的invoker,通过放射获取对象

实现公共字段自动填充步骤

1. 在Tesla实体类上给需要进行自动填充的属性增加@TableField注解

@TableField(fill = FieldFill.INSERT_UPDATE)
private String factory;
复制代码

FieldFill是一个枚举类,共有四种枚举值

image.png

起始就是设置删除或者更新时进行自动填充或者默认或者删除和更新时都进行自动填充

2. 自定义公共字段填充处理器

自定义的公共字段填充器需要实现MetaObjectHandler接口,并实现两个方法,既执行INSERT和UPDATE是自动填充的字段和字段值

public class TeslaMetaObjectHandler implements MetaObjectHandler {
    // 插入操作自动填充
    @Override
    public void insertFill(MetaObject metaObject) {
        // 获取需要被填充的字段的值
        Object fieldVal = getFieldValByName("factory", metaObject);
        if (fieldVal == null){
            setFieldValByName("name", "柏林特斯拉超级工厂", metaObject);
        }
    }
    // 更新操作自定填充
    @Override
    public void updateFill(MetaObject metaObject) {
        // 获取需要被填充的字段的值
        Object fieldVal = getFieldValByName("factory", metaObject);
        if (fieldVal == null){
            setFieldValByName("name", "弗拉蒙特特斯拉超级工厂", metaObject);
        }
    }
}
复制代码

3. 全局注入自定义的公共字段填充处理器

将自定义的字段填充器加入到容器中,并添加到全局配置中

<!--将DB配置注入全局配置-->
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
    <property name="dbConfig" ref="dbConfig"/> <!--  非必须  -->
    <!--配置自定义注入器-->
    <property name="sqlInjector" ref="teslaSqlInjector"></property>
    <property name="metaObjectHandler" ref="teslaMetaObjectHandler"></property>
</bean>
<bean id="teslaMetaObjectHandler" class="com.lilith.meta.TeslaMetaObjectHandler">
</bean>
复制代码

4. 测试自定义公共字段填充器

@Test
public void testInsertByTeslaAutoFillHandler(){
    Tesla tesla = new Tesla();
    tesla.setLogicFlag(0);
    teslaMapper.insert(tesla);
}
复制代码

image.png

在没有设置factory字段的情况下执行插入时自动填充factory字段的值为柏林特斯拉超级工厂

@Test
public void testUpdateByTeslaAutoFillHandler(){
    Tesla tesla = new Tesla();
    tesla.setId(1166057539);
    tesla.setName("Roadster 2022");
    tesla.setPrice(1300000.00);
    teslaMapper.updateById(tesla);
}
复制代码

image.png

在没有设置factory字段值进行更新时,也会为factory自定填充值

@Test
public void testInsertByTeslaAutoFillHandlerWithValue(){
    Tesla tesla = new Tesla();
    tesla.setLogicFlag(0);
    tesla.setFactory("得克萨斯州特斯拉超级工厂");
    teslaMapper.insert(tesla);
}
复制代码

image.png

factory字段有值的情况下,使用给定的值

对于添加了@TableFiled注解的属性,使用MP通用方法更新时如果保持属性不变,也需要对属性的Value进行set操作,否则会设置成自动填充处理器中的值

也可以参考MP 官网的 自动填充功能

至此,MyBatis Plus 完结✿✿ヽ(°▽°)ノ✿


相关文章
|
3月前
|
SQL XML Java
8、Mybatis-Plus 分页插件、自定义分页
这篇文章介绍了Mybatis-Plus的分页功能,包括如何配置分页插件、使用Mybatis-Plus提供的Page对象进行分页查询,以及如何在XML中自定义分页SQL。文章通过具体的代码示例和测试结果,展示了分页插件的使用和自定义分页的方法。
8、Mybatis-Plus 分页插件、自定义分页
|
3月前
|
SQL Java 测试技术
3、Mybatis-Plus 自定义sql语句
这篇文章介绍了如何在Mybatis-Plus框架中使用自定义SQL语句进行数据库操作。内容包括文档结构、编写mapper文件、mapper.xml文件的解释说明、在mapper接口中定义方法、在mapper.xml文件中实现接口方法的SQL语句,以及如何在单元测试中测试自定义的SQL语句,并展示了测试结果。
3、Mybatis-Plus 自定义sql语句
|
3月前
|
SQL Java Kotlin
MybatisPlus怎么拓展自定义BaseMapper
通过扩展Mybatis-Plus的`BaseMapper`,可以自定义SQL模板以满足特定业务需求。例如,当遇到唯一键冲突而不希望抛出异常时,可使用`INSERT IGNORE`语法。首先,创建`InsertIgnore`类继承`AbstractMethod`并定义`insertIgnore`方法及其SQL模板。接着,在自定义的`UltraBaseMapper`接口中声明`insertIgnore`方法,并让业务Mapper继承此接口。最后,通过`UltraSqlInjector`类将`InsertIgnore`方法注册到Mybatis-Plus插件中。
149 1
|
16天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
4月前
|
SQL Java 数据库连接
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
91 3
|
4月前
|
Java 数据库连接 数据库
mybatis plus 中增删改查及Wrapper的使用
mybatis plus 中增删改查及Wrapper的使用
215 3
|
4月前
|
算法 Java 数据库连接
mybatis plus 主键策略
mybatis plus 主键策略
56 2
|
1月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
110 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
1月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
54 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
1月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
311 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个