读完源码,手写一个mybatis框架(使用mybatis设计模式和框架,内含手写源码)
继上篇手写spring后(
),感觉有必要继续把mybatis框架也手写出来,供深入理解。网上已经有很多手写框架的博客,但是很多只是按照mybatis流程,面向过程地写:解析xml->代理反射mapper->调用JDBC获取结果。虽然这样理解是对的,但是失去了理解mybatis源码意义。我遵循mybatis源码整体框架和设计,使用源码包名和类名,配合工厂模式和代理模式,写了精简版的mybatis框架。能看懂我这个minmybatis,就能更加容易地理解庞大的源码体系。手写框架的源码已经上传到github上,欢迎下载点星,感谢!
github地址:
现在开始介绍下框架思路:
这个图很清晰地画出了mybatis重要组件类和流程:
从MyBatis源码实现的角度来看,MyBatis的主要的核心部件有以下几个:
Configuration:MyBatis所有的配置信息都维持在Configuration对象之中,核心类;
SqlSession:作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能;
Executor:MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护;
StatementHandler:封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。
ParameterHandler:负责对用户传递的参数转换成JDBC Statement 所需要的参数;
ResultSetHandler:负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;
MappedStatement:MappedStatement维护了一条<select|update|delete|insert>节点的封装;
MapperProxy和MapperProxyFactory:Mapper代理,使用原生的Proxy执行mapper里的方法。
我的minimybatis代码结构如下:
我从测试类main函数说说整体手写过程。
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build("conf.properties");
解释:在SqlSessionFactoryBuilder中加载properties文件配置返回一个默认SqlSessionFactory
最后一句默认sqlSession工厂中扫描mapper.xml将解析后的节点信息存到configuration中。
下面的loadMappersInfo方法中使用dom4j解析xml。
记住上面代码的最后两句设置MappedStatement和Mapper,后面有用。
SqlSession session = factory.openSession();
解释:把上面解析的configuration放在DefaultSqlSession中备用。从下面代码中可以看出,configuration一直传递到执行器里。
UserMapper userMapper = session.getMapper(UserMapper.class);
解释:重点来了,这里开始从session中获取mapper,真正的还是代理工厂返回了mapper实例,获取过程看下面的代码分析。
User user = userMapper.getUser("1");
解释:mapper中具体方法的功能,都是代理的invoke完成的。MapperProxy都实现了InvocationHandler接口。
我们查询一条记录,所以使用sqlSession.selectOne方法。代码实现如下
执行器最终调用了原生的JDBC操作数据库
执行器中我注释的很详细,大家都能明白,这里就不继续粘贴里面的代码了。想看全部的代码,请到github上下载。
现在代码写完了,我们测试以下结果:
整个mybatis精简版框架的写作流程结束,希望您看完可以有所收获,谢谢!
微信公众号:Java实用技术手册
关注可了解更多java技能和互联网面试技巧。问题或建议,请公众号留言。
如果你觉得这篇文章对你有帮助,欢迎一键三连
- 点赞
- 收藏
- 关注作者
评论(0)