1. 程式人生 > >mybatise自定義外掛或者叫mybatise攔截器,動態修改sql語句

mybatise自定義外掛或者叫mybatise攔截器,動態修改sql語句

package com.teamsun.net.common.utils;


import java.lang.reflect.Constructor;
import java.util.Properties;


import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.MappedStatement.Builder;
import org.apache.ibatis.mapping.SqlSource;
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.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor;
import com.github.miemiedev.mybatis.paginator.dialect.Dialect;
import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
import com.github.miemiedev.mybatis.paginator.support.PropertiesHelper;


@Intercepts({ @Signature(type = Executor.class, method = "query", args = {
MappedStatement.class, Object.class, RowBounds.class,
ResultHandler.class }) })
public class MyBatisePlugin implements Interceptor {
private static Logger logger = LoggerFactory
.getLogger(OffsetLimitInterceptor.class);
static int MAPPED_STATEMENT_INDEX = 0;// 這是對應上面的args的序號
static int PARAMETER_INDEX = 1;
static int ROWBOUNDS_INDEX = 2;
static int RESULT_HANDLER_INDEX = 3;
String dialectClass;// 在mybatise-config的配製屬性,可多個


@Override
public Object intercept(Invocation invocation) throws Throwable {
final Executor executor = (Executor) invocation.getTarget();
final Object[] queryArgs = invocation.getArgs();
final MappedStatement ms = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX];
final Object parameter = queryArgs[PARAMETER_INDEX];
final RowBounds rowBounds = (RowBounds) queryArgs[ROWBOUNDS_INDEX];
final PageBounds pageBounds = new PageBounds(rowBounds);


final Dialect dialect;
try {
Class clazz = Class.forName(dialectClass);// 這是在mybatise-config裡配製,就是設定你選用了哪種資料庫,mysql
// or oracle
Constructor constructor = clazz.getConstructor(
MappedStatement.class, Object.class, PageBounds.class);
dialect = (Dialect) constructor.newInstance(new Object[] { ms,
parameter, pageBounds });
} catch (Exception e) {
throw new ClassNotFoundException("Cannot create dialect instance: "
+ dialectClass, e);
}
final BoundSql boundSql = ms.getBoundSql(parameter);// 獲得查詢語句對像
GlobalUser globalUser = GlobalUser.getGlobalUser();// 獲得執行緒中的全域性使用者資訊
if (globalUser != null) {
System.out.println("user:_______"
+ globalUser.getUser().getUserid());
String sql = boundSql.getSql();// 獲得查詢語句
System.out.println("orginsql_________________:" + sql);
sql = sql + " where userid='" + globalUser.getUser().getUserid()
+ "'";// 改變查詢語句
BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), sql,
boundSql.getParameterMappings(),
boundSql.getParameterObject());// 重新new一個查詢語句對像
MappedStatement newMs = copyFromMappedStatement(ms,
new BoundSqlSqlSource(newBoundSql));// 把新的查詢放到statement裡
queryArgs[MAPPED_STATEMENT_INDEX] = newMs;
}
String methonName = invocation.getMethod().getName();
System.out.println("methodName__________:" + methonName);
return invocation.proceed();
}


@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);// 這些莫認呼叫
}


@Override
public void setProperties(Properties properties) {
// TODO Auto-generated method stub
PropertiesHelper propertiesHelper = new PropertiesHelper(properties);
String dialectClass = propertiesHelper
.getRequiredString("dialectClass");
setDialectClass(dialectClass);// 這個方法主要就是獲得mybatis-config裡的配製
// 比如:<!-- <plugin
// interceptor="com.teamsun.net.common.utils.MyBatisePlugin">
// <property name="dialectClass"
// value="com.github.miemiedev.mybatis.paginator.dialect.OracleDialect"
// />
// </plugin> -->
// 上面是在mybatise-config的配製
}


public void setDialectClass(String dialectClass) {
logger.debug("dialectClass: {} ", dialectClass);
this.dialectClass = dialectClass;
}


private MappedStatement copyFromMappedStatement(MappedStatement ms,
SqlSource newSqlSource) {
Builder builder = new MappedStatement.Builder(ms.getConfiguration(),
ms.getId(), newSqlSource, ms.getSqlCommandType());


builder.resource(ms.getResource());
builder.fetchSize(ms.getFetchSize());
builder.statementType(ms.getStatementType());
builder.keyGenerator(ms.getKeyGenerator());
if (ms.getKeyProperties() != null && ms.getKeyProperties().length > 0) {
builder.keyProperty(ms.getKeyProperties()[0]);
}
// setStatementTimeout()
builder.timeout(ms.getTimeout());


// setStatementResultMap()
builder.parameterMap(ms.getParameterMap());


// setStatementResultMap()
builder.resultMaps(ms.getResultMaps());
builder.resultSetType(ms.getResultSetType());


// setStatementCache()
builder.cache(ms.getCache());
builder.flushCacheRequired(ms.isFlushCacheRequired());
builder.useCache(ms.isUseCache());


return builder.build();
}


public static class BoundSqlSqlSource implements SqlSource {


private BoundSql boundSql;


public BoundSqlSqlSource(BoundSql boundSql) {
this.boundSql = boundSql;
}


public BoundSql getBoundSql(Object parameterObject) {
return boundSql;
}
}


}

我這裡主要是修改了 intercept,我的目的是動態修改查詢語句,寫好這個後,在mybatise-config裡配一下就可以,類似paginator的分頁外掛,配製如下:

<!-- 分頁外掛 -->
<plugins>
<plugin
interceptor="com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor">
<property name="dialectClass"
value="com.github.miemiedev.mybatis.paginator.dialect.OracleDialect" />
</plugin>
<!-- <plugin
interceptor="com.teamsun.net.common.utils.MyBatisePlugin">
<property name="dialectClass"
value="com.github.miemiedev.mybatis.paginator.dialect.OracleDialect" />
</plugin> -->
</plugins>

注意這個plugins不是隨便義,要放到typeAliases後面,mappers節點前面

相關推薦

mybatise定義外掛或者mybatise攔截動態修改sql語句

package com.teamsun.net.common.utils; import java.lang.reflect.Constructor; import java.util.Properties; import org.apache.ibatis.executo

mybatis外掛--(1)--mybatis generator定義外掛或者擴充套件報Cannot instantiate object of type XXX

1、錯誤說明 mybatis generator確實好用,但是離我們的生產程式碼還是有差別的 比如缺少,toString hashCode equals等方法,或者自定一的一些註釋,作者資訊等。 官方文件也說可以自定義外掛,但是當我們滿心歡喜的繼承或者實現

SpringBoot整合Mybatis定義攔截實現拼接sql修改

一、應用場景 1.分頁,如com.github.pagehelper的分頁外掛實現; 2.攔截sql做日誌監控; 3.統一對某些sql進行統一條件拼接,類似於分頁。 二、MyBatis的攔截器簡介 然後我們要知道攔截器攔截什麼樣的物件,攔截物件的什麼行為,什麼時候攔截? &n

2017.12.22 定義註解、AOP、攔截

一、自定義註解(AOP切面位置) Annotation:註解 建立Annotation類 [email protected] @Target說明了Annotation所修飾的物件範圍,用@Target更準確地指出修飾的目標。 取值(Eleme

SSH開發 | 配合定義註解 和 Stratus攔截實現 方法級粒度 用戶鑒權

struts OS action gin 所有 具體實現 getmethod red nal 1.提要   本文是 小小商城-SSH版的 細節詳解系列 之一,項目 github:https://github.com/xenv/S-mall-ssh 本文代碼大部分在 gith

SpringVC 攔截+定義註解 實現權限攔截

json.js 加載 bean media tar attr esp 權限 encoding 1.springmvc配置文件中配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://w

vue定義外掛

官網教程 官網連結 開發外掛 外掛通常會為 Vue 新增全域性功能。外掛的範圍沒有限制——一般有下面幾種: 新增全域性方法或者屬性,如: vue-custom-element 新增全域性資源:指令/過濾器/過渡等,如 vue-touch 通過全域性 mixin 方法新增一些元件選

spring boot整合swagger定義註解攔截xss過濾非同步呼叫定時任務案例

本文介紹spring boot整合swagger,自定義註解,攔截器,xss過濾,非同步呼叫,定時任務案例 整合swagger--對於做前後端分離的專案,後端只需要提供介面訪問,swagger提供了介面呼叫測試和各種註釋的視覺化web介面。配置swagger的掃描包路徑,api資訊等,見配置類Swagger

Cordova與現有框架的結合Cordova外掛使用教程Cordova定義外掛框架整合Cordova將Cordova整合到現有框架中

 一、框架整合cordova 將cordova整合到現有框架中 一般cordova工程是通過CMD命令來建立一個工程並新增Android、ios等平臺,這樣的建立方式可以完整的下載開發過程中所需要的的外掛。也是最方便和快捷一種方式。因此我們需要用這種方式將我們現有的框架放入到已建好的cordov

TarsGo新版本釋出支援protobufzipkin和定義外掛

本文作者:陳明傑(sandyskies) Tars是騰訊從2008年到今天一直在使用的後臺邏輯層的統一應用框架,目前支援C++,Java,PHP,Nodejs,Golang語言。該框架為使用者提供了涉及到開發、運維、以及測試的一整套解決方案,幫助一個產品或者服務快速開發、部署、測試、上線。 它集可擴充套件協

springboot-監聽器過濾器攔截aop,定義註解

springboot基礎-監聽器,過濾器,攔截器,aop,自定義註解 文章目錄 springboot基礎-監聽器,過濾器,攔截器,aop,自定義註解 1.監聽器 2.過濾器 3.攔截器 4.aop 5.自定義註解

定義flume的攔截提取body中的時間作為header

package com.springboot.MongoDB.flume; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.

Adams 2013定義外掛方法zz

1.Adams外掛介紹 Adams的高階模組(如Controls控制模組、Vibration振動模組、Durability耐久性模組等)是以外掛的形式整合在Adams軟體中。通過Adams提供的外掛管理器(Plugin Manager)工具能非常方便地對這些外掛進行管理,即插即用,

maven定義外掛

建立一個Maven專案,具體怎麼建立略。 將pom.xml檔案的packaging 改為maven-plugin <packaging>maven-plugin</packaging> pom.xml中引入外掛依賴 <

給Android開發者的Ionic定義外掛

首先需要把Ionic的環境搭好,這裡我就不廢話了,相信看到這篇文章的各位都已經是使用過Ionic的人了 直接上教程 1.建立外掛 通過命令列建立外掛  格式:plugman create --name <pluginName> --plugin_id &l

springboot 定義interceptor 對請求進行攔截

自定義interceptor package com.zhk.demo.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web

okhttp新增定義攔截封裝公共請求引數

okhttp 進行網路請求 /** * date:2018/11/22 * author:QMY(QMY) * function: */ public class OkhttpUtils { Handler handler; OkHttpClient o

VS Code python定義或者函式Import後無自動補全提示

用VS code寫python,標準模組自動補全都沒有問題,在用自定義的module,import後怎麼都沒有補全提示。 最後採用替換掉Microsoft python analysis engine,採用了Jedi as intellisense engine。設定如下: 在setting

Gradle 實現定義外掛

一、以庫專案形式建立外掛 1.建立專案 如果僅僅是自己專案中來自定義外掛,不對外發布,那麼可以按照以下的語法來構建目錄 1.1  建立一個Module,選擇Java Library專案,專案名稱必須是 buildSrc,否則外掛不被識別 1.2 構建目錄 buildSrc/sr

vue-cli 3.x 定義外掛併發布到 npm

乾貨轉載——https://www.cnblogs.com/wisewrong/archive/2018/12/28/10186611.html 全是知識點吶 趕緊記下來啊 一、調整專案結構 首先用 vue-cli 建立一個 default 專案 // 順便安利一篇文章《Vue 爬坑之路(十二)——