Mybatis高级映射&查询缓存

 

目录

一、一对一查询

1、resultType

(1)sql语句

(2)映射思路

(3)mapper.java

(4)mapper.xml

2、resultMap

(1)sql语句(同上)

(2)映射思路

(3)mapper.java

(4)mapper.xml

3、resultType和resultMap实现一对一查询小结

二、一对多查询

(1)sql语句

(2)映射思路

(3)mapper.java

(4)mapper.xml

三、多对多查询

(1)sql语句

(2)映射思路

(3)mapper.java

(4)mapper.xml

四、小结

1、resultType和resultMap

2、association和collection

五、延迟加载

1、什么是延迟加载

2、延迟加载配置

3、使用association实现延迟加载

(1)需求

(2)mapper.java

(3)mapper.xml

(4)测试

六、查询缓存

1、什么是查询缓存

2、一级缓存

(1)一级缓存工作原理

(2)一级缓存测试

(3)一级缓存应用

3、二级缓存

(1)二级缓存原理

(2)开启二级缓存

(3)调用pojo类实现序列化接口

(4)测试

(5)如何禁用二次缓存

(6)刷新缓存(就是清空缓存)


一、一对一查询

查询订单信息,关联查询创建订单的用户信息。

1、resultType

(1)sql语句

SELECT 
  orders.*,
  USER.username,
  USER.sex,
  USER.address 
FROM
  orders,
  USER 
WHERE orders.user_id = user.id

(2)映射思路

将上边sql查询的结果映射到pojo中,pojo中必须包括所有查询列名。

原始的Orders.java不能映射全部字段,需要新创建的pojo创建 一个pojo继承包括查询字段较多的po类

(3)mapper.java

(4)mapper.xml

2、resultMap

(1)sql语句(同上)

(2)映射思路

使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。

(3)mapper.java

(4)mapper.xml

3、resultType和resultMap实现一对一查询小结

实现一对一查询:

resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。如果没有查询结果的特殊要求建议使用resultType。

resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中

resultMap可以实现延迟加载,resultType无法实现延迟加载

二、一对多查询

查询订单及订单明细的信息。

(1)sql语句

(2)映射思路

在orders中添加list订单明细属性

(3)mapper.java

(4)mapper.xml

mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中。

三、多对多查询

查询用户及用户购买商品信息

(1)sql语句

SELECT 
  orders.*,
  USER.username,
  USER.sex,
  USER.address,
  orderdetail.id orderdetail_id,
  orderdetail.items_id,
  orderdetail.items_num,
  orderdetail.orders_id,
  items.name items_name,
  items.detail items_detail,
  items.price items_price
FROM
  orders,
  USER,
  orderdetail,
  items
WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id

(2)映射思路

将用户信息映射到user中。

user类中添加订单列表属性List<Orders> orderslist,将用户创建的订单映射到orderslist

Orders中添加订单明细列表属性List<OrderDetail>orderdetials,将订单的明细映射到orderdetials

OrderDetail中添加Items属性,将订单明细所对应的商品映射到Items

(3)mapper.java

(4)mapper.xml

四、小结

1、resultType和resultMap

resultType: 将查询结果按照sql列名pojo属性名一致性映射到pojo中。常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。

resultMap:使用associationcollection完成一对一和一对多高级映射(对结果有特殊的映射要求)。

2、association和collection

association:将关联查询信息映射到一个pojo对象中。

场合:  为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。

         使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。

collection:将关联查询信息映射到一个list集合中。

场合:为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块及模块下的菜单,可使用collection将模块映射到模块list中,将菜单列表映射到模块对象的菜单list属性中,这样的作的目的也是方便对查询结果集进行遍历查询。

使用resultType无法将查询结果映射到list集合中。

五、延迟加载

1、什么是延迟加载

resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。

需求:如果查询订单并且关联查询用户信息。如果先查询订单信息即可满足要求,当我们需要查询用户信息时再查询用户信息。把对用户信息的按需去查询就是延迟加载。

延迟加载:先从单表查询、需要时再从关联表去关联查询,大大提高 数据库性能,因为查询单表要比关联查询多张表速度要快

2、延迟加载配置

mybatis默认没有开启延迟加载,需要在SqlMapConfig.xml中setting配置。在mybatis核心配置文件中配置:lazyLoadingEnabled、aggressiveLazyLoading

设置项

描述

允许值

默认值

lazyLoadingEnabled

全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。

true | false

false

aggressiveLazyLoading

当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。

true | false

true

在SqlMapConfig.xml中配置:

3、使用association实现延迟加载

(1)需求

查询订单并且关联查询用户信息

(2)mapper.java

(3)mapper.xml

需要定义两个mapper的方法对应的statement。

A、只查询订单信息

SELECT * FROM orders

在查询订单的statement中使用association去延迟加载(执行)下边的satatement(关联查询用户信息)

B、关联查询用户信息

         通过上边查询到的订单信息中user_id去关联查询用户信息。 使用UserMapper.xml中的findUserById

上边先去执行findOrdersUserLazyLoading,当需要去查询用户的时候再去执行findUserById,通过resultMap的定义将延迟加载执行配置起来。

C、resultMap——findOrdersUserLazyLoading的定义

(4)测试

六、查询缓存

1、什么是查询缓存

mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。mybaits提供一级缓存【默认开启】,和二级缓存【默认不开启】。

一级缓存SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

二级缓存mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

为什么要用缓存?

        如果缓存中有数据就不用从数据库中获取,大大提高系统性能。

2、一级缓存

(1)一级缓存工作原理

第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。

如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。

第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。

(2)一级缓存测试

mybatis默认支持一级缓存,不需要在配置文件去配置。

按照上边一级缓存原理步骤去测试。

(3)一级缓存应用

正式开发,是将mybatis和spring进行整合开发,事务控制在service中。一个service方法中包括 很多mapper方法调用。

如果是执行两次service调用查询相同 的用户信息,不走一级缓存,因为session方法结束,sqlSession就关闭,一级缓存就清空。

3、二级缓存

(1)二级缓存原理

首先开启mybatis的二级缓存。

sqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到二级缓存中。

如果SqlSession3去执行相同 mapper下sql,执行commit提交,清空该 mapper下的二级缓存区域的数据。

sqlSession2去查询用户id为1的用户信息,去缓存中找是否存在数据,如果存在直接从缓存中取出数据。

 

二级缓存与一级缓存区别,二级缓存的范围更大,多个sqlSession可以共享一个UserMapper的二级缓存区域。

UserMapper有一个二级缓存区域(按namespace分) ,其它mapper也有自己的二级缓存区域(按namespace分)。

每一个namespace的mapper都有一个二缓存区域,两个mapper的namespace如果相同,这两个mapper执行sql查询到数据将存在相同 的二级缓存区域中。

(2)开启二级缓存

mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓存【默认未开启二级缓存】。

在核心配置文件SqlMapConfig.xml中加入

在UserMapper.xml中开启二缓存,UserMapper.xml下的sql执行完成会存储到它的缓存区域(HashMap)。

(3)调用pojo类实现序列化接口

为了将缓存数据取出执行反序列化操作,因为二级缓存数据存储介质多种多样,不一样在内存。

(4)测试

(5)如何禁用二次缓存

在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。

<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

总结:针对每次查询都需要最新的数据sql,要设置成useCache=false,禁用二级缓存。

(6)刷新缓存(就是清空缓存)

在mapper的同一个namespace中,如果有其它insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。

 设置statement配置中的flushCache="true" 属性默认情况下为true即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读

<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">

总结:一般下执行完commit操作都需要刷新缓存,flushCache=true表示刷新缓存,这样可以避免数据库脏读。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值