片面了!
我们提供的服务有:做网站、网站建设、微信公众号开发、网站优化、网站认证、行唐ssl等。为上1000+企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的行唐网站制作公司
一月三舟,托尔斯泰说:“多么伟大的作家,也不过就是在书写自己的片面而已”。何况是我,何况是我们!
虽然我们不书写文章,但我们写需求、写代码、写注释,当我们遇到了需要被讨论的问题点时,往往变成了争论点。这个好、那个差、你用的都是啥啥啥!
当你把路走窄了,你所能接受到的新的思路、新的想法、新的视野,以及非常重要的收入,也都会随之减少。只有横向对比、参考借鉴、查漏补缺,才能让你的头脑中会有更多的思路,无论是在写代码上、还是在理财上、还是在生活上。
你是否有在使用 IntelliJ IDEA 做开发的过程,需要拿到执行 SQL 语句,复制出来做验证的时候,总是这样的语句:SELECT * FROM USER WHERE id = ? AND name = ? 又需要自己把 ? 号 替换成入参值呢?
当然这个需求其实并不大,甚至你还可以使用其他方式解决。那么在本章节会给你提供一个新的思路,可能你几乎是没过的方式进行处理。
那么在这个章节的案例中我们用到基于 IDEA Plugin 开发能力,把字节码插桩探针,基于 Javaagent 的能力,注入到代码中。再通过增强后的字节码,获取到 com.mysql.jdbc.PreparedStatement -> executeInternal 执行时的对象,从而拿到可以直接测试的 SQL 语句。
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块:
此处的字节码增强方式,采用的 Byte-Buddy 字节码框架,它的使用方式更加简单,在使用的过程中有些像使用 AOP 的拦截方式一样,获取到你需要的信息。
此外在 gradle 打包构建的时候,需要添加 shadowJar 模块,把 Premain-Class 打包进去。这部分代码中可以查看
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);
}
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);
}
}
在测试和开发 IDEA Plugin 插件之前,我们需要先进行一个打包操作,这个打包就是把字节码增强的代码打包整一个 Jar 包。在 build.gradle -> shadowJar
这里在把写好的字节码增强组件给插件使用之前,可以做一个测试验证,避免每次都需要启动插件才能做测试。
单元测试
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"));
}
}
}
测试结果
原始SQL:
SELECT * FROM USER WHERE id = ? AND name = ?
替换SQL:
SELECT * FROM USER WHERE id = 1 AND name = '谢飞机'
谢飞机 北京.大兴区.通明湖公园
接下来我们要把开发好的字节码增强 Jar 包,复制到 IDEA Plugin 插件开发模块中的 libs(可自己创建) 下,之后在 plugin.xml 配置加载 implementation fileTree(dir: 'libs', includes: ['*jar']) 这样就可以程序中,找到这个 jar 包并配置到程序中。
dependencies {
implementation fileTree(dir: 'libs', includes: ['*jar'])
}
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());
}
}
启动插件
单元测试
@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
名称栏目:换种方式,打印MyBatis执行SQL语句!
网页路径:http://www.gawzjz.com/qtweb/news47/196497.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联