今天是刘小爱自学Java的第119天。
感谢你的观看,谢谢你。
学习内容安排如下:
- 昨天没有学完的多对多查询补充。
- resultMap标签的继承问题。
- mybatis中的延迟加载。
- colum属性的一个补充说明。
一、多对多查询
案例:查询订单,查询出下单人信息并且查询出订单详情中的商品数据。
1业务分析
一共有4张表,都是基于订单表的,我们再次梳理下它们的关系:
- 一对一:订单和用户的关系,所以在订单类中封装了一个用户对象。
- 一对多:订单和订单详情的关系,所以在订单实体类中封装订单详情集合。
- 多对多:订单详情和商品的关系,它们之间的关系是依托于订单的。
一个订单对应多个订单详情,从而引出了多个商品。但是如果在同一个订单详情中呢?
一个订单详情对应一个商品,所以我们在订单详情中加入item实体类对象。
这个关系捋清楚了,代码也就好写了。
其中关于sql语句的编写:
本来一开始时特不喜欢sql语句大写字母的,因为个人觉得其可读性差,就跟枚举一样。
不过Navicat中有一个美化SQL的功能,就是将sql语句弄成这个样子的。
我一想那肯定有它的道理,就试着用了下,慢慢地竟然觉得也挺好看的,真香。
人啊,果然最怕陷入固有的思维,不敢或者说反感去接触自身不熟悉的东西。
总觉得自己很了解自己,其实根本就不了解。
2代码编写
在接口OrderMapper中创建对应的查询方法,关于方法要保证见名知义。
老实说,这种大驼峰式的命名方式,我还觉得蛮好看的,可读性很强。
然后在映射文件中编写对应的sql语句。
返回值使用resultMap标签说明其映射关系。
其中resultMap标签中代码编写如下:
返回值都是依托于Order这个实体类的。
①一对一关系
用association标签说明Order实体类中的user属性是和User实体类对应的。
②一对多关系
用collection标签说明Order实体类中的orderdetails和List<Orderdetail>对应。
③多对多关系
在一对多关系中的一对一关系为多对多。
在同一订单详情中商品和订单详情是一对一关系,所以使用association标签说明。
值得注意的是:
- autoMapping属性为true即开启自动映射,如果控制台有的值输出为null,大概率就是没有设置自动映射的原因。
- colum属性,是和数据库中的列名相对应的,非order的id就使用对应的外键id名,如果没有,我们可以自己创建一个别名。
关于colum属性,我做一个详细说明:
上图是Navicat中执行sql语句后的一张结果表,因为太长了我把它们分开了,其实就是一张表,数据由四张表组成:
该结果表中的id也就是和主表order中的id。
id1,id2,id3也就是从表各自的id,但是其顺序是可变化的,并不能成为表的唯一标识。
所以就使用外键的方式来说明从表的id,也就是user_id,item_id这些。
但orderdetail表并没有外键,就在sql语句中给它创建一个别名,也就是detail_id。
二、resultMap的继承
补充说明下这个小知识点;
在resultMap中有代码会出现不断地重复配置的情况,比如关于order与user的映射关系。
如果存在重复的代码,可以使用继承的方式,和Java中一样也是extend这个关键字。
在extend属性中说明需要继承的resultMap标签对应的id即可。
三、延迟加载
延迟加载的作用在于性能上的节省。
1改造一对一查询
案例:根据订单号查询出订单信息,并查询出该订单的下单人信息。
我们一开始是使用的一条sql语句完成数据库查询,可以将其改造成两条sql语句。
①resultMap标签中说明返回值。
②association子标签
通过select指定需要执行的查询语句。
也就是说①中的sql语句执行后,通过该属性让③中的sql语句执行。
这样就能完成两条sql语句的依次执行了。
2开启延迟加载
①开启延迟加载
lazyLoadingEnabled,延迟加载的全局开关,当开启时,所有关联对象都会延迟加载。
默认值是false,我们需要将其设定为true。
②开启按需加载
aggressiveLazyLoading
当开启时,任何方法的调用都会加载该对象的所有属性;否则,每个属性会按需加载。
默认值为true,这里设定false,关闭立即加载,也就是开启按需加载了。
最后
谢谢你的观看。
如果可以的话,麻烦帮忙点个赞,谢谢你。