13.平凡之路-MyBatis拦截器 上卷

夜晚,寂寞,冷
夜晚,寂寞,冷

概述

拦截器:我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法。
Mybatis拦截器:就是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

   Executor (update, query, flushStatements, commit, rollback, 
    getTransaction, close, isClosed)
   ParameterHandler (getParameterObject, setParameters)
   ResultSetHandler (handleResultSets, handleOutputParameters)
*   StatementHandler (prepare, parameterize, batch, update, query)

Mybatis 提供的Interceptor接口

对于拦截器Mybatis为我们提供了一个Interceptor接口,通过实现该接口就可以定义我们自己的拦截器。我们先来看一下这个接口的定义:

public interface Interceptor { 
    Object intercept(Invocation invocation) throws Throwable;
    Object plugin(Object target); 
    void setProperties(Properties properties); 
}

Interceptor接口提供三个方法:

  • plugin方法是拦截器用于封装目标对象的,通过该方法我们可以返回目标对象本身,也可以返回一个它的代理。
  • 当返回的是代理的时候我们可以对其中的方法进行拦截来调用intercept方法,当然也可以调用其他方法,这点将在后文讲解。
  • setProperties方法是用于在Mybatis配置文件中指定一些属性的。
  • 定义自己的Interceptor最重要的是要实现plugin方法和intercept方法,在plugin方法中我们可以决定是否要进行拦截进而决定要返回一个什么样的目标对象。而intercept方法就是要进行拦截的时候要执行的方法。

不想介绍的太多,实践出真理

自定义插件

需求设计

把Mybatis所有执行的sql都记录下来。

代码实现

通过对 MyBatis org.apache.ibatis.executor.statement.StatementHandler 中的prepare 方法进行拦截即可。
自定义一个类,实现 org.apache.ibatis.pluginInterceptor 接口,代码如下:

package com.shxt.interceptor;

import java.sql.Connection;
import java.util.Properties;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.log4j.Logger;


@Intercepts(@Signature(type=StatementHandler.class,method="prepare",args={Connection.class, Integer.class}))
public class SQLStatsInterceptor implements Interceptor {
    private final Logger logger = Logger.getLogger(this.getClass());
    @Override
    public Object intercept( Invocation invocation ) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = statementHandler.getBoundSql();
        String sql = boundSql.getSql();
        this.logger.info("mybatis intercept sql:" + sql);
        return invocation.proceed();
    }

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

    @Override
    public void setProperties( Properties properties ) {
        String dialect = properties.getProperty("dialect");
        this.logger.info("mybatis intercept dialect:"+ dialect);

    }

}

这样一个插件就开发完成了,接下来需要在 mybatis-config.xml 文件中增加 plugins节点,完整配置如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE configuration

  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

  "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

    <!-- 加载属性文件 -->

    <properties resource="jdbc.properties"/>

    

    <plugins>

        <plugin interceptor="com.shxt.interceptor.SQLStatsInterceptor">

            <property name="dialect" value="mysql" />

        </plugin>

    </plugins>

    

    <!-- 配置数据库的环境 -->

    <environments default="development">

        <environment id="development">

            <!-- 事务管理器:保证数据的完整性和一致性 -->

            <!-- 框架:默认情况下CUD操作需要手动提交事务 -->

            <transactionManager type="JDBC" />

            <!-- 使用的是连接池:百度Java如何实行连接池的原理? -->

            <dataSource type="POOLED">

                <property name="driver" value="${jdbc.mysql.driver}" />

                <property name="url" value="${jdbc.mysql.url}" />

                <property name="username" value="${jdbc.mysql.username}" />

                <property name="password" value="${jdbc.mysql.password}" />

            </dataSource>

        </environment>

    </environments>

    

    <!-- 加载映射文件 -->

    <mappers>

        <mapper resource="com/shxt/model/SkillMapper.xml"/>

    </mappers>

</configuration>

配置Log4J属性文件

在这里我参考了网上的一些资料

# Global logging configuration
log4j.rootLogger=info,stdout,database
# MyBatis logging configuration...
# 如果显示SQL语句,那么这个位置需要配置为命名空间
# log4j.logger.com.shxt.model.Skill=TRACE
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

### 把日志信息写入到数据库### 
log4j.appender.database=org.apache.log4j.ConsoleAppender  
log4j.appender.database.layout=org.apache.log4j.PatternLayout  
log4j.appender.database.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss:SSS}[%p]: %m%n  
  
log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.database.driver=com.mysql.jdbc.Driver
log4j.appender.database.URL=jdbc:mysql://127.0.0.1:3306/cy42_mss?useUnicode=true&characterEncoding=UTF-8
log4j.appender.database.user=root
log4j.appender.database.password=shxt
log4j.appender.database.sql=INSERT INTO log (class,method,createtime,loglevel,msg) VALUES ('%C','%M','%d{yyyy-MM-dd hh:mm:ss}','%p','%m')
log4j.appender.database.layout=org.apache.log4j.PatternLayout

计划是后面讲解一下MyBatis的分页拦截器

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 1.需求背景 设定订单表order,要根据订单类型统计订单数据,大致sql如下: Mybatis无法将以上sql以...
    48892085f47c阅读 7,214评论 0 2
  • MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能。那么拦截器拦截MyBati...
    七寸知架构阅读 3,241评论 3 54
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,282评论 0 4
  • 共享单车市场,在遭遇了早期摩拜的腿废、押金高等痛点后我选择了ofo,经历了一段蜜月期后立马觉得不是那么回事,满大街...
    克拉钻阅读 331评论 0 0
  • 生活只有苟且,没有诗和远方。 车子在这条歪歪斜斜的山间小路颠簸半小时了,不到十公里的距离。清晨的露水还未褪去,我放...
    Sim丶陌弦阅读 4,109评论 0 5