java元婴期(25)----java进阶(mybatis(4)---高级映射查询缓存)
1.需要用到的数据模型(这是后面高级查询需要用到的实例)
用户表user:
记录了购买商品的用户信息
订单表:orders
记录了用户所创建的订单(购买商品的订单)
订单明细表:orderdetail:
记录了订单的详细信息即购买商品的信息
商品表:items
记录了商品信息
表与表之间的业务关系:
在分析表与表之间的业务关系时需要建立 在某个业务意义基础上去分析。
先分析数据级别之间有关系的表之间的业务关系:
usre和orders:
- user---->orders:一个用户可以创建多个订单,一对多
- orders--->user:一个订单只由一个用户创建,一对一
orders和orderdetail:
- orders--->orderdetail:一个订单可以包括 多个订单明细,因为一个订单可以购买多个商品,每个商品的购买信息在orderdetail记录,一对多关系
- orderdetail--> orders:一个订单明细只能包括在一个订单中,一对一
orderdetail和itesm:
- orderdetail--->itesms:一个订单明细只对应一个商品信息,一对一
- items--> orderdetail:一个商品可以包括在多个订单明细 ,一对多
再分析数据库级别没有关系的表之间是否有业务关系:
orders和items:(涉及到数据库的知识)
orders和items之间可以通过orderdetail表建立 关系。
高级查询
1.一对一查询
1.需求
查询订单信息,关联查询创建订单的用户信息
2.resultType
1.sql语句
- 确定查询的主表:订单表
- 确定查询的关联表:用户表
关联查询使用内链接?还是外链接?
由于orders表中有一个外键(user_id),通过外键关联查询用户表只能查询出一条记录,可以使用内链接。
SELECT orders.*,USER.username,USER.sex,USER.address
FROMorders,USER
WHERE orders.user_id = user.id
2.创建pojo
将上边sql查询的结果映射到pojo中,pojo中必须包括所有查询列名。
原始的Orders.java不能映射全部字段,需要新创建的pojo。
创建 一个pojo继承包括查询字段较多的po类。
3.mapper.xml
4.mapper.java
3.resultMap
1.sql语句
同resultType实现的sql(同上)
2.使用resultMap映射的思路
使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。
3.需要Orders类中添加user属性
4.mapper.xml
定义resultMap
<!-- 订单查询关联用户的resultMap将整个查询的结果映射到cn.itcast.mybatis.po.Orders中--><resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"><!-- 配置映射的订单信息 --><!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个idcolumn:订单信息的唯 一标识 列property:订单信息的唯 一标识 列所映射到Orders中哪个属性--><id column="id" property="id"/><result column="user_id" property="userId"/><result column="number" property="number"/><result column="createtime" property="createtime"/><result column="note" property=note/><!-- 配置映射的关联的用户信息 --><!-- association:用于映射关联查询单个对象的信息property:要将关联查询的用户信息映射到Orders中哪个属性--><association property="user" javaType="cn.itcast.mybatis.po.User"><!-- id:关联查询用户的唯 一标识column:指定唯 一标识用户信息的列javaType:映射到user的哪个属性--><id column="user_id" property="id"/><result column="username" property="username"/><result column="sex" property="sex"/><result column="address" property="address"/></association></resultMap>
statement定义
5.mapper.java
3.resultType和resultMap实现一对一查询小结
实现一对一查询:
resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。
如果没有查询结果的特殊要求建议使用resultType。
resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。
resultMap可以实现延迟加载,resultType无法实现延迟加载。(后面再详解)
2.一对多查询
1.需求
查询订单及订单明细的信息。
2.sql语句
- 确定主查询表:订单表
- 确定关联查询表:订单明细表
在一对一查询基础上添加订单明细表关联即可。
SELECTorders.*,USER.username,USER.sex,USER.address,orderdetail.id orderdetail_id,orderdetail.items_id,orderdetail.items_num,orderdetail.orders_idFROMorders,USER,orderdetailWHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id
3.分析
使用resultType将上边的 查询结果映射到pojo中,订单信息的就是重复。
要求:
对orders映射不能出现重复记录。
在orders.java类中添加List<orderDetail> orderDetails属性。
最终会将订单信息映射到orders中,订单所对应的订单明细映射到orders中的orderDetails属性中。
4.在orders中添加list订单明细属性
5.mapper.xml
6.resultMap定义
<!-- 订单及订单明细的resultMap使用extends继承,不用在中配置订单信息和用户信息的映射--><resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap"><!-- 订单信息 --><!-- 用户信息 --><!-- 使用extends继承,不用在中配置订单信息和用户信息的映射 --><!-- 订单明细信息一个订单关联查询出了多条明细,要使用collection进行映射collection:对关联查询到多条记录映射到集合对象中property:将关联查询到多条记录映射到cn.itcast.mybatis.po.Orders哪个属性ofType:指定映射到list集合属性中pojo的类型--><collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"><!-- id:订单明细唯 一标识property:要将订单明细的唯 一标识 映射到cn.itcast.mybatis.po.Orderdetail的哪个属性--><id column="orderdetail_id" property="id"/><result column="items_id" property="itemsId"/><result column="items_num" property="itemsNum"/><result column="orders_id" property="ordersId"/></collection></resultMap>
7.mapper.java
8.小结
mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中。(一对多,推荐使用这种)
使用resultType实现:
将订单明细映射到orders中的orderdetails中,需要自己处理,使用双重循环遍历,去掉重复记录,将订单明细放在orderdetails中。
3.多对多查询
将查询用户购买的商品信息明细清单,(用户名、用户地址、购买商品名称、购买商品时间、购买商品数量)
针对上边的需求就使用resultType将查询到的记录映射到一个扩展的pojo中,很简单实现明细清单的功能。
一对多是多对多的特例,如下需求:
查询用户购买的商品信息,用户和商品的关系是多对多关系。
需求1:
查询字段:用户账号、用户名称、用户性别、商品名称、商品价格(最常见)
企业开发中常见明细列表,用户购买商品明细列表,
使用resultType将上边查询列映射到pojo输出。
需求2:
查询字段:用户账号、用户名称、购买商品数量、商品明细(鼠标移上显示明细)
使用resultMap将用户购买的商品明细列表映射到user对象中。
总结:
使用resultMap是针对那些对查询结果映射有特殊要求的功能,,比如特殊要求映射成list中包括 多个list。
4.resultMap总结
resultType:
作用:将查询结果按照sql列名pojo属性名一致性映射到pojo中。
场合:
常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。
resultMap:
使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。
association:
作用: 将关联查询信息映射到一个pojo对象中。
场合:
为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。
使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。
collection:
作用:将关联查询信息映射到一个list集合中。
场合:
为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块及模块下的菜单,可使用collection将模块映射到模块list中,将菜单列表映射到模块对象的菜单list属性中,这样的作的目的也是方便对查询结果集进行遍历查询。
如果使用resultType无法将查询结果映射到list集合中。
查询缓存
什么是查询缓存
- mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。
- mybaits提供一级缓存,和二级缓存。
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
为什么要用缓存?
如果缓存中有数据就不用从数据库中获取,大大提高系统性能。
2.一级缓存
一级缓存工作原理
1.第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。
得到用户信息,将用户信息存储到一级缓存中。
2.如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
3.第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。
一级缓存测试
mybatis默认支持一级缓存,不需要在配置文件去配置。
按照上边一级缓存原理步骤去测试。
@Testpublic void testCache1() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();//创建代理对象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//下边查询使用一个SqlSession//第一次发起请求,查询id为1的用户User user1 = userMapper.findUserById(1);System.out.println(user1);// 如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。//更新user1的信息user1.setUsername("测试用户22");userMapper.updateUser(user1);//执行commit操作去清空缓存sqlSession.commit();//第二次发起请求,查询id为1的用户User user2 = userMapper.findUserById(1);System.out.println(user2);sqlSession.close();}
一级缓存应用
正式开发,是将mybatis和spring进行整合开发,事务控制在service中。
一个service方法中包括 很多mapper方法调用。
service{
//开始执行时,开启事务,创建SqlSession对象
//第一次调用mapper的方法findUserById(1)
//第二次调用mapper的方法findUserById(1),从一级缓存中取数据
//方法结束,sqlSession关闭
}
如果是执行两次service调用查询相同 的用户信息,不走一级缓存,因为session方法结束,sqlSession就关闭,一级缓存就清空。
3.二级缓存(了解)
原理
- 首先开启mybatis的二级缓存。
- sqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到二级缓存中。
- 如果SqlSession3去执行相同 mapper下sql,执行commit提交,清空该 mapper下的二级缓存区域的数据。
- sqlSession2去查询用户id为1的用户信息,去缓存中找是否存在数据,如果存在直接从缓存中取出数据。
- 二级缓存与一级缓存区别,二级缓存的范围更大,多个sqlSession可以共享一个UserMapper的二级缓存区域。
UserMapper有一个二级缓存区域(按namespace分) ,其它mapper也有自己的二级缓存区域(按namespace分)。
每一个namespace的mapper都有一个二缓存区域,两个mapper的namespace如果相同,这两个mapper执行sql查询到数据将存在相同 的二级缓存区域中。
java元婴期(25)----java进阶(mybatis(4)---高级映射查询缓存)相关推荐
- MyBatis的高级映射之多对一
第五节 MyBatis的高级映射之多对一 2016年3月4日 星期五 09:25 使用传统方式的形式 使用MyBatis的方式 这样会产生两条语句 使用ResultMap的方式,对结果进行映射和转换, ...
- 第4章 MyBatis的关联映射和缓存机制
目录/Contents 第4章 MyBatis的关联映射和缓存机制 学习目标 了解数据表之间的三种关联关系 了解对象之间的三种关系 熟悉关联关系中的嵌套查询和嵌套结果 掌握一对一关联映射 掌握一对多关 ...
- java元婴期(23)----java进阶(mybatis(2)---mapper代理mybatis核心配置文件输入输出映射)
1.mapper代理 1.mybatis开发dao的方法----引入(为啥要使用mapper代理) 1.SqlSession使用范围 1.SqlSessionFactoryBuilder 通过SqlS ...
- java元婴期(29)----java进阶(springmvc(3)---springmvc和mybatis整合参数绑定(上))
springmvc和mybatis整合 需求 使用springmvc和mybatis完成商品列表查询. 整合思路 springmvc+mybaits的系统架构: 第一步:整合dao层 mybatis和 ...
- Mybatis(四) 高级映射,一对一,一对多,多对多映射
天气甚好,怎能不学习? 一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种 ...
- Mybatis学习记录(六)----Mybatis的高级映射
作者:余家小子 1.一对多查询 1.1 需求 查询订单及订单明细的信息. 1.2 sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关联即可. SELECT ...
- Mybatis高级应用 查询缓存
mybatis提供了查询缓存功能,用于减轻数据压力,提高数据库性能.mybatis提供了一级缓存和二级缓存,如下图所示: 从上图可以看出: 一级缓存是存在于一个sqlSession中的,而sqlSes ...
- MyBatis学习--高级映射
简介 前面说过了简单的数据库查询和管理查询,在开发需求中有一些一对一.一对多和多对多的需求开发,如在开发购物车的时候,订单和用户是一对一,用户和订单是一对多,用户和商品是多对多.这些在Hibernat ...
- mybatis (高级映射 缓存 延迟加载)
1 一对一查询映射的pojo 创建pojo包括 订单信息和用户信息,resultType才可以完成映射. 一个订单对应一个用户 因此在订单实体类中 我们应该加入一个用户属性 实体类如下: ...
最新文章
- M_Map画南海水深地形图
- 谷歌大神Jeff Dean点赞网红博士论文:改进分布式共识机制 | 技术头条
- 赛门铁克:“高度怀疑”WannaCry的幕后黑手是朝鲜
- web10 动态action的应用
- android连接Mysql数据库之JDBC方式
- python语言的优缺点论文_Python语言的优缺点是什么呢?
- 《WTM送书活动:向更遥远的星辰大海起航~》
- 研究科学的科学院,一开始也没那么科学!
- Android Picasso最详细的使用指南
- 红橙Darren视频笔记 换肤框架1 获取其他apk中的资源
- Google安全团队对Android安全的认识
- php如何用菜刀连接getshell,xise菜刀后门箱子制作:Sqlmao连接Mysql实现Getshell
- Use Data Caching Techniques to Boost Performance and Ensure Synchronization(转)
- HanLP: Han Language Processing
- jeDate实现日期联动
- 卸载软件时,出现解压缩支持文件时出错,灾难性故障--转载
- 一个生信人的自白:从生物转生信,我的学习与工作经历
- 向NS2中添加协议PING
- 【信息系统项目管理师学习笔记】10大管理|47个过程组:项目整体管理|制定项目章程
- 数据库的基本命令 创建数据库 创建表 插入数据
热门文章
- java 常用的api_Java中常用的API(一)——Object
- shell开启飞行模式_手机上的飞行模式,每天都能用得上,我是才知道,涨知识...
- oracle 信用检查,Oracle EBS 信用(Credit)额度(1)-基础设置
- Excel:Excel使用技巧经验总结之(利用Excel自带功能统计各个字段不同类别及其个数并进行图表可视化+非编程实现)图文教程之详细攻略
- ML之LoR:利用信用卡数据集(欠采样{Nearmiss/Kmeans/TomekLinks/ENN}、过采样{SMOTE/ADASYN})同时采用LoR算法(PR和ROC评估)进行是否欺诈二分类
- ML:从0到1 机器学习算法思路实现全部过程最强攻略
- FE之DR之线性降维:PCA/白化、LDA算法的数学知识(协方差矩阵)、相关论文、算法骤、代码实现、案例应用等相关配图之详细攻略
- 成功解决:利用编程向数据库插入一条记录,而从数据库中查不到该条记录
- CSS学习之盒子模型
- 倒计时321控制器设置