MyBatis(六)--多表关联查询
一 什么是多变关联
1. 所谓的多变关联,就是表结构中存在多对一,一对多的现象,当然也存在多对多。
2. 在真正的工作中,经常存在多表关联的存在,就是说外键的存在。比如说:商品表 goods,会关联一个分类表,将每个商品进行分类处理。
3.Bean 类中的多变关联,作为分类表,应该存在有一个 List 对象来存放属于该分类的商品对象。而每个商品表中也应该有一个分类 bean 对象用于说明商品的分类信息
4. 在 JDBC 的正常操作中,我们需要通过两次查询来依次存放数据来完成商品 Bean,分类 Bean 对象,当然这使用 MyBatis 同样可以做到
5. 在 MyBatis 中,提供了一些操作可以使我们在一次查询中将直接完成 Bean
二 多变关联实现(一)
1. 操作原理:
(1)在单表操作中,我们使用 resultType 来指定返回类型,并将得到的值依次类型传递到业务逻辑中去,而在多变关联查询中,我们则不使用 resultType,而是使用 resultMap 将返回值以 Map 的形式传递到 resultMap 操作中。
(2)如何映射相应的 resultMap?必须使得 select 中的 resultMap 的值与 resultMap 中的 id 值保持一致
(3)将返回值作为 Map 的话,列名作为 key,那多条语句的 key 值重复问题?我们必须明确,在 SQL 语句中的多条语句查询,是像指针逐条逐条输出的,所以每次都是一个新的 map 虽然 key 值都是这些列名,但是 Value 值却随着指针的改变而改变。这也是为什么当我们需要返回一个 List 对象是,resultType 依旧要写 List 泛型中的 Bean 类。
2. 一对多与多对多的实现
resultMap 的实现
执行结果
(1)所谓一对多与多对多无非就是查询一条与多条的区别,除了返回值一个是 bean 对象一个是 List 对象外并没有本质区别
(2)id 与 result,id 用于设置主键的映射关系(这里也包括外联表的主键),而 result 则用于设置非主键的映射关系
(3)collection 中,用于设置外联表的映射,使用 ofType 来设置外联表的 Bean 类,而原本表的 bean 类由 resultMap 中的 Type 属性确定
(4)column 与 property:column 则是列名,即 SQL 语句返回出来的列名,property 则是 Bean 对象的属性名
3. 多对一的实现
select 语句:不用在意 useCache 属性,这是用于设置缓存的属性,与这次无关
resultMap 语句:
(1)基本是所有东西与一对多相似,下面只说区别
(2)assciation 替换 javaType
三 多变关联实现(二)
1. 一次查询的缺陷
我们发现这种写法实际上是很麻烦的,他需要将表关联起来,就是使用连接的方式,也就是这样
即使是一对多也会是这样
导致了分类表信息大量的重复,如果只是这几条数据没什么问题,但是当数据量过大时则会出现效率问题,所以我们还是应该采用两次查询来完成操作,当然对于业务逻辑层的执行依旧是一次操作(不然的话,我们费力干这些是为了干嘛?)
2. 两次查询的操作
执行结果
(1)我们本质上还是针对于 selClassifyOneAndAll 进行了查询
(2)当返回结果进入 classifySepMap 中后,先是映射 id 和 result 属性,在进入 collection 标签中,而 collection 标签中则使用 select 访问下一次查询,并将主键使用 column 属性传递到下次查询中,找到相应外键值并传递
(3)property 中的 list 并非指类,而是 Classify 中的属性名,第二次查询(selGoodsByCid)会将结果返回成 Goods 的集合传递到这个属性中。
四 多变关联实现(三)
1. 约束 : 这种实现要求在 select 中讲结果使用别名的方式与对象中的属性名映射起来且值是用于多对一查询
2. 对于 bean 对象的内部 bean 对象属性,要使用“bean 属性名.bean 对象属性名的“的方式来指定,但是由于点在 SQL 语句中有特殊含义,所以需要使用 `` 来取消他的特殊含义。
执行结果