网站访客qq获取原理,yw52777最新跳转接口,免费自动建站,江苏省教育网站官网前言
新开一个坑#xff0c;为了学习一下MyBatis的源码#xff0c;写代码是次要的#xff0c;主要为了吸收一下其中的思想和手法。
目的
关联对象接口和映射类的问题#xff0c;把 DAO 接口使用代理类#xff0c;包装映射操作。
知识点
动态代理简单工厂模式Invocati…前言
新开一个坑为了学习一下MyBatis的源码写代码是次要的主要为了吸收一下其中的思想和手法。
目的
关联对象接口和映射类的问题把 DAO 接口使用代理类包装映射操作。
知识点
动态代理简单工厂模式InvocationHandler接口的使用
实现
既然是简易的MyBatis编写那肯定得看下源码了先来一波回忆MyBatis的使用
忘记的朋友可以看下之前写的MyBatis手册 https://blog.csdn.net/weixin_43908900/article/details/129780085
https://www.cnblogs.com/xbhog/p/17258782.html
Test
public void testMybatis(){//加载核心配置文件try {//字符流加载配置InputStream resourceAsStream Resources.getResourceAsStream(mybatis-config.xml);//创建sql连接工厂SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(resourceAsStream);//创建session连接,设置true,默认提交事务SqlSession sqlSession sqlSessionFactory.openSession(true);//反射获取类对象UserMapper mapper sqlSession.getMapper(UserMapper.class);ListUser userAll mapper.getUserAll();System.out.println(userAll);} catch (IOException e) {e.printStackTrace();}
}代码中可以看到接口和映射器有关系的地方应该是sqlSession.getMapper(UserMapper.class);点进去。 先看映射器工厂类MapperProxyFactory
这部分就是我们本次实现的地方。
public class MapperProxyFactoryT {private final ClassT mapperInterface;private final MapMethod, MapperMethodInvoker methodCache new ConcurrentHashMap();public MapperProxyFactory(ClassT mapperInterface) {this.mapperInterface mapperInterface;}public ClassT getMapperInterface() {return mapperInterface;}public MapMethod, MapperMethodInvoker getMethodCache() {return methodCache;}SuppressWarnings(unchecked)protected T newInstance(MapperProxyT mapperProxy) {return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);}public T newInstance(SqlSession sqlSession) {final MapperProxyT mapperProxy new MapperProxy(sqlSession, mapperInterface, methodCache);return newInstance(mapperProxy);}}简易映射器类图 MapperProxy代理类来代理需要使用的接口,为了方便后续的维护扩展在代理类上加一层代理工厂类MapperProxyFactory
使用代理类的好处是 动态代理允许 MyBatis 在不修改接口实现的情况下为接口方法提供自定义的行为。这意味着开发者只需要定义接口和 SQL 映射而无需编写接口的实现类。这种设计促进了关注点分离使得数据访问逻辑SQL与业务逻辑更加清晰MapperProxy 能够在运行时将 SQL 语句与接口方法动态绑定这样MyBatis 可以根据接口方法的签名和注解或 XML 配置来执行相应的 SQL 操作。
使用简单工厂模式的好处 实现代码复用和模块化对代理逻辑和接口使用解耦灵活性高不改变公共接口等。
总之都是为了项目的高度灵活、扩展、复用等。
通过上述的分析现在进行代码编写的流程比较明朗了。
代理类的实现
public class MapperProxyT implements InvocationHandler, Serializable {private static final long serialVersionUID -6424540398559729838L;//模拟SqlSessionprivate MapString, String sqlSession;private final ClassT mapperInterface;public MapperProxy(MapString, String sqlSession, ClassT mapperInterface) {this.sqlSession sqlSession;this.mapperInterface mapperInterface;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//检查一个方法是否来自特定的类或者是一系列接口中的一个//是Object自身的方法就没必要代理直接调用就行if (Object.class.equals(method.getDeclaringClass())) {return method.invoke(this, args);} else {//需要匹配的是类名方法名return 你的被代理了 sqlSession.get(mapperInterface.getName() . method.getName());}}}映射器代理工厂实现
public class MapperProxyFactoryT {private final ClassT mapperInterface;public MapperProxyFactory(ClassT mapperInterface) {this.mapperInterface mapperInterface;}public T newInstance(MapString, String sqlSession) {final MapperProxyT mapperProxy new MapperProxy(sqlSession, mapperInterface);return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);}}执行流程如下 测试
public void testApp() {MapperProxyFactoryIUserDao proxyFactory new MapperProxyFactory(IUserDao.class);MapString,String sqlSession new HashMap();sqlSession.put(com.xbhog.IUserDao.getUserName,模拟执行 Mapper.xml 中 SQL 语句的操作查询用户姓名);IUserDao userDao proxyFactory.newInstance(sqlSession);String userName userDao.getUserName(100001);System.out.println(userName);
}总结
通过追溯MyBatis中的源码,明确本文的主要的内容明确目标类的依赖关系代码实现简易效果明确执行流程测试代码符合预期结果
参考学习
https://mp.weixin.qq.com/s/G3fZES2FvNQK8JLnd9Hx9w
AI大模型辅助
MyBatis源码