Mybatis自定义拦截器

需求背景:

在插入数据时需要提前设置 ID 和创建时间, 在更新时设置修改时间.

实现:

定义 Mybatis 拦截器只需要实现 Interceptor 类, 并通过注解设置需要拦截的对象即可:

type=>mybatis 的四大对象:[ParameterHandler],[ResultSetHandler],[StatementHandler],[Executor].

method => 四大对象中需要拦截的方法, 具体可以直接看源码. 例如 Executor 类的 update 方法就经常用到.

args=> 拦截方法所需要的参数, 如果不清楚的话也可以直接看源码. 例如 update 方法需要 MappedStatement 类型和 Object 类型的两个参数.

intercept(Invocation invocation)=> 此方法内写具体的拦截逻辑.

plugin()=> 没什么特殊要求的话直接写成如下形式即可, 意思是把定义的插件注册进插件链里面 (越晚注册越先执行).

@Override
public Object plugin(Object target) {
    return Plugin.wrap(target, this);
}

setProperties(Properties properties)=> 对属性进行配置.
详细代码如下:

import com.eric.site.core.utils.SnowflakeIdWorker;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.Properties;

/**
 * @author Eric
 */
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class PrepareInterceptor implements Interceptor {

    private Logger log = LoggerFactory.getLogger(PrepareInterceptor.class);

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        //注解中method的值
        String methodName = invocation.getMethod().getName();
        //sql类型
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        if ("update".equals(methodName)) {
            Object object = invocation.getArgs()[1];
            Date currentDate = new Date(System.currentTimeMillis());
            //对有要求的字段填值
            if (SqlCommandType.INSERT.equals(sqlCommandType)) {
                Field fieldId = object.getClass().getDeclaredField("id");
                fieldId.setAccessible(true);
                long id = snowflakeIdWorker.nextId();
                fieldId.set(object, id);
                log.info("插入操作前设置id:{}", id);
                Field fieldCreateTime = object.getClass().getDeclaredField("createTime");
                fieldCreateTime.setAccessible(true);
                fieldCreateTime.set(object, currentDate);
                log.info("插入操作时设置create_time:{}", currentDate);
            } else if (SqlCommandType.UPDATE.equals(sqlCommandType)) {
                Field fieldModifyTime = object.getClass().getDeclaredField("modifyTime");
                fieldModifyTime.setAccessible(true);
                fieldModifyTime.set(object, currentDate);
                log.info("更新操作时设置modify_time:{}", currentDate);
            }
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }
}

配置

如果是配置文件的话, 在文件中的标签中追加如下内容:

<plugins>
  <plugin interceptor="自定义插件类"></plugin>
</plugins>

如果是 springboot 的话则如下配置:

import com.eric.site.config.druid.DruidConfiguration;
import com.eric.site.config.mybatis.interceptors.PrepareInterceptor;
import com.github.pagehelper.PageHelper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

/**
 * mybatis的配置:<br/>
 * <p>在配置plugin时,定义的越靠后则越先执行.<p/>
 *
 * @Author: Eric
 */
@Configuration
@MapperScan("com.eric.site.web.dao")
@AutoConfigureAfter(DruidConfiguration.class)
public class MybatisConfiguration {

    /**
     * 分页插件
     */
    @Bean
    public PageHelper pageHelper() {
        PageHelper pageHelper = new PageHelper();
        Properties p = new Properties();
        p.setProperty("offsetAsPageNum", "true");
        p.setProperty("rowBoundsWithCount", "true");
        p.setProperty("reasonable", "true");
        pageHelper.setProperties(p);
        return pageHelper;
    }

    /**
     * 前置拦截器,主要功能是插入前设置ID和create_time,更新时设置modify_time
     */
    @Bean
    public PrepareInterceptor idInterceptor() {
        return new PrepareInterceptor();
    }
}

这样就简单的实现了自定义拦截器.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值