Mybatis的延迟加载***
问题:
在一对多或多对多中,多的一方一般在实体类中表现为一个集合。在查询时,集合的大小是没有理论限制的。
有些时候,此集合的数据在查询后根本不会被使用,就会造成内存空间的极大浪费。
所以,这类数据我们可以在不使用的时候不查询,只有当被使用时才真正查询。达到节省空间和性能的目的。
为什么会有延迟加载?(懒加载)
数据在查询时有一部分是不去查询封装的,而是到真正使用该数据时才去查询。这样就把查询(加载)数据的操作推迟了,所以叫延迟加载。
原则:
多的一方(集合存储的地方)一般使用懒加载
一的一方一般使用立即加载。
如何实现延迟加载
1.使用延迟加载,sql不能编写多表级联语句。否则一次性就查询所有数据,无法实现部分加载。
2.在配置dao的方法时,需要对sql进行拆分
当前的表,直接单表查询。
关联的表,单独调用对应表的dao中的方法进行查询
<association fetchType="eager" property="user" column="uid" javaType="user" select="com.itheima.dao.IUserDao.findById">
property:封装的属性的名称
javaType:封装的属性的类型
select:指定了关联表对应的dao中的方法(statmentid)
column:指定调用dao中方法时传递的参数,实际使用结果集中的某一列的值作为参数,该属性指定的就是列名。
3.开启延迟加载的全局开关
在主配置文件中进行配置
<settings>
<!--开启Mybatis支持延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 高版本mybatis此处可以不设置,因为默认已经为false了-->
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
多表查询的延迟加载配置和上方类似,只是在collection标签上设置select和column
上述步骤中,如果只配置前两步,不去打开全局开关,就只是把多表关联查询拆分成多个单边查询来完成。并不是延迟加载。
如果配置完成了第三步,同时还只想进行拆分而不用延迟加载。可以设置fetchType属性
fetchType有两个取值:
lazy:代表懒加载
eager:代表立即加载。
Mybatis的缓存**
缓存的适用场景
1.经常查询的数据
2.不经常修改的数据
3.数据正确与否影响不大的数据
一级缓存
存在于哪个位置
SqlSession对象中。当查询完毕之后,mybatis会自动把本次查询的结果存入SqlSession。存储的是对象本身
当SqlSession关闭,缓存就会消失。
缓存不需要手动进行维护,mybatis自动维护缓存的使用过程。
以下操作会引发一级缓存的清除
如果在SqlSession上进行增删改操作、以及调用commit方法、close方法、clearCache方法,都会引发缓存的清空。
二级缓存
存在于哪个位置
SqlSessionFactory中。存储的是数据
同一个factory调用openSession获取的SqlSession对象,都可以共享二级缓存中的数据。
二级缓存需要手动开启
1.在主配置文件中
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
2.在映射配置中
在mapper标签内部添加<cache/>
3.在select标签上,添加useCache="true"属性
小结:
mybatis的缓存,都不需要我们手动存储和获取数据。mybatis自动维护的。
在mybatis中,如果是中小型项目,使用自带缓存的机制是可以满足需求的。如果是大型项目,mybatis的缓存灵活性不足,需要使用第三方的缓存技术解决问题。
Mybatis的注解开发*****
注解开发和xml配置优劣分析
1.注解开发和xml配置相比,从开发效率来说,注解编写更简单,效率更高。
2.从可维护性来说,注解如果要修改,必须修改源码,会导致维护成本增加。xml维护性更强。
在实际开发时,一般采取注解开发略多。
如果使用注解,所有dao及dao中的所有方法都要使用注解配置。如果使用xml,所有dao和dao中的所有方法也都要使用xml配置。最好不要混用。
CRUD操作
@Select
@Insert
@Update
@Delete
多表关系配置
1.结果集的字段名称和实体类中属性名称不一致时的处理方式
需要使用 @Results注解完成映射关系的配置。
在Results注解中,使用 @Result指定某一列和属性的对应关系
2.一对一关系配置
@Result(property = "user",column = "uid",
one = @One(select="com.itheima.dao.IUserDao.findById",fetchType= FetchType.EAGER))
在Result注解中,如果要表示一对一的关系,使用one属性设置,one属性的数据类型是 @One
在One注解中,使用select属性配置要调用的目标dao的方法,fetchType指定是否懒加载,一般会是立即加载
3.一对多关系配置
@Result(property = "accounts",column = "id",
many = @Many(select = "com.itheima.dao.IAccountDao.findAccountByUid",
fetchType = FetchType.LAZY))
在Result注解中,如果要表示一对多的关系,使用many属性设置,many属性的数据类型是 @Many
在Many注解中,使用select属性配置要调用的目标dao的方法,fetchType指定是否懒加载,一般会是懒加载
缓存
一级缓存是自动完成的,不需要配置
二级缓存的配置
1.在主配置文件中
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
2.在dao接口的类上添加注解。
@CacheNamespace(blocking = true)
当前dao就支持二级缓存了。