mybatis攔截器的使用方式(輸出日志或sql語(yǔ)句)
攔截器的一個(gè)作用
是我們可以攔截某些方法的調(diào)用,我們可以選擇在這些被攔截的方法執(zhí)行前后加上某些邏輯,也可以在執(zhí)行這些被攔截的方法時(shí)執(zhí)行自己的邏輯而不再執(zhí)行被攔截的方法。
Mybatis攔截器設(shè)計(jì)的一個(gè)初衷就是為了供用戶在某些時(shí)候可以實(shí)現(xiàn)自己的邏輯而不必去動(dòng)Mybatis固有的邏輯。mybatis攔截器一般用于分頁(yè)插件、輸出日志、sql等。
使用的方法
首先要實(shí)現(xiàn)mybatis的Interceptor接口,
實(shí)現(xiàn)它的三個(gè)方法:
Object intercept(Invocation invocation) throws Throwable; Object plugin(Object target); void setProperties(Properties properties);
plugin方法是攔截器用于封裝目標(biāo)對(duì)象的,通過(guò)該方法我們可以返回目標(biāo)對(duì)象本身,也可以返回一個(gè)它的代理。
當(dāng)返回的是代理的時(shí)候我們可以對(duì)其中的方法進(jìn)行攔截來(lái)調(diào)用intercept方法,當(dāng)然也可以調(diào)用其他方法,這點(diǎn)將在后文講解。
setProperties方法是用于在Mybatis配置文件中指定一些屬性的。plugin方法中我們可以決定是否要進(jìn)行攔截進(jìn)而決定要返回一個(gè)什么樣的目標(biāo)對(duì)象。而intercept方法就是要進(jìn)行攔截的時(shí)候要執(zhí)行的方法。
下面例子本來(lái)相用于記錄日志到數(shù)據(jù)庫(kù)
但是由于mybatis底層無(wú)法注入spring的對(duì)象,所以,只能用于輸出日志。
@Intercepts({@Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class})})
public class LogInterceptor implements Interceptor {
/**
* 注解攔截接口的方法
* Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
* ParameterHandler (getParameterObject, setParameters)
* ResultSetHandler (handleResultSets, handleOutputParameters)
* StatementHandler (prepare, parameterize, batch, update, query)
*/
private static final Logger LOGGER = LoggerFactory.getLogger(LogInterceptor.class);
private Properties properties;
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
// 獲取執(zhí)行的方法
if (args.length > 1) {
// 傳入的對(duì)象
Object obj = args[1];
if (obj instanceof Log) {
// 若是日志對(duì)象 則直接跳過(guò)
return invocation.proceed();
}
saveLog(args[0], obj);
}
return invocation.proceed();
}
private void saveLog(Object arg, Object obj) {
Log log = new Log();
log.setCreateTime(DateUtils.now());
log.setModifyTime(DateUtils.now());
MappedStatement mappedStatement = (MappedStatement) arg;
// 執(zhí)行的方法名
String name = mappedStatement.getSqlCommandType().name();
String change = JsonMapper.toJson(obj);
if (name.startsWith("INSERT")) {
log.setType("新增" + obj.getClass().getSimpleName());
log.setNewContent(change);
} else if (name.startsWith("UPDATE")) {
log.setType("修改" + obj.getClass().getSimpleName());
log.setNewContent(change);
} else if (name.startsWith("DELETE")) {
log.setType("刪除" + obj.getClass().getSimpleName());
log.setOldContent(change);
}
LOGGER.info("----------------------------------------------");
LOGGER.info(JsonMapper.toJson(log));
LOGGER.info("----------------------------------------------");
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}類上面必須添加@Intercepts注解
@Signature,代表攔截點(diǎn),
@Intercepts({@Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class})})method表示需要攔截的方法
mybatis有update, query, flushStatements, commit, rollback, getTransaction, close, isClosed等方法,其中,update包括新增、修改、刪除等方法,query用于查詢,其它的基本用不到。
type表示攔截的接口類型,有Executor、StatementHandler、ParameterHandler和ResultSetHandler。args表示攔截的參數(shù)類型,有MappedStatement、Object、RowBounds和ResultHandler等等.
編寫完攔截器
需要在配置文件中注冊(cè)攔截器,在sqlMapConfig配置文件中加上
<?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>
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
</settings>
<plugins>
<plugin interceptor="com.tc.itfarm.commons.interceptor.LogInterceptor"></plugin>
</plugins>
</configuration>啟動(dòng)項(xiàng)目測(cè)試即可
輸出的日志如下:
2016-08-28 14:48:02 [ http-apr-8888-exec-8:70630 ] - [ INFO ] ----------------------------------------------
2016-08-28 14:48:02 [ http-apr-8888-exec-8:70634 ] - [ INFO ] {"recordId":null,"type":"修改User","oldContent":null,"newContent":"{\"recordId\":1,\"username\":\"wdd\",\"telephone\":\"18888888888\",\"sex\":2,\"password\":null,\"age\":22,\"status\":1,\"address\":\"安徽靈璧1\",\"photo\":null,\"email\":\"asdds\",\"qq\":\"812908087\",\"nickname\":\"愛吃貓的魚1\",\"registerTime\":null,\"modifyTime\":1472366881824}","userId":null,"username":null,"createTime":1472366881824,"modifyTime":1472366881824}
2016-08-28 14:48:02 [ http-apr-8888-exec-8:70634 ] - [ INFO ] ----------------------------------------------
若要插入到數(shù)據(jù)庫(kù),必須new一個(gè)dao對(duì)象操作
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Mybatis Plus 3.4.0分頁(yè)攔截器的用法小結(jié)
- MyBatis攔截器如何自動(dòng)設(shè)置創(chuàng)建時(shí)間和修改時(shí)間
- Mybatis攔截器如何實(shí)現(xiàn)數(shù)據(jù)權(quán)限過(guò)濾
- mybatis 攔截器添加參數(shù)的實(shí)現(xiàn)
- Mybatis自定義攔截器實(shí)現(xiàn)權(quán)限功能
- Mybatis攔截器實(shí)現(xiàn)公共字段填充的示例代碼
- Spring Boot集成MyBatis-Plus 自定義攔截器實(shí)現(xiàn)動(dòng)態(tài)表名切換功能
相關(guān)文章
JAVA求兩直線交點(diǎn)和三角形內(nèi)外心的方法
本文提供了JAVA求兩直線交點(diǎn)、三角形外心、三角形內(nèi)心的代碼和算法講解,大家可以參考使用2013-11-11
淺談java 增強(qiáng)型的for循環(huán) for each
下面小編就為大家?guī)?lái)一篇淺談java 增強(qiáng)型的for循環(huán) for each。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10
Java中的字符流FileReader與FileWriter詳解
這篇文章主要介紹了Java中的字符流FileReader與FileWriter詳解,在Java中,使用Unicode約定存儲(chǔ)字符,字符流自動(dòng)允許我們逐字符讀/寫數(shù)據(jù),有助于執(zhí)行16位Unicode的輸入和輸出,它是以reader和writer結(jié)尾的,需要的朋友可以參考下2023-10-10
java實(shí)現(xiàn)區(qū)域內(nèi)屏幕截圖示例
這篇文章主要介紹了java截圖示例,需要的朋友可以參考下2014-04-04
java 各種數(shù)據(jù)類型的互相轉(zhuǎn)換實(shí)例代碼
這篇文章主要介紹了java 各種數(shù)據(jù)類型的互相轉(zhuǎn)換實(shí)例代碼,需要的朋友可以參考下2020-10-10
Java多線程并發(fā)編程 Volatile關(guān)鍵字
volatile 關(guān)鍵字是一個(gè)神秘的關(guān)鍵字,也許在 J2EE 上的 JAVA 程序員會(huì)了解多一點(diǎn),但在 Android 上的 JAVA 程序員大多不了解這個(gè)關(guān)鍵字。只要稍了解不當(dāng)就好容易導(dǎo)致一些并發(fā)上的錯(cuò)誤發(fā)生,例如好多人把 volatile 理解成變量的鎖2017-05-05
java設(shè)計(jì)模式之代理模式(Porxy)詳解
這篇文章主要為大家詳細(xì)介紹了java設(shè)計(jì)模式之代理模式Porxy的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
Java中成員方法與成員變量訪問(wèn)權(quán)限詳解
在Java學(xué)習(xí)過(guò)程中,在寫類經(jīng)常為用到public,private和protected,我個(gè)人的經(jīng)驗(yàn)是一般類的成員變量都是用private,方法用public,類的內(nèi)部用protected方法,如果是存在子類的,那我就會(huì)把父類中的成員變量變?yōu)閜rotected。(其余的看具體實(shí)際情 況而定)2015-08-08

