使用CGLib动态代理jdbc原生类来实现应用层无感知的proxy层面的SaaS分库支持
Posted 李昊轩的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用CGLib动态代理jdbc原生类来实现应用层无感知的proxy层面的SaaS分库支持相关的知识,希望对你有一定的参考价值。
本文紧接上一篇
独家首发! java助力mycat实现动态添加数据源, 实现SaaS新增租户秒登独立数据库
使用了动态代理来代理了jdbc的Connection, PreparedStatement对象,
是SaaS应用层实现的具体对接:
这个纯属我个人考虑开发效率搞的骚操作, 因为动态代理肯定是没有一个一个重写这种静态编译效率高, 希望给大家多一种解决思路~~
public class CGLIBProxyPreparedStatement {
static String s = "executeupdate,executequery"; // 需要proxy的方法,
static Set<String> targetMethodNames = new HashSet(Arrays.asList(s.split(",")));
static class CjLibProxy implements MethodInterceptor {
private final PreparedStatement preparedStatement;
public CjLibProxy(PreparedStatement preparedStatement) {
this.preparedStatement = preparedStatement;
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// 根据方法名判断是否追加hint注解
if (targetMethodNames.contains(method.getName().toLowerCase())) {
if (args.length >= 1) {
// sql 参数一定是在第一位的
args[0] = ProxySqlHints.renderHints(args[0].toString());
}
}
return method.invoke(preparedStatement, args);
}
}
public static PreparedStatement newInstance(PreparedStatement preparedStatement) {
CjLibProxy proxy = new CjLibProxy(preparedStatement);
return (PreparedStatement) Enhancer.create(PreparedStatement.class, proxy);
}
}
ProxySqlHints.renderHints() 这个方法不多说, 这里是实现增加sql改写的位置, 不同的中间件例如mycat sharding proxy都有不同的实现, 大概就是增加注解, 这里就不做举例了, 不会的同学可以私信或者下面评论答惑.
谢谢大家观看本文~~.
以上是关于使用CGLib动态代理jdbc原生类来实现应用层无感知的proxy层面的SaaS分库支持的主要内容,如果未能解决你的问题,请参考以下文章