精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

亚洲伦理影院| 日韩中文字幕观看| 欧美电影一区| 日韩精品影音先锋| 99999精品视频| 日本成a人片在线观看| 国产一区不卡在线| 欧美一区二区三区免费观看| 亚洲AV成人无码网站天堂久久| 色播一区二区| 91久久精品日日躁夜夜躁欧美| 超碰免费在线公开| 蜜桃av中文字幕| 美女性感视频久久| 8x拔播拔播x8国产精品| 波兰性xxxxx极品hd| 欧美爱爱网站| 欧美一区二区在线播放| 国产成人久久777777| 伊人影院在线视频| 国产日韩精品一区| 国产精品我不卡| 99riav国产| 日韩av在线免费观看不卡| 九九视频直播综合网| 美女100%露胸无遮挡| 国产成人一二片| 91精品国产综合久久久久久久| 午夜精品久久久久久久无码| а√天堂在线官网| 国产欧美一区二区三区鸳鸯浴 | 亚洲男人的天堂av| 日韩中文字幕一区二区| 亚洲日本中文字幕在线| 国产一区在线观看视频| 国产精品久久久久久久一区探花| 欧美成人aaaaⅴ片在线看| 911久久香蕉国产线看观看| 亚洲天堂免费观看| 北岛玲一区二区| 国产精品任我爽爆在线播放| 91精品国产欧美一区二区18| 成人亚洲精品777777大片| 不卡av播放| 精品久久久中文| 国产乱淫av片杨贵妃| a视频在线播放| 亚洲色图19p| 宅男av一区二区三区| 大胆av不用播放器在线播放| 91麻豆免费观看| 久久综合福利| 蜜桃免费在线| 不卡电影一区二区三区| 国产精品久久久一区二区三区| 99国产精品欲| 国产精品资源网| 亚洲v日韩v综合v精品v| 国产精品视频无码| 国产毛片精品一区| 97se国产在线视频| 亚洲精品久久久久久无码色欲四季| 国产麻豆视频精品| 999视频在线免费观看| 超碰人人人人人人| 成人性视频免费网站| 国产精品综合久久久久久| 人成网站在线观看| 99这里只有久久精品视频| 久久久久国产精品视频| 毛片在线播放网站| 国产精品视频麻豆| 天天干天天色天天爽| 污视频网站在线免费| 亚洲国产精品久久不卡毛片 | 77thz桃花论族在线观看| 亚洲高清中文字幕| 精品一区二区中文字幕| 台湾佬中文娱乐久久久| 欧美久久久久中文字幕| 中文字幕一区二区三区人妻在线视频 | 亚洲精品久久久蜜桃| 中文字幕中文字幕在线中一区高清 | 中文字幕资源网| 精品一二三四区| αv一区二区三区| 亚洲aaaaaaa| 国产欧美一区二区精品仙草咪| 中文字幕一区二区三区乱码| 国产网红在线观看| 在线中文字幕一区二区| 三年中文在线观看免费大全中国| 成人激情自拍| 亚洲无线码在线一区观看| 日本美女黄色一级片| 亚洲国产三级| 国产精品丝袜一区二区三区| wwwxxxx国产| 国产午夜久久久久| 久久天天东北熟女毛茸茸| 欧美13videosex性极品| 欧美日韩国产一区| 少妇一级淫片免费放播放| 欧美日韩一区二区综合 | 青青草成人免费| 香蕉国产精品偷在线观看不卡| 国产美女久久精品香蕉69| 国产综合无码一区二区色蜜蜜| 国产日韩v精品一区二区| 欧美久久久久久久久久久久久久| 姬川优奈av一区二区在线电影| 日韩欧美国产精品一区| 欧美大波大乳巨大乳| 激情综合在线| 成人黄色片在线| 久久99久久| 亚洲国产视频一区二区| www.涩涩涩| 欧美有码在线| 超碰97人人做人人爱少妇| 精品免费囯产一区二区三区| 国产成人在线色| 一区二区不卡视频| 久久影院午夜精品| 日韩精品一区二区三区中文不卡| 亚洲av熟女国产一区二区性色| 亚洲激情另类| 99在线视频免费观看| 暖暖日本在线观看| 在线观看三级视频欧美| 国产白嫩美女无套久久| 韩日成人av| 91久久久久久久久| 18视频免费网址在线观看| 欧美性xxxxx| 国产麻豆xxxvideo实拍| 欧美高清不卡| 91免费视频国产| 日本高清视频在线观看| 在线观看视频一区二区| 欧美丰满美乳xxⅹ高潮www| 免费日韩av| 久久婷婷国产综合尤物精品| 92久久精品| 亚洲高清一区二| 国产精品23p| 成人激情文学综合网| 欧美日韩中文字幕在线播放 | 777亚洲妇女| 亚洲av无一区二区三区| 九一久久久久久| 一区中文字幕在线观看| 亚洲精品成a人ⅴ香蕉片| 中文字幕在线视频日韩| 一二三区中文字幕| 1024成人网色www| 亚洲色图欧美自拍| 欧美在线高清| 国产精品sss| 国产乱码精品一区二三赶尸艳谈| 精品美女被调教视频大全网站| 欧美丰满艳妇bbwbbw| 国产69精品久久99不卡| 亚洲一区二区三区av无码| 久久a爱视频| 日韩av免费一区| a中文在线播放| 欧美日韩成人综合| 欧美日韩中文字幕在线观看 | 国产精品青青草| av日韩电影| 色诱女教师一区二区三区| 97超碰人人模人人人爽人人爱| 亚洲另类中文字| 亚洲av成人片色在线观看高潮| 媚黑女一区二区| 亚洲五月六月| 伊人精品综合| 国产福利精品在线| 国产在线一区二区视频| 精品福利在线导航| 天天干,天天干| 中文字幕亚洲在| 亚洲激情 欧美| 日日摸夜夜添夜夜添亚洲女人| 亚洲欧美国产一区二区| 综合欧美亚洲| 国产91精品最新在线播放| 欧美a在线看| 日韩电视剧在线观看免费网站 | 免费成人av资源网| 国产人妻人伦精品| 天堂资源在线亚洲| 国产精自产拍久久久久久蜜| 欧洲黄色一区| 国产亚洲精品久久久久久| 国产又大又黄的视频| 亚洲va欧美va人人爽| 国产精品久久免费观看| 盗摄精品av一区二区三区| 日本999视频| 伊人影院久久| 一区二区三区欧美成人| 蜜臀av一区| 91色精品视频在线| 少妇视频一区| 欧美激情按摩在线| 日本最新在线视频| 亚洲精品自拍第一页| 99热在线只有精品| 在线视频你懂得一区二区三区| 久久综合激情网| 国产精品看片你懂得| 国产麻豆xxxvideo实拍| 国产精品一区三区| 五月激情婷婷在线| 日韩精品一区第一页| www.日本在线播放| 亚洲有吗中文字幕| 天堂精品视频| 夜色77av精品影院| 国产精品区一区二区三在线播放 | 精品成人佐山爱一区二区| 在线观看国产精品视频| 日韩欧美在线视频| 精品无码久久久久久久| 亚洲视频资源在线| 国产亚洲精品熟女国产成人| av成人动漫在线观看| 乳色吐息在线观看| 国内成人精品2018免费看| 欧美日韩大尺度| 久久精品123| 国产精品裸体瑜伽视频| 欧美日韩日本国产亚洲在线| 国产成人精品免费看在线播放| 成人一区二区| 色狠狠久久av五月综合|| 亚洲天堂日韩在线| 精品视频在线观看| 激情小说亚洲色图| 国产一区免费观看| 国产成人tv| 精品毛片久久久久久| 国产精品超碰| 国产超碰91| 欧美一级全黄| 精品国产综合久久| 性人久久久久| 欧美色图亚洲自拍| 国产探花在线精品一区二区| 欧美日韩在线播放一区二区| 国产99久久精品一区二区300| 免费久久99精品国产自| 久久不见久久见国语| 日本高清不卡一区二区三| 欧洲福利电影| 色女孩综合网| 色天天综合网| 正义之心1992免费观看全集完整版| 色琪琪久久se色| 国产日韩欧美大片| 狠狠久久婷婷| 日韩欧美在线播放视频| 日本在线观看不卡视频| 亚洲天堂av线| 国内精品伊人久久久久av一坑| 宇都宫紫苑在线播放| 成人午夜视频福利| 播金莲一级淫片aaaaaaa| 国产三级精品三级在线专区| 潮喷失禁大喷水aⅴ无码| 亚洲男人都懂的| 日本一区二区欧美| 色综合天天做天天爱| 在线观看国产精品视频| 精品对白一区国产伦| 精彩国产在线| 久久精品小视频| 啊啊啊久久久| 国产精品无av码在线观看| 日韩精品一区国产| 欧美一区二区三区在线播放 | 国产精品久久久久久久久毛片 | 国产精品a久久久久| 成人一区二区免费视频| 奇米影视一区二区三区小说| 亚洲一级片免费观看| 99re成人在线| 国产91在线播放九色| 亚洲国产精品影院| 天天射天天干天天| 日韩一区二区三区视频在线| 日韩精品系列| 久久综合88中文色鬼| 欧美gv在线| 成人黄色生活片| 图片婷婷一区| 好吊色视频988gao在线观看| 久久国产欧美| 亚洲性图第一页| 中文欧美字幕免费| 日本熟女一区二区| 欧美美女一区二区三区| 三级av在线播放| 欧美精品在线看| 久久精品黄色| 久久久综合香蕉尹人综合网| 亚洲字幕久久| 日韩一区二区三区久久| 久久综合网色—综合色88| 欧美日韩三级在线观看| 欧美性大战久久| 香蕉av一区二区三区| 欧美成人精品在线播放| 精品欧美日韩精品| 久久99蜜桃综合影院免费观看| 综合激情视频| 九九精品久久久| 久久久精品国产免费观看同学| 妺妺窝人体色www聚色窝仙踪 | 婷婷丁香综合| 国产精品69页| 91丝袜美腿高跟国产极品老师| 青青草原免费观看| 欧美电影一区二区三区| 3p视频在线观看| 国产精品久久久久91| 欧美性生活一级片| 国产真人做爰毛片视频直播 | 欧美吻胸吃奶大尺度电影 | 国产精品人人妻人人爽人人牛| 成人综合婷婷国产精品久久 | 欧美精品hd| 国产精品久久久久久久久久新婚| 亚洲美女久久| avav在线看| 国产亚洲美州欧州综合国| 天堂а√在线中文在线新版| 日韩精品高清视频| 擼擼色在线看观看免费| 国内精品久久久久久久果冻传媒| 黑人一区二区| 成人性生活免费看| 精品久久在线播放| 四虎精品在线| 欧洲亚洲妇女av| 精品国产一区二区三区四区| 国产美女三级视频| 久久久久久久综合日本| 一级片视频在线观看| 亚洲人成伊人成综合网久久久 | 日本少妇高潮喷水xxxxxxx| 欧美日在线观看| 黑人与亚洲人色ⅹvideos| 国产成人一区二区三区电影| 久久99国内| 欧美三级午夜理伦三级富婆| 国产精品久久久久久妇女6080| 国产又粗又黄又爽| 欧美日本高清视频| 亚洲精品黑牛一区二区三区| 国产av国片精品| 91在线你懂得| 波多野结衣视频在线观看| 中文欧美日本在线资源| 999色成人| 国产欧美日韩小视频| 久久综合狠狠综合久久综合88| 国产一级片av| 日韩视频在线免费| 亚洲视频国产精品| 色综合av综合无码综合网站| 国产蜜臀97一区二区三区| 国产又粗又大又黄| 国产69精品久久久| 曰本一区二区三区视频| 日本在线一二三区| 一区二区三区在线免费观看| 日本xxxxxwwwww| 国产精品福利在线观看网址| 女人天堂亚洲aⅴ在线观看| 中文字幕无码人妻少妇免费| 欧美在线制服丝袜| 在线看三级电影| 麻豆成人av| 国产又黄又大久久| 影音先锋亚洲天堂| 日韩在线观看免费av| 国产亚洲精品美女久久| 亚洲免费av一区二区三区| 亚洲黄一区二区三区| 日本精品专区| 92看片淫黄大片欧美看国产片| aa亚洲婷婷| 国产第一页浮力| 亚洲美女自拍视频| 视频一区视频二区欧美| 久久久久国产精品熟女影院| 亚洲精品va在线观看|