远方的灯塔 - 专注于服务端技术分享 远方的灯塔 - 专注于服务端技术分享
首页
  • Java SE
  • Struts2
  • Hibernate
  • MyBatis
  • JAX-WS
  • 并发
  • 分布式
  • Git
  • 《C程序设计语言》
心情随笔
  • 文章分类
  • 文章标签
  • 文章归档
友情链接
关于我
GitHub (opens new window)

Terwer Green

一个后端老菜鸟
首页
  • Java SE
  • Struts2
  • Hibernate
  • MyBatis
  • JAX-WS
  • 并发
  • 分布式
  • Git
  • 《C程序设计语言》
心情随笔
  • 文章分类
  • 文章标签
  • 文章归档
友情链接
关于我
GitHub (opens new window)
  • MyBatis

    • 解析原生JDBC开发问题与优化方案
    • 自定义持久层框架的设计思路
    • 自定义持久层框架的代码实现一
    • 自定义持久层框架的代码实现二
    • 使用getMapper方式对自定义持久层框架进行优化
      • 问题分析
      • 解决思路
        • getMapper + 动态代理方式优化
      • 优化版代码
      • 默认实现方式
    • MyBatis的基本介绍及优势
    • MyBatis的基本使用
    • Mybatis基本流程及配置文件解析
    • MyBatis复杂映射开发之一对一查询
    • MyBatis复杂映射开发之一对多查询
    • MyBatis复杂映射开发之多对多查询
    • MyBatis常用注解及基本增删改查的注解实现
    • MyBatis的注解实现复杂映射开发
    • MyBatis缓存的概念
    • 深度剖析MyBatis的一级缓存
    • 深度剖析MyBatis的二级缓存
    • MyBatis的二级缓存整合redis
    • MyBatis-RedisCache源码分析
    • MyBatis机制介绍与原理
    • 自定义MyBatis插件
    • 插件源码进一步分析与pageHelper分页插件介绍
    • 通用 Mapper 封装
    • 深入剖析MyBatis的架构原理
  • 《设计模式》

  • 后端开发
  • MyBatis
terwer
2022-08-29
目录

使用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

# 优化版代码

mybatis-proxy/custom-persistence (opens new window)

# 默认实现方式

mybatis-normal/custom-persistence (opens new window)

文章更新历史

2024/04/24 同步文章到其他平台

2022/05/08 feat: 初稿

‍

编辑 (opens new window)
#custom#dao#persistence#framework#mybatis#mybatis-5#mapper#动态代理#持久层框架#SqlSession
上次更新: 2024/06/13, 05:26:42
自定义持久层框架的代码实现二
MyBatis的基本介绍及优势

← 自定义持久层框架的代码实现二 MyBatis的基本介绍及优势→

最近更新
01
深入剖析MyBatis的架构原理
12-04
02
通用 Mapper 封装
10-09
03
插件源码进一步分析与pageHelper分页插件介绍
10-09
更多文章>
Theme by Vdoing | Copyright © 2011-2024 Terwer Green | MIT License | 粤ICP备2022020721号-1 | 百度统计
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式