精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

換種方式,打印 MyBatis 執行 SQL 語句!

數據庫 其他數據庫
你是否有在使用 IntelliJ IDEA 做開發的過程,需要拿到執行 SQL 語句,復制出來做驗證的時候,總是這樣的語句:SELECT * FROM USER WHERE id = ? AND name = ? 又需要自己把 ? 號 替換成入參值呢?

一、前言

片面了!

一月三舟,托爾斯泰說:“多么偉大的作家,也不過就是在書寫自己的片面而已”。何況是我,何況是我們!

雖然我們不書寫文章,但我們寫需求、寫代碼、寫注釋,當我們遇到了需要被討論的問題點時,往往變成了爭論點。這個好、那個差、你用的都是啥啥啥!

當你把路走窄了,你所能接受到的新的思路、新的想法、新的視野,以及非常重要的收入,也都會隨之減少。只有橫向對比、參考借鑒、查漏補缺,才能讓你的頭腦中會有更多的思路,無論是在寫代碼上、還是在理財上、還是在生活上。

二、需求目的

你是否有在使用 IntelliJ IDEA 做開發的過程,需要拿到執行 SQL 語句,復制出來做驗證的時候,總是這樣的語句:SELECT * FROM USER WHERE id = ? AND name = ? 又需要自己把 ? 號 替換成入參值呢?

當然這個需求其實并不大,甚至你還可以使用其他方式解決。那么在本章節會給你提供一個新的思路,可能你幾乎是沒過的方式進行處理。

那么在這個章節的案例中我們用到基于 IDEA Plugin 開發能力,把字節碼插樁探針,基于 Javaagent 的能力,注入到代碼中。再通過增強后的字節碼,獲取到 com.mysql.jdbc.PreparedStatement -> executeInternal 執行時的對象,從而拿到可以直接測試的 SQL 語句。

三、案例開發

1. 工程結構

guide-idea-plugin-probe
├── .gradle
├── probe-agent
│ ├── src
│ │ └── main
│ │ └── java
│ │ └── cn.bugstack.guide.idea.plugin
│ │ ├── MonitorMethod.java
│ │ └── PreAgent.java
│ └── build.gradle
└── probe-plugin
│ └── src
│ │ └── main
│ │ ├── java
│ │ │ └── cn.bugstack.guide.idea.plugin
│ │ │ └── utils
│ │ │ │ └── PluginUtil.java
│ │ │ └── PerRun.java
│ │ └── resources
│ │ └── META-INF
│ │ └── plugin.xml
│ └── build.gradle
├── build.gradle
└── gradle.properties

公眾號:bugstack蟲洞棧 回復:idea 即可下載全部 IDEA 插件開發源碼

在此 IDEA 插件工程中,工程結構分為2塊:

  • probe-agent:探針模塊,用于編譯打包提供字節碼增強服務,給 probe-plugin 模塊使用
  • probe-plugin:插件模塊,通過 java.programPatcher加載字節碼增強包,獲取并打印執行數據庫操作的 SQL 語句。

2. 字節碼增強獲取 SQL

此處的字節碼增強方式,采用的 Byte-Buddy 字節碼框架,它的使用方式更加簡單,在使用的過程中有些像使用 AOP 的攔截方式一樣,獲取到你需要的信息。

此外在 gradle 打包構建的時候,需要添加 shadowJar 模塊,把 Premain-Class 打包進去。這部分代碼中可以查看

2.1 探針入口

cn.bugstack.guide.idea.plugin.PreAgent

//JVM 首先嘗試在代理類上調用以下方法
public static void premain(String agentArgs, Instrumentation inst){
AgentBuilder.Transformer transformer = (builder, typeDescription, classLoader, javaModule) -> {
return builder
.method(ElementMatchers.named("executeInternal")) // 攔截任意方法
.intercept(MethodDelegation.to(MonitorMethod.class)); // 委托
};
new AgentBuilder
.Default()
.type(ElementMatchers.nameStartsWith("com.mysql.jdbc.PreparedStatement"))
.transform(transformer)
.installOn(inst);
}
  • 通過 Byte-buddy 配置,攔截匹配的類和方法,因為這個類和方法下,可以獲取到完整的執行 SQL 語句。

2.2 攔截 SQL

cn.bugstack.guide.idea.plugin.MonitorMethod

@RuntimeType
public static Object intercept(@This Object obj, @Origin Method method, @SuperCall Callable<?> callable, @AllArguments Object... args) throws Exception {
try {
return callable.call();
} finally {
String originalSql = (String) BeanUtil.getFieldValue(obj, "originalSql");
String replaceSql = ReflectUtil.invoke(obj, "asSql");
System.out.println("數據庫名稱:Mysql");
System.out.println("線程ID:" + Thread.currentThread().getId());
System.out.println("時間:" + new Date());
System.out.println("原始SQL:\r\n" + originalSql);
System.out.println("替換SQL:\r\n" + replaceSql);
}
}
  • 攔截方法入參是一種可配置操作,比如 @This Object obj是為了獲取當前類的執行對象,@Origin Method method是為了獲取執行方法。
  • 在 finally 塊中,我們可以通過反射拿到當前類的屬性信息,以及反射拿到執行的 SQL,并做打印輸出。

2.3 編譯打包

在測試和開發 IDEA Plugin 插件之前,我們需要先進行一個打包操作,這個打包就是把字節碼增強的代碼打包整一個 Jar 包。在 build.gradle -> shadowJar

  • 打包編譯后,就可以在 build -> libs 下看到 Jar:probe-agent-1.0-SNAPSHOT-all.jar這個 Jar 就是用來做字節碼增強處理的。

2.4 測試驗證

這里在把寫好的字節碼增強組件給插件使用之前,可以做一個測試驗證,避免每次都需要啟動插件才能做測試。

單元測試

public class ApiTest {

public static void main(String[] args) throws Exception {

String URL = "jdbc:mysql://127.0.0.1:3306/itstack?characterEncoding=utf-8";
String USER = "root";
String PASSWORD = "123456";
Class.forName("com.mysql.jdbc.Driver");

Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
String sql="SELECT * FROM USER WHERE id = ? AND name = ?";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setLong(1,1L);
statement.setString(2,"謝飛機");
ResultSet rs = statement.executeQuery();

while (rs.next()) {
System.out.println(rs.getString("name") + " " + rs.getString("address"));
}

}

}
  • VM options:-javaagent:你的路徑\libs\probe-agent-1.0-SNAPSHOT-all.jar
  • 注意在測試運行的時候,你要給 ApiTest 配置 VM options 才能打印攔截 SQL 信息

測試結果

原始SQL:
SELECT * FROM USER WHERE id = ? AND name = ?
替換SQL:
SELECT * FROM USER WHERE id = 1 AND name = '謝飛機'
謝飛機 北京.大興區.通明湖公園
  • 好啦,這樣我們就可以攔截可以復制執行的 SQL 語句了,接下來我們再做下 IDEA Plugin 的處理。

3. 通過插件開發引入探針 Jar

接下來我們要把開發好的字節碼增強 Jar 包,復制到 IDEA Plugin 插件開發模塊中的 libs(可自己創建) 下,之后在 plugin.xml 配置加載 implementation fileTree(dir: 'libs', includes: ['*jar']) 這樣就可以程序中,找到這個 jar 包并配置到程序中。

3.1 復制 jar 到 libs 下

3.2 build.gradle 配置加載

dependencies {
implementation fileTree(dir: 'libs', includes: ['*jar'])
}
  • 通過 implementation fileTree引入加載文件樹的方式,把我們配置好的 Jar 加載到程序運行中。

3.3 程序中引入 javaagent

cn.bugstack.guide.idea.plugin.PerRun

public class PerRun extends JavaProgramPatcher {

@Override
public void patchJavaParameters(Executor executor, RunProfile configuration, JavaParameters javaParameters){

RunConfiguration runConfiguration = (RunConfiguration) configuration;
ParametersList vmParametersList = javaParameters.getVMParametersList();
vmParametersList.addParametersString("-javaagent:" + agentCoreJarPath);
vmParametersList.addNotEmptyProperty("guide-idea-plugin-probe.projectId", runConfiguration.getProject().getLocationHash());

}

}
  • 通過繼承 JavaProgramPatcher類,實現patchJavaParameters方法,通過 configuration 屬性來配置我們自己需要被加載的-javaagent包。
  • 這樣在通過 IDEA 已經安裝此插件,運行代碼的時候,就會執行到這個攔截和打印 SQL 的功能。

3.4 plugin.xml 添加配置

<extensions defaultExtensionNs="com.intellij">
<!-- Add your extensions here -->
<java.programPatcher implementation="cn.bugstack.guide.idea.plugin.PerRun"/>
</extensions>
  • 之后你還需要把開發好的加載類,配置到 java.programPatcher這樣就可以程序運行的時候,被加載到了。

四、測試驗證

  • 準備好一個有數據庫操作的工程,需要的是 JDBC,如果是其他的,你需要自己擴展
  • 啟動插件后,打開你的工程,運行單元測試,查看打印區

啟動插件

  • 如果你是新下載代碼,那么可以在 probe-plugin -> Tasks -> intellij -> runIde 中進行運行啟動。

單元測試

@Test
public void test_update(){
User user = new User();
user.setId(1L);
user.setName("謝飛機");
user.setAge(18);
user.setAddress("北京.大興區.亦莊經濟開發區");
userDao.update(user);
}

測試結果

22:30:55.593 [main] DEBUG cn.bugstack.test.demo.infrastructure.dao.UserDao.update[143] - ==>  Preparing: UPDATE user SET name=?,age=?,address=? WHERE id=? 
22:30:55.625 [main] DEBUG cn.bugstack.test.demo.infrastructure.dao.UserDao.update[143] - ==> Parameters: 謝飛機(String), 18(Integer), 北京.大興區.亦莊經濟開發區(String), 1(Long)
數據庫名稱:Mysql
線程ID:1
原始SQL:
UPDATE user SET name=?,age=?,address=?
WHERE id=?
替換SQL:
UPDATE user SET name='謝飛機',age=18,address='北京.大興區.亦莊經濟開發區'
WHERE id=1
  • 通過測試結果可以看到,我們可以獲取到直接拿去測試驗證的 SQL 語句了,就不用在復制帶問號的 SQL 還得修改后測試了。

五、總結

  • 首先我們是在本章節初步嘗試使用多模塊的方式來創建工程,這樣的方式可以更加好維護各類一個工程下所需要的代碼模塊。你也可以嘗試使用 gradle 創建多模塊工程
  • 對于字節碼插樁增強的使用方式,本篇只是一個介紹,這項技術還可以運用到更多的場景,開發出各種提升研發效率的工具。
  • 了解額外的 Jar 包是怎么加載到工程的,以及如何通過配置的方式讓 javaagent引入自己開發好的探針組件。
責任編輯:武曉燕 來源: 今日頭條
相關推薦

2024-02-04 09:24:45

MyBatisSQL語句Spring

2010-11-12 11:48:15

2010-11-24 08:54:33

2010-11-04 09:43:46

LINQ to SQL

2018-04-28 15:51:33

Mybatis方式傳遞

2010-09-25 14:38:29

SQL分頁

2010-09-03 14:47:50

SQLSELECT語句

2010-09-25 14:59:54

SQL語句

2024-12-26 08:16:26

2010-04-29 14:06:40

Oracle SQL

2021-07-28 07:22:40

SQL順序Hive

2010-09-25 16:21:41

SQL語句

2019-11-06 09:30:35

SQL查詢語句數據庫

2010-09-27 10:55:01

SQL事件探查器

2010-10-21 16:24:18

sql server升

2022-10-18 10:41:44

Flowable服務任務

2024-01-17 13:56:00

Redis節點映射關系

2022-10-28 11:04:24

Python映射容器

2011-07-21 13:44:52

MySQLmysqldumpsl

2022-09-01 16:42:47

MySQL數據庫架構
點贊
收藏

51CTO技術棧公眾號

精品夜夜嗨av一区二区三区| 国产精品久久久网站| 中文欧美字幕免费| 国产一区二区丝袜高跟鞋图片| 亚洲最大的黄色网址| 6080亚洲理论片在线观看| 国产精品日韩久久久| 亚洲精品在线看| jizz18女人| 四虎影院在线播放| 91tv精品福利国产在线观看| 日韩欧美国产精品一区| 日日碰狠狠添天天爽超碰97| 国产经典自拍视频在线观看| 激情五月激情综合网| 97国产在线视频| 中文字幕第69页| 国产精品调教视频| 欧美视频在线一区二区三区| 久久综合久久久久| av大片在线看| 99精品国产视频| 欧美久久久精品| 天堂久久久久久| 色999韩欧美国产综合俺来也| 亚洲一区二区三区在线看| 午夜精品区一区二区三| 国产情侣在线视频| 婷婷综合在线| 亚洲天堂日韩电影| 美女伦理水蜜桃4| 欧美综合影院| 在线看国产日韩| 日本a在线免费观看| 蜜桃视频网站在线| 国产日产欧美精品一区二区三区| 成人精品一二区| 中文字幕一二区| 亚洲影院一区| 欧美精品久久久久a| www.黄色com| 九一精品国产| 日韩av中文字幕在线| 中文字幕1区2区| 在线观看欧美| 在线中文字幕一区| 成人免费观看毛片| av伦理在线| 一区二区三区在线观看视频| 亚洲乱码一区二区三区| 欧美精品少妇| 久久久噜噜噜久噜久久综合| 欧洲亚洲免费视频| 日韩三级免费看| 国产精品啊啊啊| 精品少妇v888av| 午夜精品福利在线视频| 五月婷婷六月综合| 久久久成人精品视频| 亚洲 欧美 国产 另类| 日韩欧美一区二区三区在线视频| 国产亚洲福利一区| av男人的天堂av| 国产精品亚洲二区| 国产亚洲精品激情久久| 亚洲а∨天堂久久精品2021| 精品一区二区三| 中文字幕日韩电影| 老司机深夜福利网站| 99久久www免费| 久久国内精品一国内精品| 91狠狠综合久久久| 亚洲美女视频| 欧美精品videos| 中日韩精品视频在线观看| 亚洲视频成人| 国产精品成人一区二区| 中文字幕 视频一区| 久久66热偷产精品| 操人视频欧美| 天天操天天舔天天干| 老牛国产精品一区的观看方式| 69久久夜色精品国产69| 久久精品视频7| 男女性色大片免费观看一区二区| 成人女保姆的销魂服务| 亚洲精品无码专区| 2024国产精品视频| 热99精品里视频精品| 五月天中文字幕| 国产一区亚洲一区| 日韩免费中文字幕| 97精品人妻一区二区三区香蕉| 国产精品一区二区无线| 精品一区二区日本| 亚洲1卡2卡3卡4卡乱码精品| 亚洲免费观看高清在线观看| 日韩精品大片| 黄色小网站在线观看| 天天亚洲美女在线视频| 一本色道久久亚洲综合精品蜜桃| 日韩欧美久久| 亚洲无限av看| 久久久久久久久久久久国产| 五月天综合网站| 久久成人久久爱| 偷拍亚洲欧洲综合| 免费黄色福利视频| 亚洲精品三区| 亚洲国产一区二区三区在线观看 | 欧美另类在线观看| 国产又爽又黄的视频| 石原莉奈在线亚洲三区| 热门国产精品亚洲第一区在线| 亚洲国产无线乱码在线观看| 国产传媒一区在线| caoporen国产精品| 性开放的欧美大片| 性久久久久久久久久久久| 国产精品久久久久9999小说| 国产一区二区三区| 亚洲免费影视第一页| 天天鲁一鲁摸一摸爽一爽| 国产精品www994| 国产精品日韩电影| 日韩在线视频第一页| 中文字幕免费不卡| 国产在线播放观看| 亚洲欧洲二区| 亚洲国产高潮在线观看| jizz亚洲少妇| 日韩国产成人精品| 国产精品一区视频网站| 午夜在线播放| 精品福利在线视频| 国产国语老龄妇女a片| 93在线视频精品免费观看| 午夜精品www| 999免费视频| 国产日产精品一区| 欧美国产激情视频| 日韩精品视频中文字幕| 在线精品91av| 特级做a爱片免费69| 成人av二区| 97精品国产97久久久久久免费| 一区二区小视频| 久久综合九色综合欧美98 | 久久精品国产99久久| 2019中文字幕在线免费观看| 国产欧美日韩成人| 国产精品久久久久四虎| 日本网站免费在线观看| 小嫩嫩12欧美| 97色在线视频观看| 国产刺激高潮av| 成人午夜av影视| 久久99国产精品一区| 怡红院在线观看| 欧美日韩精品一区二区三区蜜桃| 无套内谢大学处破女www小说| 国产精品久久久久久久免费软件| 99久久99| 午夜羞羞小视频在线观看| 这里只有精品99re| 中国一级片在线观看| 精品一区二区综合| 亚洲国产欧美日韩| 国模大尺度视频一区二区| 深夜福利一区二区| 国产又大又黄又爽| 亚洲天堂a在线| 超碰91在线播放| 国产精品www.| 九色综合日本| 自拍偷拍欧美视频| 亚洲人成网站999久久久综合| 国产精久久久久久| 久久新电视剧免费观看| 久久久久久久久久福利| 精品久久久久久久久久久aⅴ| 国产99久久精品一区二区| 久久精品国产亚洲a∨麻豆| 色综合天天性综合| 艳妇乳肉亭妇荡乳av| 亚洲一区色图| av蓝导航精品导航| 91超碰在线| 亚洲免费视频观看| 久久精品国产亚洲av麻豆蜜芽| 国产精品天天摸av网| 中文字幕欧美视频| 亚洲黄色三级| 欧美视频1区| 日韩大陆av| 欧美日本中文字幕| 成人资源www网在线最新版| 欧美日韩久久久| 美女福利视频在线观看| 97久久超碰国产精品| 欧美伦理片在线看| 好看不卡的中文字幕| 欧美动漫一区二区| 精品久久福利| 亚洲国产欧美一区二区三区久久| 久久免费激情视频| 中文字幕一区二区三区蜜月| 久久人人妻人人人人妻性色av| 日韩电影网1区2区| 国产91在线亚洲| 精品国产91乱码一区二区三区四区| 成人a在线视频| 影音先锋男人资源在线| 中文字幕av一区二区| 欧美一级淫片免费视频魅影视频| 色成人在线视频| 久久久久亚洲av无码专区体验| 久久综合久久99| 国产免费中文字幕| 99在线|亚洲一区二区| 99在线热播| 欧美三级精品| 欧美精品久久久久久久| 在线免费看a| 亚洲变态欧美另类捆绑| 日本熟女一区二区| 国产精品国产三级国产普通话蜜臀 | 日韩中文字幕在线一区| 日本伊人精品一区二区三区介绍| 超碰超碰在线| 在线色欧美三级视频| 亚洲精品中文字幕成人片| 欧美午夜寂寞影院| 欧美一区二区激情视频| 亚洲黄色在线视频| 国产伦理片在线观看| 久久综合给合久久狠狠狠97色69| 手机精品视频在线| 免费高清在线视频一区·| 国产二级片在线观看| 欧美极品一区二区三区| 一区二区三区在线视频看| 蜜桃a∨噜噜一区二区三区| 99视频网站| 麻豆国产一区| 国产精品日日摸夜夜添夜夜av| 日本黄色免费在线| 91成品人片a无限观看| 七七成人影院| 欧美成人免费全部| 久操视频在线播放| 自拍偷拍免费精品| 黄色精品在线观看| 中文字幕欧美日韩精品| av在线电影网| 亚洲色图五月天| 先锋av资源站| 亚洲日本aⅴ片在线观看香蕉| 香蕉视频网站在线| 亚洲国产成人一区| 色婷婷激情五月| 欧美精品一区二区久久久| 日本国产在线观看| 亚洲精品一区在线观看| 日韩一卡二卡在线| 日韩精品极品视频免费观看| 隣の若妻さん波多野结衣| 亚洲精品国产欧美| 欧美日韩影视| 亚洲色图35p| 97视频在线观看网站| 久久精品欧美视频| 2024短剧网剧在线观看| 欧美成人精品激情在线观看 | 中文字幕av一区中文字幕天堂| 搞黄视频免费在线观看| 有码中文亚洲精品| 暖暖日本在线观看| 欧美极品美女视频网站在线观看免费| yellow91字幕网在线| 欧美精品日韩www.p站| 香蕉久久aⅴ一区二区三区| 欧美—级a级欧美特级ar全黄| 高清不卡av| 国产精品吴梦梦| 99视频这里有精品| www.av一区视频| 国产精区一区二区| 久热这里只精品99re8久| 精品福利久久久| 中文字幕在线中文字幕日亚韩一区| 久久精品亚洲人成影院| 最新av在线免费观看| 国产欧美一区二区色老头 | 午夜在线观看免费一区| 日本精品一区二区三区四区| 美腿丝袜亚洲色图| 少妇性l交大片7724com| 97精品电影院| 99在线视频免费| 亚洲一区在线观看免费观看电影高清| 日本熟妇色xxxxx日本免费看| 日本高清不卡在线观看| 一道本在线视频| 亚洲变态欧美另类捆绑| 黄色在线视频网站| 8x海外华人永久免费日韩内陆视频| 桃花岛tv亚洲品质| 7777奇米亚洲综合久久| 成人免费a**址| 免费在线看黄色片| 久久午夜精品一区二区| 亚洲视频在线不卡| 丰满放荡岳乱妇91ww| 国产探花视频在线播放| 亚洲一区电影777| 正在播放亚洲精品| 亚洲成人激情在线| 综合图区亚洲| 日韩av免费在线观看| 6080成人| 亚洲一区二区三区在线观看视频 | 999精品在线| 九一国产精品视频| 国产一区二区三区免费播放| 爱爱免费小视频| 午夜精品福利一区二区三区蜜桃| 影音先锋黄色网址| 亚洲国产高清高潮精品美女| 免费av网站在线观看| 国产成人免费av电影| 精品中文一区| 久久国产精品网| 国产在线国偷精品产拍免费yy| 新91视频在线观看| 五月天中文字幕一区二区| 国产女人18毛片18精品| 一区二区三区国产在线观看| 高清毛片在线观看| 99久热re在线精品996热视频| 日韩中文在线电影| 欧在线一二三四区| 国产aⅴ精品一区二区三区色成熟| 亚洲不卡在线播放| 欧美日韩黄色影视| 黄色片在线看| 国产91露脸中文字幕在线| 香蕉人人精品| 中文字幕无码精品亚洲35| 国产宾馆实践打屁股91| 午夜激情视频在线播放| 欧美精品第1页| av大片在线播放| 国产精品网站入口| 成人午夜国产| 日韩在线一区视频| 国产精品免费aⅴ片在线观看| 一二三区免费视频| 亚洲男人天堂2019| 成人亚洲网站| 亚洲国产精品一区在线观看不卡| 日日夜夜免费精品视频| 国产又粗又猛又爽视频| 欧美日韩你懂得| 麻豆网站在线| 成人久久久久久| 日产精品一区二区| 久久综合在线观看| 亚洲免费在线视频| 午夜精品久久久久久久99热黄桃| 一本久久综合亚洲鲁鲁| 国产一区2区在线观看| 先锋影音亚洲资源| 久久激情一区| 国产又粗又猛又爽又黄av| 欧美性xxxxx极品娇小| av在线日韩国产精品| 成人久久精品视频| 国产中文一区| 国产精品一级黄片| 91精品办公室少妇高潮对白| 成年人在线免费观看| 成人黄色免费片| 性欧美69xoxoxoxo| 国产精品99精品无码视亚| 亚洲va欧美va国产va天堂影院| 天天躁日日躁狠狠躁伊人| 国产精品99久久久久久人 | av网在线播放| 在线精品国精品国产尤物884a| 在线激情免费视频| 91亚洲精品久久久久久久久久久久| 中文字幕一区二区三区在线视频| 无人码人妻一区二区三区免费| 午夜在线成人av| 成人影视在线播放| 91最新国产视频| 久久中文在线| 在线观看亚洲网站| 亚洲电影天堂av|