Mybatis-Plus:Sql 注⼊器⾃动填充功能逻辑删除

Posted 丿涛哥哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis-Plus:Sql 注⼊器⾃动填充功能逻辑删除相关的知识,希望对你有一定的参考价值。

1、Sql 注⼊器

在MP中,通过AbstractSqlInjector将BaseMapper中的⽅法注⼊到了Mybatis容器,这样这些⽅法才可以正常执⾏。

那么,如果我们需要扩充BaseMapper中的⽅法,⼜该如何实现呢?

下⾯以扩展findAll⽅法为例进⾏演示。

1.1、编写MyBaseMapper

/**
 * 通用mapper接口,以后创建其他mapper接口时,不再继承BaseMapper,而是继承MyBaseMapper
 * @param <T>
 */
public interface MyBaseMapper<T> extends BaseMapper<T> 
    /*
        查询所有用户
     */
    public List<User> findAll();

其他的Mapper都可以继承该Mapper,这样实现了统⼀的扩展。

如:

public interface UserMapper extends MyBaseMapper<User> 

    /*
        自定义findById方法
     */
    public User findById(Long id);


1.2、编写mysqlInjector

如果直接继承AbstractSqlInjector的话,原有的BaseMapper中的⽅法将失效,所以选择继承 DefaultSqlInjector进⾏扩展。

/**
 * 自定义Ssl注入器
 */
public class MySqlInjector extends DefaultSqlInjector 
    @Override
    public List<AbstractMethod> getMethodList() 
        List<AbstractMethod> methodList = super.getMethodList();
        //扩充自定义方法
        methodList.add(new FindAll());
        return methodList;
    


1.3、编写FindAll

public class FindAll extends AbstractMethod 
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) 
        String sql = "select * from " + tableInfo.getTableName();
        SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
        return this.addSelectMappedStatement(mapperClass, "findAll", sqlSource, modelClass, tableInfo);
    


1.4、注册到Spring容器

/*
    自定义sql注入器
 */
@Bean
public MySqlInjector mySqlInjector()
    return new MySqlInjector();


1.5、测试

/*
    自定义sql注入器测试
 */
@Test
public void testFindAll()
    List<User> all = userMapper.findAll();
    for (User user : all) 
        System.out.println(user);
    

输出的SQL:

Time:10 ms - ID:com.tao.mapper.UserMapper.findAll
Execute SQL:
    select
        * 
    from
        user

2、⾃动填充功能

有些时候我们可能会有这样的需求,插⼊或者更新数据时,希望有些字段可以⾃动填充数据,⽐如密码、version 等。在MP中提供了这样的功能,可以实现⾃动填充。

2.1、添加@TableField注解

@TableField(fill = FieldFill.INSERT) //插⼊数据时进⾏填充
private String version;

为 version 添加⾃动填充功能,在新增数据时有效。

FieldFill提供了多种模式选择:

public enum FieldFill 
 /**
 * 默认不处理
 */
 DEFAULT,
 /**
 * 插⼊时填充字段
 */
 INSERT,
 /**
 * 更新时填充字段
 */
 UPDATE,
 /**
 * 插⼊和更新时填充字段
 */
 INSERT_UPDATE


2.2、编写MyMetaObjectHandler

@Component
public class MyMetaObjectHandler implements MetaObjectHandler 
    @Override
    public void insertFill(MetaObject metaObject) 
        Object version = getFieldValByName("version", metaObject);
        if (null == version)
            //该属性为空,可以进行填充
            setFieldValByName("version",1,metaObject);
        
    

    @Override
    public void updateFill(MetaObject metaObject) 

    


2.3、测试

@Test
public void testInsert()
    User user = new User();
    user.setName("小七333");
    user.setAge("18");
    user.setMail("xiaoqi@163.com");

    //返回值是数据库中影响的行数
    int result = userMapper.insert(user);
    System.out.println(result);
    System.out.println("id值为:" + user.getId());


打印sql:

Time:15 ms - ID:com.tao.mapper.UserMapper.insert
Execute SQL:
    INSERT 
    INTO
        user
        ( name, age, email, version ) 
    VALUES
        ( '小七333', '18', 'xiaoqi@163.com', 1 )

结果:


3、逻辑删除

开发系统时,有时候在实现功能时,删除操作需要实现逻辑删除,所谓逻辑删除就是将数据标记为删除,⽽并⾮真正的物理删除(⾮DELETE操作),查询时需要携带状态条件,确保被标记的数据不被查询到。这样做的⽬的就是避免数据被真正的删除。

MP提供了这样的功能,⽅便我们使⽤:

3.1、修改表结构

为user表增加deleted字段,⽤于表示数据是否被删除,1代表删除,0代表未删除。

ALTER TABLE `user`
ADD COLUMN `deleted` int(1) NULL DEFAULT 0 COMMENT '1代表删除,0代表未删除' AFTER `version`;

同时,也修改User实体,增加deleted属性并且添加@TableLogic注解:

@TableLogic
private Integer deleted;

3.2、配置

application.properties:

# 逻辑已删除值(默认为 1)
mybatis-plus.global-config.db-config.logic-delete-value=1
# 逻辑未删除值(默认为 0)
mybatis-plus.global-config.db-config.logic-not-delete-value=0

3.3、测试

@Test
public void testDeleteById()
    int i = userMapper.deleteById(6L);
    System.out.println(i);

执⾏的SQL:

Time:4 ms - ID:com.tao.mapper.UserMapper.deleteById
Execute SQL:
    UPDATE
        user 
    SET
        deleted=1 
    WHERE
        id=6 
        AND deleted=0

测试查询:

@Test
public void testSelectById()
    User user = userMapper.selectById(6L);
    System.out.println(user);

执⾏的SQL:

Time:6 ms - ID:com.tao.mapper.UserMapper.selectById
Execute SQL:
    SELECT
        id,
        name,
        age,
        email AS mail,
        version,
        deleted 
    FROM
        user 
    WHERE
        id=6 
        AND deleted=0

null

可⻅,已经实现了逻辑删除。

以上是关于Mybatis-Plus:Sql 注⼊器⾃动填充功能逻辑删除的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis-Plus:Sql 注⼊器⾃动填充功能逻辑删除

Mybatis-Plus:Sql 注入器(扩展BaseMapper)

MyBatis-Plus 使用这么方便,底层是如何处理的呢?

MyBatis-Plus - 一篇带你解决自定义 SQL 注入器失效必杀技

MyBatis-Plus 3.0.3 Sql注入器添加,即全局配置Sql注入器,sqlInjector改写

Mybatis-plus 自定义SQL注入器查询@TableLogic 逻辑删除后的数据