三种方式:
①业务装配
对两个表编写单表查询语句,在业务层(Serivce)把查询的两个结果进行关联
②使用Auto Mapping特性
在实现两表联合查询时通过别名完成映射,使用Maybatis的<resultMap>元素进行实现
多表查询时,类中包含另一个类对象
①单个对象
如:一个工人对应一个公司
②集合对象
如:一个公司包含多个工人
<resultMap>元素
<resultMap id="" type="">
<id property="属性名" column="查询结果列名"/> //主键使用id
<result property=""/ column=""> //其余使用result
</resultMap>
实现关联单个对象查询(N+1方式)
使用子元素:
<association property="" javaType=“对象类型”(可省略) select=“另一个select元素的引用” column=“传入参数”/>
Ps:需要传入多个参数时,column="{“key”:property,“key”:property},实质为map
例(一个产品有一个生产工厂):通过接口绑定
public Goods selGoodsUseNadd1(@Param(“id”)int id);
<!--resultMap元素-->
<resultMap id="GoodsNadd1" type="Goods">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="produce" column="produce"/>
<association property="manufactory" select="com.mfqh.mapper.UnionMapper.selManu" column="produce"></association>
</resultMap>
<!--被引用的查询-->
<select id="selManu" resultType="Manufactory">
SELECT * FROM manufactory WHERE id=#{0}
</select>
<!--主查询-->
<select id="selGoodsUseNadd1" resultMap="GoodsNadd1">
SELECT * FROM goods WHERE id=#{id}
</select>
结果:
实现关联多个对象查询(N+1方式)
使用子元素:
<collection property="" select = “另一个select元素的引用” javaType=“集合类型”(可省略) ofType=“集合的范型”(可省略) column=“传入参数”/>
例(一个工厂生产多个产品):通过接口绑定
<!-- rsultMap查询结果处理 -->
<resultMap id="ManufactoryNadd1" type="Manufactory">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="local" column="local"/>
<collection property="goods" select="com.mfqh.mapper.UnionMapper.selGoods" column="id"></collection>
</resultMap>
<!-- 副查询 -->
<select id="selGoods" resultType="Goods">
SELECT * FROM goods WHERE produce = #{0}
</select>
<!-- 主查询 -->
<select id="selManuUseNadd1" resultMap="ManufactoryNadd1">
SELECT * FROM manufactory WHERE name = #{name}
</select>
结果:
与业务装配的区别:service中执行的代码,在mybatis中完成
Ps:如果列名和属性名相同可以不配置,但是要进行传参的列必须进行配置
实现关联单个对象查询(联合查询)
将<association>元素扩展开:
<associatetion properity="" javaType="对象类型>
<id property="" column=""/> //主键使用id
<result property=""/ column=""> //其余使用result
</associatetion>
此时在SELECT中直接使用多表查询语句
例(一个产品有一个生产工厂):通过接口绑定
public Goods selGoodsUseUnion(int id);
<!-- rsultMap查询结果处理 -->
<resultMap id="GoodsUseUnion" type="Goods">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="produce" column="produce"/>
<association property="manufactory" javaType="Manufactory">
<id property="id" column="fid"/>
<result property="name" column="fname"/>
<result property="local" column="flocal"/>
</association>
</resultMap>
<!-- 查询 -->
<select id="selGoodsUseUnion" resultMap="GoodsUseUnion">
SELECT g.*,f.id fid,f.name fname,f.local flocal FROM goods g LEFT OUTER JOIN manufactory f ON g.produce=f.id WHERE g.id=#{0}
</select>
Ps:此处若两个表有相同的字段名称,则需起别名
结果:
实现关联多个对象查询(联合查询)
多个对象(mybatis可根据主键判断对象是否创建):
<collection property="" ofType="集合的范型”>
<id property="" column=""/> //主键使用id
<result property=""/ column=""> //其余使用result
</collection>
例(一个生产工厂有多个产品):通过接口绑定
public Manufactory selMaunUseUnion(String name);
<!-- rsultMap查询结果处理 -->
<resultMap id="ManuUseUnion" type="Manufactory">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="local" column="local"/>
<collection property="goods" ofType="Goods">
<id property="id" column="gid"/>
<result property="name" column="gname"/>
<result property="produce" column="gproduce"/>
</collection>
</resultMap>
<!-- 查询 -->
<select id="selMaunUseUnion" resultMap="ManuUseUnion">
SELECT f.*,g.id gid,g.name gname,g.produce gproduce FROM goods g LEFT OUTER JOIN manufactory f ON g.produce=f.id WHERE f.name=#{param1}
</select>
结果:
联合查询和N+1方式的对比
N+1:需求不明确,含义为得出结果需要N+1条sql语句;效率低;适用场景不一定两个表都需要查时
联合查询:需求中确定两个表都一定查询
Auto Mapping结合别名实现多表查询
此时只能使用多表联合查询,并且只能实现一个对象的查询
别名使用:类名.列名的方式
此时直接使用resultType属性和sql联合查询语句,会进行自动映射
例:通过接口绑定
public Goods selGoodsAlias(int id);
<!-- 类名.别名方式进行查询 -->
<select id="selGoodsAlias" resultType="Goods">
SELECT g.*,f.id `Manufactory.id`,f.name `Manufactory.name`,f.local `Manufactory.local` FROM goods g LEFT OUTER JOIN manufactory f ON g.produce=f.id WHERE g.id=#{0}
</select>
Ps:此处注意sql中.
为关键字,需使用着重号`将别名括起来。
结果: