MyBatis:lazy loadingMyBatis学习笔记。

懒加载的原理

mybatis
会循环处理结果集中返回的每行数据的,在拍卖之前率先会见通过反射调用构造方法来创造
result 对象,结果集中之一条龙数最终见面射为一个 result
对象(严格的来说是尴尬的,结果集中之一条龙数以多表连接的情事下可能会见炫耀为多独
result
对象,结果集中的一行数以多表连接一对多的景况下结果集中的多行数据也许映射一个
result 对象,简单的单表查询结果集中之一行数映射为一个 result 对象)。

其实在调用构造方法创建 result
对象的时刻,构造方法还可能会见发参数,需要事先将结果集中的参数还领到出来,传被相应的构造方法通过反射创建对象。

mybatis 其实第一步是分析配置文件,把安排文件映射为 mybatis 的
Configuration 类,把安排文件的 xml 属性都投为 Java 对象吃的属于性值。xml
mapper 文件之处理比较复杂,< resultMap/> 标签映射为 ResultMap
对象, 标签中之< id/> 、< result/>、< association/>
等映射为 ResultMapping 对象。

实在只要摆 mybatis
的落实过程,涉及到的点最为多矣,没法在平篇博客中称。在这里,我偏偏简简单单的谈话一下原理。

继之又道创建好 result 对象下,mybatis 会循环
resultMappings(标签中的每个子标签都映射为一个 resultMapping,这些
resultMapping 组成了一个聚众就是
resultMappings)集合,看起没有发生要懒加载的性,如果有的话,则会呢这
result 对象创建一个代理对象。

咦状态下才见面出现用懒加载的习性也?只有 < association
property=”author” column=”author_id” select=”selectAuthor”
fetchType=”lazy”/> 
以及 < collection property=”xxx” column=”xxx” select=”xxxx”
fetchType=”lazy”/> 作为一个子标签出现在 < resultMap/>
标签(也无必然就是 < resultMap/> 标签,< collection/>
等标签事实上为毕竟一个 < resultMap/>
标签)之内才见面出现得懒加载的习性。select 属性和 fetchType=”lazy”
必须以起在 < collection/> 或 < association/>
属性中才得懒加载,select 代表的凡嵌套查询语句之 id ,fetchType=”lazy”
表示的凡懒加载。

重接着说道 result 对象的代办对象,代理类是出于 javassist
框架在运转时创造及加载的,这个代理类继承自 result
对象所属之类似,以地方的例子也例,这个代理类继承自 Blog 类。

对此这个代理类的详细讲解在我之博客深入了解 Java
动态代理中产生异常详细的介绍,在此间我还简单的牵线下。

这代理类继承了 result
对象所属的切近(被代理类)并重新写了于代理类的具备的点子,所以于代理对象及调用懒加载属性的
get 方法(getAuthor())时会见触发懒加载动作,mybatis
这时便可知觉察欲去懒加载一个性质,然后去加载是特性。

实际上,有几只方式还足以触发发懒加载的操作,比如调用懒加载的 get/set
方法(确实调用 set 方法时为会触发懒加载操作)还有调用
clone()、equals()、hashCode()、toString()方法为会见触发懒加载操作,如果代理对象有多单懒加载属性,则调用后面的即时四个点子时见面又触发加载所有的懒加载属性。

懒加载操作才见面沾一浅,下次再也调用这些点子时莫会见再触发懒加载操作的。

懒加载其实以是相同不成查询操作,懒加载查询需要传递一些参数,还有有其它条件。这些需要传递的属性、参数、查询所待的
sql 语句等连锁的规则都曾经封装到了代办对象中,这些条件封装于一个 Map
中,键是懒加载查询的性质名称,值是查询该属性所用的格,包括参数、sql
语句等。懒加载完一个属性之后会拿这特性从 Map
中移除,所以又起身懒加载操作时 mybatis
就亮该属性已被受加载了了,不见面再次加载。

懒加载也是一个充分复杂的过程,我在地方的讲授着简易了好多,要不折不扣说出来涉及的事物顶多。

自己又下结论一下,懒加载功能使用了代理对象,所以当调用懒加载属性的 get/set
方法(或者是另触发懒加载操作的措施)时 mybatis
才能够明了此刻应该去加载懒加载属性。

 

 

ORM 框架hibernate 也是支撑lazy 加载的,相信原理为是近似之。

《深入浅出MyBatis技术原理同实战》2016年版本 读书笔记

第一章 MyBatis简介

1.ORM模型:对象关系映射,即数据库表与目标期间的投关系模型。
2.Hibernate缺点:全表映射,sql不活,性能略差。
3.MyBatis内需提供的照文件:

  • SQL
  • 照耀规则
  • POJO
    4.MyBatis比于Hibernate更为灵活、可以动态生成映射关系。

第二章 MyBatis入门

1.核心组件:

SqlSessionFactoryBuilder:读取配置到Configuration然后生成SqlSessionFactory。

SqlSessionFactory:工厂模式生成SqlSession。默认实现类DefaultSqlSessionFactory。

  • SqlSession:获取Mapper接口。
  • SQL Mapper:由Java接口和XML文件构成,负责发送SQL执行并返回结果。
    2.生命周期:
  • SqlSessionFactoryBuilder:方法有,创建了即可销毁。

    SqlSessionFactory:存活于MyBatis应用之全方位生命周期,宜用单例,减少开支。

  • SqlSession:相当给JDBC中的Connection,存活于下之伸手和操作。
  • SQL Mapper:接口类,尽量以一个SqlSession事务中使。
    3.实例详见:https://github.com/conanswp/MyBatisDemo.git

第三章 配置

一.MyBatis配备XML层次结构,各标签需要各个以。

图片 1

image

1.properties用来配置属性,可以利用property配置子元素要么下resource属性引用配置文件
2.若需要加密,可以使方面配置密文,而当先后采取SqlSessionFactoryBuild构建SqlSessionFactory的build方法时传出解密后底properties文件。
3.配备优先级:使用程序构建时传出的参数>配置文件>xml中properties中定义的子元素。

二.setting用于配置改变mybatis的作为,例如指定日志组件等。

    <settings>
        <setting name="logImpl" value="LOG4J" />
    </settings>

三.typeAliases用于定义别名,不区分轻重缓急写,用于在mybatis上下文中使用。
1.网已定义别名:_byte->byte,byte->Byte,map->Map,collection->Collection,iterator->Iterator,resultSet->ResultSet等。
2.还足以下typeAliases定义扫描包,然后以类似吃使@Alias注解定义别名。

四.typeHandler类型处理器:用于转换javaType和jdbcType。
1.系已经定义的typeHandler:例如Boolean对应于BooleanTypeHandler,SqlTimestampTypeHandler处理时准确到秒的辰。
2.由此点名jdbcType,javaType,handler属性,可以自定义typeHandler。
3.枚举类型typeHandler:可以用来落实字典。
3.1EnumTypeHander:使用枚举字符串名称作为参数传递。
3.2EnumOrdinalTypeHandler:使用整数下标作为参数传递,默认枚举类新电脑。

五.ObjectFactory是mybatis默认的对象工厂,可以应用该标签定义新的靶子工厂,要求落实DefaultObjectFactory。

六.插件用于覆盖mybatis核心对象的作为。

七.environments用于配置环境,如安排多只数据源,配置多独数据库事务。
1.事务管理器transactionManager:JDBC->JDBC管理事务,MANAGED:容器管理工作,适用于JNDI数据源,自定义->使用者自定义数据库事务管理办法。
2.数目源dataSource:UNPOOLED->非连接池数据库,POOLED->数据库连接池,JNDI->JNDI数据源,自定义->自定义数据源,如dbcp数据源。

八.databaseIdProvider数据库厂商标识,用于指定sql到相应之数据库厂商提供的数据库被运行。即于mapper.xml中的价签中以databaseId指定数据库。自定义需要贯彻DatabaseIdProvider接口。

九.映射器mapper:包括mapper接口和mapper规则配置。引入方式:mapper子元素+resouce属性引入,包名引入,类名引入等。

    <mappers>
        <mapper resource="com/conanswp/mapper/userMapper.xml" />
    </mappers>  

第四章 映射器

以映射器中可定义select查询,insert插入,update更新,delete删除,parameterMap参数映射(已弃),sql定义sql,resultMap结果集,cache/cache-ref命名空间缓存配置等。

一.select
1.机动映射:开在settings中设置autoMappingBhavior配置活动映射策略,其取值为:

  • NONE:取消机关映射
  • PARTIAL:自动映射,不映射结果嵌套的结果集,默认值
  • FULL:自动映射任意复杂的结果集,包括嵌套,性能低
    java类中利用驼峰,数据库被采用_相隔,可以设置mapUnderscoreToCamelCase为true实现活动映射。
    2.传递多单参数可以行使:
  • map:在传递时冲map的key来确定。缺点是参数有事情语义,扩展维护困难。
  • 运用注解@Param实现,然后于select中不应用参数类型。缺点是参数多可读性不高。
  • 使用javabean传递:parameter指定jababean对应类。
    3.默认resultType可以兑现全自动映射,resultMap映射结果集,一般用来复杂、级联查询。resultMap中id元素用于标识主键,result用于投数据库列与对象属性。

二.insert
1.以keyProperty指定主键字段,使用useGeneratedKeys告诉MyBatis这个主键是否采用数据库内置策略生成。
2.好使用selectKey实现检测是否生数据,没有加塞儿1,有插入当前ID+1。

三.update和delete元素执行了后赶回整数表示影响的笔录条数。

四.参数
1.通过EL可以记参数的类、处理器等,例如:
`

{price,javaType=double,jdbcTye=NUMERIC,numericScale=2}

//表示price属性处理项目,精度
`
2.支持存储过程:

  • 支撑回到IN/OUT/INOUT
  • 设存储过程返回游标jdbcType=CURSOR,需要可选设置javaType=ResultSet并定义resultMap
    3.对此返回值是null的,指定StringTypeHandler处理#{note,jdbcType=VARCHAR},用jdbcType=VARCHAR提示mybatis使用StringTypeHandler处理null值。

五.可以定义sql元素,然后于select等操作着经<include
refid=’x’/>引用。

<sql id='x'>
    id,role_name,note
</sql>
<select ...>
    select <include refid="x"/> from t_role
</select>

六.resultMap结果集映射,现在支撑resultMap的询问,不支持创新、删除和改。
1.resultMap组成:

图片 2

image

  • constructor元素用于指定构造方法
  • id用于表示主键,允许多个主键:联合主键。
  • result是POJO到sql列名的照。

2.可以以Map存储结果集(根据key读博结果),但是可读性较逊色,一般推荐POJO方式。

3.行使POJO存储结果集支持电动映射,也可行使resultMap自定义映射。

4.级联:

  • 一对一:association
  • 同样针对几近:collection,多对多可转账为平针对性几近
  • discriminator:鉴别器,根据实际选择以哪个类作为实例

5.延迟加载:

  • 1+N题材:查询主数据,是1破询问,查询出n长记下;根据当时n条主记录,查询从记录,共需要n次,所以于数据库1+n题目;这样会带来性能问题,比如,查询及之n条记录,我或许不过所以到内1长,但是呢尽了n次从记录查询,这是免成立之。
  • mybatis通过安装全局参数:lazyLoadingEnabled(是否被延迟加载功能)和aggressiveLazyLoading(对自由延迟属性发的调用会使带有延迟加载属性的靶子完整加载,反的本需要加载)解决拖欠问题。由于mybatis延迟加载是按层行之,因此aggressiveLazyLoading设置也true表示按层加载,false为依照需要加载。
  • 全局设置不活,可以以association、collection和discriminator中运用fetchType=”lazy”属性设置懒加载(延迟加载)或者fetchType=”eager”即经常加载。
  • 缓加载的落实原理是过渡动态代理实现的。

七.缓存cache
1.默伏支持一级缓存:同一个sqlsession对象调用mapper的方,没过和刷新的气象下单独实行同样不良sql。不同之sqlsession还是会频殡葬sql执行。
2.展二级缓存要求POJO是不过序列化的(实现serializable接口),然后以安排文件中打开缓存<cache/>。这会导致:

  • select语句会缓存
  • insert/update/delete会刷新缓存
  • 缓存默认使用LRU(最近至少使用)算法回收
    二级缓存是sqlsessiofactory级别共享的。一级缓存是sqlsession级别共享的。
    3.二级缓存属性:
  • eviction:缓存策略,LRU/FIFO/SOFT/WEAK
  • flushInterval:刷新时
  • size:缓存数目
  • readOnly:是否只读,不克改改
    4.支持从定义缓存,例如缓存到redis等,需要实现Cache接口。

第五章 动态SQL

支持之动态sql如下:

图片 3

image

一.if
常用test合用,根据test结果判断是否调用,如:

select role_no from t_role where 1=1
<if test="roleName!=null and roleName!=''">
    and role_name like concat('%',#{roleName},'%')
</if>

二.choose/when/otherwise
实现switch…case…default逻辑
三.trim/where/set
1.为避免上面的1=1,可以用where元素:

<where>
<if test="roleName!=null and roleName!=''">
    and role_name like concat('%',#{roleName},'%')
</if>
</where>

2.trim用于去掉and、or等话。

  • prefix:表示语句前缀
  • prefixOverrides:需要去丢的字符串
    3.set用于更新部分许段要不是通时不时错过丢不欲字段后面的逗号。
    四.foreach
    遍历集合,支持数组、List、Set。
    五.test
    用以规范判断
    六.bind
    通过OGNL表达式自定义一个上下文变量。如用于拍卖模糊搜索时mysql的动连接的concat连接,而oracle使用||连接。

PS:基本以上了,原理待读。

相关文章