国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語(yǔ)言|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Mybatis Interceptor 攔截器的實(shí)現(xiàn)

Mybatis Interceptor 攔截器的實(shí)現(xiàn)

2021-06-22 13:32廣訓(xùn) Java教程

這篇文章主要介紹了Mybatis Interceptor 攔截器的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

mybatis采用責(zé)任鏈模式,通過(guò)動(dòng)態(tài)代理組織多個(gè)攔截器(插件),通過(guò)這些攔截器可以改變mybatis的默認(rèn)行為(諸如sql重寫之類的),由于插件會(huì)深入到mybatis的核心,因此在編寫自己的插件前最好了解下它的原理,以便寫出安全高效的插件。

攔截器(interceptor)在 mybatis 中被當(dāng)做插件(plugin)對(duì)待,官方文檔提供了 executor,parameterhandler,resultsethandler,statementhandler 共4種,并且提示“這些類中方法的細(xì)節(jié)可以通過(guò)查看每個(gè)方法的簽名來(lái)發(fā)現(xiàn),或者直接查看 mybatis 發(fā)行包中的源代碼”。

攔截器的使用場(chǎng)景主要是更新數(shù)據(jù)庫(kù)的通用字段,分庫(kù)分表,加解密等的處理。

1. interceptor

攔截器均需要實(shí)現(xiàn)該 org.apache.ibatis.plugin.interceptor 接口。

2. intercepts 攔截器

?
1
2
3
@intercepts({
    @signature(type = executor.class, method = "update", args = {mappedstatement.class, object.class})
})

攔截器的使用需要查看每一個(gè)type所提供的方法參數(shù)。

signature 對(duì)應(yīng) invocation 構(gòu)造器,type 為 invocation.object,method 為 invocation.method,args 為 invocation.object[]。

method 對(duì)應(yīng)的 update 包括了最常用的 insert/update/delete 三種操作,因此 update 本身無(wú)法直接判斷sql為何種執(zhí)行過(guò)程。

args 包含了其余所有的操作信息, 按數(shù)組進(jìn)行存儲(chǔ), 不同的攔截方式有不同的參數(shù)順序, 具體看type接口的方法簽名, 然后根據(jù)簽名解析。

3. object 對(duì)象類型

args 參數(shù)列表中,object.class 是特殊的對(duì)象類型。如果有數(shù)據(jù)庫(kù)統(tǒng)一的實(shí)體 entity 類,即包含表公共字段,比如創(chuàng)建、更新操作對(duì)象和時(shí)間的基類等,在編寫代碼時(shí)盡量依據(jù)該對(duì)象來(lái)操作,會(huì)簡(jiǎn)單很多。該對(duì)象的判斷使用

?
1
2
3
4
object parameter = invocation.getargs()[1];
if (parameter instanceof baseentity) {
  baseentity entity = (baseentity) parameter;
}

即可,根據(jù)語(yǔ)句執(zhí)行類型選擇對(duì)應(yīng)字段的賦值。

如果參數(shù)不是實(shí)體,而且具體的參數(shù),那么 mybatis 也做了一些處理,比如 @param("name") string name 類型的參數(shù),會(huì)被包裝成 map 接口的實(shí)現(xiàn)來(lái)處理,即使是原始的 map 也是如此。使用

?
1
2
3
4
object parameter = invocation.getargs()[1];
if (parameter instanceof map) {
  map map = (map) parameter;
}

即可,對(duì)具體統(tǒng)一的參數(shù)進(jìn)行賦值。

4. sqlcommandtype 命令類型

executor 提供的方法中,update 包含了 新增,修改和刪除類型,無(wú)法直接區(qū)分,需要借助 mappedstatement 類的屬性 sqlcommandtype 來(lái)進(jìn)行判斷,該類包含了所有的操作類型

?
1
2
3
public enum sqlcommandtype {
 unknown, insert, update, delete, select, flush;
}

畢竟新增和修改的場(chǎng)景,有些參數(shù)是有區(qū)別的,比如創(chuàng)建時(shí)間和更新時(shí)間,update 時(shí)是無(wú)需兼顧創(chuàng)建時(shí)間字段的。

?
1
2
mappedstatement ms = (mappedstatement) invocation.getargs()[0];
sqlcommandtype commandtype = ms.getsqlcommandtype();

5. 實(shí)例

自己編寫的小項(xiàng)目中,需要統(tǒng)一給數(shù)據(jù)庫(kù)字段屬性賦值:

?
1
2
3
4
5
6
7
public class baseentity {
  private int id;
  private int creator;
  private int updater;
  private long createtime;
  private long updatetime;
}

dao 操作使用了實(shí)體和參數(shù)的方式,個(gè)人建議還是統(tǒng)一使用實(shí)體比較簡(jiǎn)單,易讀。

使用實(shí)體:

?
1
int add(bookentity entity);

使用參數(shù):

 

復(fù)制代碼 代碼如下:
int update(@param("id") int id, @param("url") string url, @param("description") string description, @param("playcount") int playcount, @param("creator") int creator, @param("updatetime") long updatetime);

 

完整的例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package com.github.zhgxun.talk.common.plugin;
 
import com.github.zhgxun.talk.common.util.dateutil;
import com.github.zhgxun.talk.common.util.userutil;
import com.github.zhgxun.talk.entity.baseentity;
import com.github.zhgxun.talk.entity.userentity;
import lombok.extern.slf4j.slf4j;
import org.apache.ibatis.executor.executor;
import org.apache.ibatis.mapping.mappedstatement;
import org.apache.ibatis.mapping.sqlcommandtype;
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.springframework.stereotype.component;
 
import java.util.map;
import java.util.properties;
 
/**
 * 全局?jǐn)r截?cái)?shù)據(jù)庫(kù)創(chuàng)建和更新
 * <p>
 * signature 對(duì)應(yīng) invocation 構(gòu)造器, type 為 invocation.object, method 為 invocation.method, args 為 invocation.object[]
 * method 對(duì)應(yīng)的 update 包括了最常用的 insert/update/delete 三種操作, 因此 update 本身無(wú)法直接判斷sql為何種執(zhí)行過(guò)程
 * args 包含了其余多有的操作信息, 按數(shù)組進(jìn)行存儲(chǔ), 不同的攔截方式有不同的參數(shù)順序, 具體看type接口的方法簽名, 然后根據(jù)簽名解析, 參見(jiàn)官網(wǎng)
 *
 * @link http://www.mybatis.org/mybatis-3/zh/configuration.html#plugins 插件
 * <p>
 * mappedstatement 包括了sql具體操作類型, 需要通過(guò)該類型判斷當(dāng)前sql執(zhí)行過(guò)程
 */
@component
@intercepts({
    @signature(type = executor.class, method = "update", args = {mappedstatement.class, object.class})
})
@slf4j
public class normalplugin implements interceptor {
 
  @override
  @suppresswarnings("unchecked")
  public object intercept(invocation invocation) throws throwable {
    // 根據(jù)簽名指定的args順序獲取具體的實(shí)現(xiàn)類
    // 1. 獲取mappedstatement實(shí)例, 并獲取當(dāng)前sql命令類型
    mappedstatement ms = (mappedstatement) invocation.getargs()[0];
    sqlcommandtype commandtype = ms.getsqlcommandtype();
 
    // 2. 獲取當(dāng)前正在被操作的類, 有可能是java bean, 也可能是普通的操作對(duì)象, 比如普通的參數(shù)傳遞
    // 普通參數(shù), 即是 @param 包裝或者原始 map 對(duì)象, 普通參數(shù)會(huì)被 mybatis 包裝成 map 對(duì)象
    // 即是 org.apache.ibatis.binding.mappermethod$parammap
    object parameter = invocation.getargs()[1];
    // 獲取攔截器指定的方法類型, 通常需要攔截 update
    string methodname = invocation.getmethod().getname();
    log.info("normalplugin, methodname; {}, commandtype: {}", methodname, commandtype);
 
    // 3. 獲取當(dāng)前用戶信息
    userentity userentity = userutil.getcurrentuser();
    // 默認(rèn)測(cè)試參數(shù)值
    int creator = 2, updater = 3;
 
    if (parameter instanceof baseentity) {
      // 4. 實(shí)體類
      baseentity entity = (baseentity) parameter;
      if (userentity != null) {
        creator = entity.getcreator();
        updater = entity.getupdater();
      }
      if (methodname.equals("update")) {
        if (commandtype.equals(sqlcommandtype.insert)) {
          entity.setcreator(creator);
          entity.setupdater(updater);
          entity.setcreatetime(dateutil.gettimestamp());
          entity.setupdatetime(dateutil.gettimestamp());
        } else if (commandtype.equals(sqlcommandtype.update)) {
          entity.setupdater(updater);
          entity.setupdatetime(dateutil.gettimestamp());
        }
      }
    } else if (parameter instanceof map) {
      // 5. @param 等包裝類
      // 更新時(shí)指定某些字段的最新數(shù)據(jù)值
      if (commandtype.equals(sqlcommandtype.update)) {
        // 遍歷參數(shù)類型, 檢查目標(biāo)參數(shù)值是否存在對(duì)象中, 該方式需要應(yīng)用編寫有一些統(tǒng)一的規(guī)范
        // 否則均統(tǒng)一為實(shí)體對(duì)象, 就免去該重復(fù)操作
        map map = (map) parameter;
        if (map.containskey("creator")) {
          map.put("creator", creator);
        }
        if (map.containskey("updatetime")) {
          map.put("updatetime", dateutil.gettimestamp());
        }
      }
    }
    // 6. 均不是需要被攔截的類型, 不做操作
    return invocation.proceed();
  }
 
  @override
  public object plugin(object target) {
    return plugin.wrap(target, this);
  }
 
  @override
  public void setproperties(properties properties) {
  }
}

6. 感受

其它幾種類型,后面在看,尤其是分頁(yè)。

在編寫代碼的過(guò)程中,有時(shí)候還是需要先知道對(duì)象的類型,比如 object.class 跟 interface 一樣,很多時(shí)候僅僅代表一種數(shù)據(jù)類型,需要明確知道后再進(jìn)行操作。

@param 標(biāo)識(shí)的參數(shù)其實(shí)會(huì)被 mybatis 封裝成 org.apache.ibatis.binding.mappermethod$parammap 類型,一開(kāi)始我就是使用

?
1
2
3
for (field field:parameter.getclass().getdeclaredfields()) {
 
}

的方式獲取,以為這些都是對(duì)象的屬性,通過(guò)反射獲取并修改即可,實(shí)際上發(fā)現(xiàn)對(duì)象不存在這些屬性,但是打印出的信息中,明確有這些字段的,網(wǎng)上參考一些信息后,才知道這是一個(gè) map 類型,問(wèn)題才迎刃而解。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://segmentfault.com/a/1190000017393523

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 我要看a级毛片 | 黄色毛片在线看 | 久久天天 | 亚洲视频在线观看免费 | 九九九久久国产免费 | 欧美日韩免费 | 四虎免费看黄 | 日韩码有限公司在线观看 | 日韩在线观看 | 精品粉嫩超白一线天av | 婷婷久久综合九色综合绿巨人 | 影音在线资源 | 一区二区免费在线观看 | 国产一区二区免费 | 激情五月婷婷 | 99久久婷婷国产精品综合 | 亚洲精品国产剧情久久9191 | 日韩欧美在线综合网 | 黄色av网站在线观看 | 欧美日韩一区二区三区不卡视频 | 日韩欧美视频一区 | 国产精品美女一区 | 日本不卡视频 | 成人黄色网 | 毛片网免费 | 欧美亚洲国产一区二区三区 | 欧美亚洲免费 | 中国a毛片 | 国产伦精品一区二区三区精品视频 | 国产精品第一区 | 日韩成人在线播放 | 91色在线观看 | 午夜av电影| 一区二区精品在线 | 日韩字幕在线 | 亚洲欧美日韩国产 | 免费在线成人网 | 亚洲视频在线观看免费 | 成人激情视频 | 日日爽| 91亚洲国产成人久久精品网站 |