本篇文章,可乐将为大家介绍通过接口代理的方式去执行SQL操作。话不多说,直接上图:

其实无论哪种方式,我们最终是需要找到对应的 SQL 语句,接口代理的方式就是通过 【包名.方法名】 的方式,去找到 xxxMapper.xml 文件中的 SQL 语句。

很明显,通过动态代理的方式,我们能够实现该功能。下面,可乐将为大家手撸一个 Mybatis 的接口代理。

1、创建接口

package com.itcoke.mapperproxy;

import com.itcoke.bean.Person;

public interface PersonMapper {

    Person selectPersonById(Long pid);
}

2、创建代理类

package com.itcoke.mapperproxy;

import org.apache.ibatis.session.SqlSession;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class MapperProxyHandler implements InvocationHandler {
private SqlSession sqlSession;
private Class<?> targetInterface; public MapperProxyHandler(SqlSession sqlSession,Class<?> targetInterface){
this.sqlSession = sqlSession;
this.targetInterface = targetInterface;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String className = targetInterface.getName();
String methodName = method.getName();
String statement = className + "." + methodName; return sqlSession.selectOne(statement,args[0]);
}
}

3、创建代理工厂类

package com.itcoke.mapperproxy;

import java.lang.reflect.Proxy;

public class MapperProxyFactory {
private Class<?> targetInterface; public MapperProxyFactory(Class<?> targetInterface){
this.targetInterface = targetInterface;
} public Object newInstance(MapperProxyHandler handler){
return Proxy.newProxyInstance(targetInterface.getClassLoader(),
new Class[]{targetInterface},
handler);
}
}

4、创建测试类

package com.itcoke.mapperproxy;

import com.itcoke.bean.Person;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException;
import java.io.InputStream; public class MapperProxyTest { public static void main(String[] args) {
// 1、获取目标接口对象
Class<?> targetInterface = PersonMapper.class;
// 2、获取 SqlSession 对象
SqlSession sqlSession = getSqlSession();
MapperProxyHandler proxyHandler = new MapperProxyHandler(sqlSession,targetInterface);
MapperProxyFactory mapperProxyFactory = new MapperProxyFactory(PersonMapper.class);
PersonMapper personMapper = (PersonMapper)mapperProxyFactory.newInstance(proxyHandler);
Person person = personMapper.selectPersonById(1L);
System.out.println(person);
} public static SqlSession getSqlSession() {
//定义mybatis全局配置文件
String resource = "mybatis-config.xml";
//加载 mybatis 全局配置文件
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sessionFactory.openSession();
}
}

5、总结

其实 Mybatis 内部实现方式大体上和上面差不多,在加入一些类型处理器,其实就是一个简易版本的 Mybatis

Mybatis源码解析5—— 接口代理的更多相关文章

  1. Mybatis源码解析(三) —— Mapper代理类的生成

    Mybatis源码解析(三) -- Mapper代理类的生成   在本系列第一篇文章已经讲述过在Mybatis-Spring项目中,是通过 MapperFactoryBean 的 getObject( ...

  2. Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取

    在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们提到了两个问题: 1,为什么在以前的代码流程中从来没有addMapper,而这里却有getMapper? 2,UserDao ...

  3. mybatis源码-解析配置文件(三)之配置文件Configuration解析

    目录 1. 简介 1.1 系列内容 1.2 适合对象 1.3 本文内容 2. 配置文件 2.1 mysql.properties 2.2 mybatis-config.xml 3. Configura ...

  4. Mybatis源码解析优秀博文

    最近阅读了许久的mybatis源码,小有所悟.同时也发现网上有许多优秀的mybatis源码讲解博文.本人打算把自己阅读过的.觉得不错的一些博文列出来.以此进一步加深对mybatis框架的理解.其实还有 ...

  5. Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码

    在文章:Mybatis源码解析,一步一步从浅入深(一):创建准备工程,中我们为了解析mybatis源码创建了一个mybatis的简单工程(源码已上传github,链接在文章末尾),并实现了一个查询功能 ...

  6. Mybatis源码解析(一) —— mybatis与Spring是如何整合的?

    Mybatis源码解析(一) -- mybatis与Spring是如何整合的?   从大学开始接触mybatis到现在差不多快3年了吧,最近寻思着使用3年了,我却还不清楚其内部实现细节,比如: 它是如 ...

  7. Mybatis源码解析(四) —— SqlSession是如何实现数据库操作的?

    Mybatis源码解析(四) -- SqlSession是如何实现数据库操作的?   如果拿一次数据库请求操作做比喻,那么前面3篇文章就是在做请求准备,真正执行操作的是本篇文章要讲述的内容.正如标题一 ...

  8. 【MyBatis源码解析】MyBatis一二级缓存

    MyBatis缓存 我们知道,频繁的数据库操作是非常耗费性能的(主要是因为对于DB而言,数据是持久化在磁盘中的,因此查询操作需要通过IO,IO操作速度相比内存操作速度慢了好几个量级),尤其是对于一些相 ...

  9. Mybatis源码解析-DynamicSqlSource和RawSqlSource的区别

    XMLLanguageDriver是ibatis的默认解析sql节点帮助类,其中的方法其会调用生成DynamicSqlSource和RawSqlSource这两个帮助类,本文将对此作下简单的简析 应用 ...

随机推荐

  1. AndroidStudio快捷键总结

    本文总结一下最近常用的命令: 1.格式化代码:Ctrl+Alt+L[可能与电脑快捷键冲突,修改方法:在设置里点击Keymap 搜索:Reformat Code] 2.复制当前类:Ctrl+Shift+ ...

  2. STM32启动文件详解及SystemInit函数分析(转)

    ;先在RAM中分配系统使用的栈,RAM的起始地址为0x2000_0000 ;然后在RAM中分配变量使用的堆 ;然后在CODE区(flash)分配中断向量表,flash的起始地址为0x0800_0000 ...

  3. 能说会道爱办公——“别人家的”Chrome插件到底怎么做

    根据相关数据显示,谷歌的Chrome浏览器目前已达近七成的市场占有率,成为浏览器的"霸主".大家选择Chrome,除了是因为性能的优越以及强大的兼容性之外,Chrome充足的扩展插 ...

  4. 轻量级状态管理库Pinia试吃

      最近连续看了几个GitHub上的开源项目,里面都用到了 Pinia 这个状态管理库,于是研究了一下,发现确实是个好东西!那么,Pinia 的特点: 轻量化 -- Pinia 体积约1KB,十分轻巧 ...

  5. NOIP 模拟 $36\; \rm Cicada 拿衣服$

    题解 \(by\;zj\varphi\) 发现右端点固定时,左端点的 \(min-max\) 单调递减,且对于 \(or\) 和 \(and\) 相减,最多有 \(\rm2logn\)个不同的值,且相 ...

  6. NOIP 模拟 6 大佬

    这道题是一道数学期望,考场上想的是,每相邻 \(k\) 天之间有 \(k-1\) 天是重合的,所以每两端之间肯定是有影响的. 结果啪啪打脸 这道题其实不用考虑每两段之间的影响,因为在上一段的每种排法, ...

  7. 熟悉而陌生的新朋友——IAsyncDisposable

    本文作者--句幽 在.NET Core 3.0的版本更新中,官方我们带来了一个新的接口 IAsyncDisposable. 小伙伴一看肯定就知道,它和.NET中原有的IDisposable接口肯定有着 ...

  8. 【mysql】关联查询_子查询_排序分组优化

    1. 关联查询优化 1.1 left join 结论: ①在优化关联查询时,只有在被驱动表上建立索引才有效! ②left join 时,左侧的为驱动表,右侧为被驱动表! 1.2 inner join ...

  9. MyBatis like报错

    错误的likeSQL语句是这么写的 select * from student name like '%#{name}%' 下面是错误信息 Parameter index out of range ( ...

  10. web整合Spring和Hibernate

    上一篇是简单整合web和Spring, 这一篇是整合hibernate: 连接池c3p0: spring5.0, hibernate5.0 jars: ------------------------ ...