MyBatis
JDBC、Hibernate和MyBatis对比
这一部分主要来自《深入浅出MyBatis 技术原理与实战》杨开振的一本书
JDBC
JDBC是由SUN公司提出的一系列规范,只定义接口规范,具体的实现由各数据库厂商去实现。JDBC是一种典型的桥架模式。
使用JDBC步骤
- 连接数据库,注册驱动和数据库信息
- 操作Connection,打开Statement对象
- 通过Statement执行SQL,返回ResultSet对象
- 使用ResultSet读取数据,通过代码转化为POJO对象
- 关闭数据库相关资源
弊端
- 工作量相对较大。需要先连接,然后处理JDBC底层事物,处理数据类型。还需要操作Connection对象,Statement对象和ResultSet对象去拿到数据,并准确关闭它们。
- 需要对JDBC编程可能产生的异常进行捕捉处理并正确关闭资源
Hibernate
全表映射模型,只需要提供POJO和映射关系,最致命的问题是性能。适用于场景不太复杂,要求性能不太苛刻的时候使用。
好处
- 消除了代码的映射规则
- 无需再管理数据库连接
- 一个会话中,不要操作多个对象,只要操作Session对象
- 关闭资源只需要关闭一个Session
缺点
- 全表映射带来的不便,比如更新时需要发送所有的字段
- 无法根据不同的条件组装不同的SQL
- 对多表关联和复杂SQL查询支持较差,需要自己写SQL,返回后,需要自己将数据组装成POJO
- 不能有效支持存储过程
- HQL性能较差,不能满足互联网优化SQL的需求
MyBatis
半自动映射框架,手动提供POJO、SQL和映射关系
优缺点参考:浅谈mybatis优缺点
MyBatis执行大致流程
- 拿到的mapper是JDK动态代理生成的
- 执行查询等方法时,
MapperMethod
通过命令模式执行,拿MapperMethod
是有缓存的 executor
执行查询方法时,先根据MappedStatement
拿到已经变成?
作为占位符的SQL语句- 查数据库前会先查缓存,如果有,直接返回
StatementHandler
将SQL语句转变为PreparedStatement
,并填充参数- 执行
PreparedStatement
resultSetHandler
处理查询结果
遗留问题
- 解析sql时的流程
先替换include,然后计算动态sql部分,然后把${}
替换掉,把#{}
替换掉
- 什么时候把
#{}
换成?
的?
在org.apache.ibatis.builder.SqlSourceBuilder#parse
中在org.apache.ibatis.parsing.GenericTokenParser#parse
方法中,用org.apache.ibatis.parsing.TokenHandler#handleToken