问题分析
1、Dao层使用持久层框架,存在代码重复,整个操作过程模板重复(加载配置文件、创建SqlSessionFactory、生产SqlSession)文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html
2、存在硬编码(statementId)文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html
解决思路
getMapper+动态代理方式优化
使用代理模式生成Dao层接口的实现类文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html
文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html
文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html
SqlSession接口新增getMapper方法文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html
fun <T> getMapper(mapperClass: Class<*>?): T
public <T> T getMapper(Class<?> mapperClass);
DefaultSqlSession中getMapper方法的实现文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html
override fun <T> getMapper(mapperClass: Class<*>): T {
// 使用JDK动态代理为Dao接口生成代理对象
return Proxy.newProxyInstance(
DefaultSqlSession::class.java.classLoader,
arrayOf(mapperClass)
) { proxy, method, args -> // 底层还是执行JDBC
// 准备参数1
// statemendid=namespace.id,获取不到
// statemendid=接口全限定名.方法名
val clazzName = method.declaringClass.name
val methodName = method.name
val statementId = "$clazzName.$methodName"
// 准备参数2:params=args
// 获取被调用方法的返回类型
val genericReturnType = method.genericReturnType
// 判断是否进行了泛型类型参数化
if (genericReturnType is ParameterizedType) {
selectList<Any>(statementId, *args)
} else selectOne<Any>(statementId, *args)
} as T
}
@Override
public <T> T getMapper(Class<?> mapperClass) {
// 使用JDK动态代理为Dao接口生成代理对象
return (T) Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 底层还是执行JDBC
// 准备参数1
// statemendid=namespace.id,获取不到
// statemendid=接口全限定名.方法名
String clazzName = method.getDeclaringClass().getName();
String methodName = method.getName();
String statementId = clazzName + "." + methodName;
// 准备参数2:params=args
// 获取被调用方法的返回类型
Type genericReturnType = method.getGenericReturnType();
// 判断是否进行了泛型类型参数化
if (genericReturnType instanceof ParameterizedType) {
return selectList(statementId, args);
}
return selectOne(statementId, args);
}
});
}
优化版代码
mybatis-proxy/custom-persistence文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html
默认实现方式
mybatis-normal/custom-persistence文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html
文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html文章更新历史
2022/05/08 feat:增加Kotlin实现 文章源自浅海拾贝-https://blog.terwergreen.com/use-getmapper-to-optimize-the-custom-persistence-layer-framework.html
- 扫码加我微信
- 验证消息请输入:来自你的博客
-
- 我的微信公众号
- 微信扫一扫与我交流吧
-
评论