我理解的Mybatis

一 概述

Mybatis是一个半ORM(对象关系映射)框架,它支持自定义SQL,存储过程以及高级映射,使得开发时只需要关注SQL语句本身。节省了处理加载驱动,创建连接,创建获取结果集的statement等繁杂工作的时间。

MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

二 MyBatis与Hibernate的不同

MyBatis

MyBatis可以理解为半自动ORM映射工具,使用MyBatis在查询关联对象或关联集合对象时需要开发者自己编写原生态的Sql语句。通过这些Sql语句可以控制Sql的执行性能,灵活度高,适合对数据模型要求不高的软件开发,从而能够满足软件需求多变的情况。

于此同时,MyBatis虽然比较灵活,但是它无法做到数据库的无关性,如果需要实现支持多种数据库的软件,则需要自定义多套Sql映射文件,工作量大。

Hibernate

Hibernate可以理解为全自动ORM映射工具,而且对象/关系映射能力强,所以使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取。同时,Hibernate很好的满足数据库无关性的业务场景需求,即能够支持多种数据库的软件,使得编码的工作量较小,能够提高效率。

三 基于Mybatis的分页实现

Mybatis借助RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,并非物理分页。我们可以通过在Sql内直接书写带有物理分页的参数来实现物理分页功能,也可以使用分页插件来完成物理分页。

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

四 与Mybatis相关的延迟加载问题

Mybatis仅仅支持association关联对象和collection关联对象集合对象的延迟加载,其中association是指一对一的查询,而collection则是指一对多的查询。

association 实现的一对一延迟加载

<association property="user" javaType="com.User"  column="user_id" select="getUserByUserId"> </association>

collection 实现的一对多延迟加载

<collection property="userList" fetchType="lazy" column="user_id" select="getUserByUserId"> </collection>  

Mybatis支持延迟加载与否的配置

<!-- 开启懒加载配置 -->
<settings>
    <!-- 全局性设置懒加载。如果设为‘false',则所有相关联的都会被初始化加载-->   
    //可以配置lazyLoadingEnabled 值为true,不设置aggressiveLazyLoading,为全局设置。
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 当设置为‘true'的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载-->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

Mybatis延迟加载的原理:借助CGLIB创建目标对象的代理对象,当调用目标对象时,进入拦截器方法,如通过User的对象获取其成员变量Student实例化对象中的name属性,即user.getStu().getName()。拦截器invoke()方法发现user.getStudent()获取的值为null值,那么就会单独发送事先保存好的查询关联对象Stu的sql,将Student对象查询出来,然后调用user.setStudent(stu)使得user对象中的Stu对象存在值,从而完成user.getStu().getName()的整个调用过程。

除了Mybatis以外,Hibernate同样借助该原理实现延迟加载。

五 Mybatis中不同的Xml映射文件id的可重复性问题

在Xml映射文件中将namespace+id作为Map<String,MapperStatement>的key使用,Mybatis之前的版本中的namespace是可选的,而新版本的namespace则是必须的。由此可知,当namespace存在且不同时,id可以重复,否则不可以。

六 Mybatis中的一级缓存和二级缓存

一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为SqlSession,当执行SqlSession flush或者close操作之后,该Session中的所有缓存就会被清空,同时默认情况下是开启一级缓存的。

二级缓存:二级缓存同一级缓存的机制相同,默认也是采用Perpetualcache,HashMap进行存储,不同在于其存储作用域为Mapper(Namespaces),并且可以进行自定义存储源。默认情况下二级缓存并不开启,如果要开启二级缓存,使用二级缓存的属性类需要实现序列化接口(Serializable),并在映射文件中进行配置。

对于缓存数据更新时,(一级缓存 Session/二级缓存Namespaces)进行C/U/D操作后,默认该作用域下所有的select中的缓存将会被clear清理并重新更新。如果为二级缓存时,则需要根据配置文件进行执行刷新的判断。

参考资料:Mybatis官房文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值