使用getMapper方式对自定义持久层框架进行优化
本文介绍了通过使用代理模式优化MyBatis持久层框架中的Dao层代码重复和硬编码问题。通过引入getMapper方法和动态代理,实现Dao层接口的自动生成,简化了整个操作过程模板,同时消除了硬编码,提高了代码的灵活性和可维护性。
# 问题分析
说一说不使用 getMapper 操作 mybatis 存在哪些弊端?
1、Dao 层使用持久层框架,存在代码重复,整个操作过程模板重复(加载配置文件、创建 SqlSessionFactory、生产 SqlSession)
2、存在硬编码(statementId)
# 解决思路
# getMapper + 动态代理方式优化
使用代理模式生成 Dao 层接口的实现类
SqlSession 接口新增 getMapper 方法
public <T> T getMapper(Class<?> mapperClass);
1
DefaultSqlSession 中 getMapper 方法的实现
@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);
}
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 优化版代码
mybatis-proxy/custom-persistence (opens new window)
# 默认实现方式
mybatis-normal/custom-persistence (opens new window)
文章更新历史
2024/04/24 同步文章到其他平台
2022/05/08 feat: 初稿
编辑 (opens new window)
上次更新: 2024/06/13, 04:00:49