我是靠谱客的博主 怕黑电话,最近开发中收集的这篇文章主要介绍Mybatis基于xml的一对一、一对多、多对多嵌套结果查询和嵌套查询,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

说在前面

MyBatis在映射文件中加载关联关系对象主要通过两种方式:
嵌套查询和嵌套结果。
嵌套查询:
是指通过执行另外一条SQL映射语句来返回预期的复杂类型。
会执行多条sql语句
嵌套结果查询:
是使用嵌套结果映射来处理重复的联合结果的子集。
只会执行一条复杂的sql语句

简单来说:
嵌套查询是多条sql语句分开写并配置
嵌套结果是一条sql语句关联查询并配置
实质效果是一样的。
但嵌套查询会导致数据库访问次数不定,进而有可能影响到性能。

一对一查询

举例:人和身份证是一一对应的,满足一对一查询
pojo:

public class Person{
	private String name;
	private Integer id;
	private String gender;
	private Integer age;
	private Card card;
	//省略getter、setter
}

public class Card{
	private Integer cid;
	private String address; //住址
	//省略getter、setter
}

  • 数据库表字段与实体类属性对应,person表通过外键cid关联card表

需求:查询person时要求把card也查询出来
问题:数据库查询只能查询出card的字段,不能封装进person实体里的card属性
方法:编写resultMap,手动指定person表字段和实体属性的映射关系

1.嵌套结果查询

	<resultMap id="personMap" type="Person"> <!-- type:实体类名,如不定义别名需写全类名 -->
		<!--column是数据库表的字段名,property是实体的属性名-->
		<id column="id" property="id"></id> 
		<result column="name" property="name"></result>
		<result column="gender" property="gender"></result>
		<result column="age" property="age"></result>
		<!--封装card-->
		<association property="card" javaType="Card"> <!--property:当前实体中的pojo属性  javaType:当前实体中的pojo属性的类型,此处已定义别名-->
			<!--映射card属性-->
			<id column="cid" property="cid"></id>
			<result column="address" property="address"></result>
		</association>
	</resultMap>
	<!--查询-->
	<select id="findAll" resultMap="personMap">
		select * from person p,card c where p.id = c.cid
	</select>

2.还是嵌套结果查询,抽取出被映射的pojo,提高复用性

<resultMap type="Card" id="cardMap">
	<id column="cid" property="cid"></id>
	<result column="address" property="address"></result>
</resultMap>

<resultMap type="Person" id="personMap">
	<id column="id" property="id"></id> 
	<result column="name" property="name"></result>
	<result column="gender" property="gender"></result>
	<result column="age" property="age"></result>
	<association property="Card" resultMap="cardMap" /><!--association标签中通过resultMap="cardMap"引用-->
</result>

<!--嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集-->
<select id="findAll" resultMap="personMap">
	select * from person p,card c where p.id = c.cid
</select>

3.嵌套查询

	<resultMap id="personMap" type="Person">
		<id column="id" property="id"></id> 
		<result column="name" property="name"></result>
		<result column="gender" property="gender"></result>
		<result column="age" property="age"></result>
		<!--association使用select属性引入另外一条SQL语句 -->
		<association property="card" 
			javaType="Card"
			column="cid" <!--引入另外定制sql的参数值,这里是person表里的外键cid-->
			select="cn.wyu.mapper.CardMapper.findCardById"><!--通过findCardByPersonId方法查询出card映射到person实体中的card属性-->
		</association>
	</resultMap>

	<select id="findAll" resultMap="personMap">
		select * from person<!--因为在resultMap-->
	</select>

一对多查询

举例:用户和订单,用户可以有多条订单,每条订单对应一个用户
pojo:

public class User{
	private String username;
	private Integer id;
	private List<Order> orders; //一对多
	//省略getter、setter
}

public class Order{
	private Integer oid;
	private Double money;
	private private User user; //一条订单从属一个用户
	//省略getter、setter
}

  • 数据库表字段与实体类属性对应,order表通过外键uid关联user表

1.嵌套结果查询
userMapper.xml

<resultMap id="baseUserMapper" type="User"><!--User:别名-->
	<id column = "id" property="id"/>
	<result column = "username" property="usernmae"/>
</resultMap>

<resultMap id="userMapper" type="userMapper" extends="baseUserMapper"><!--extends:继承baseUserMapper,减少代码编写,利于维护-->
	<!--一个用户有多条订单,使用collection标签-->
	<collection property="orders" javaType="list" ofType="Order"><!--javaType:封装的是多条订单,是set类型 ofType:集合里的泛型,这里是Order-->
		<id column="oid" property="oid"/>
		<result column="money" property="money"/>
	</collection>
</resultMap>

<!--查询-->
<select id="findAll" resultMap="userMapper">
	select * from user left join order on user.id=order.uid
</select>

orderMapper.xml

<result id="baseOrderMapper" type="Order"><!--Order:别名-->
	<id column="oid" property="oid">
	<result column="money" property="money"/>
</result>

<result id="orderMapper" type="Order" extends="baseOrderMapper">
	<!--一条订单从属一个用户,这里相当于是一对一查询-->
	<association property="user" javaType="user">
		<id column = "id" property="id"/>
		<result column = "username" property="usernmae"/>
	</association>
</result>

<!--查询-->
<select id="findAll" resultMap="orderMapper">
	select * from order,user where order.uid = user.id
</select>

2.嵌套查询
userMapper.xml

<resultMap id="baseUserMapper" type="User"><!--User:别名-->
	<id column = "id" property="id"/>
	<result column = "username" property="usernmae"/>
</resultMap>

<resultMap id="userMapper" type="userMapper" extends="baseUserMapper">
	<!--一个用户有多条订单,使用collection标签-->
	<collection 
		property="orders" 
		javaType="list" 
		ofType="Order" 
		column="id" <!--这里是user表中的id-->
		select="cn.wyu.mapper.OrderMapper.findOrderByUid">
	</collection>
</resultMap>

<!--查询-->
<select id="findAll" resultMap="userMapper">
	select * from user
</select>

orderMapper.xml

<result id="baseOrderMapper" type="Order"><!--Order:别名-->
	<id column="oid" property="oid">
	<result column="money" property="money"/>
</result>

<result id="orderMapper" type="Order" extends="baseOrderMapper">
	<association 
		property="user" 
		javaType="user" 
		column="uid" 
		select="cn.wyu.mapper.userMapper.findUserByUid">
	</association>
</result>
<!--查询-->
<select id="findAll" resultMap="orderMapper">
	select * from order
</select>

多对多查询

举例:用户和角色,一个用户可以有多名角色,一个角色可以被多个用户使用
pojo:

public class User{
	private Integer id;
	private String username;
	private List<Role> roles;
	//省略getter、setter
}

public class Role{
	private Integer id;
	private String rolename;
	private List<User> users ;
}

  • 数据库表字段与实体类属性对应,还要一张维护user和role的中间表,字段是user和role的id,并且都是外键

由于用户和角色是多对多的关系,即它们是同一级别,这里只举出查询用户并对实体内部的角色属性实现映射的例子

userMapper.xml
1.嵌套结果查询

<resultMap id="baseUserMapper" type="User"><!--User是别名-->
	<id column="id" property="id"/>
	<result column="username" property="username"/>
</resultMap>

<resultMap id="userMapper" type="User" extends="baseUserMapper">
	<collection property="roles" javaType="list" ofType="Role">
		<id column="id" property="id">
		<result column="rolename" property="rolename">
	</collection>
</resultMap>

<select id="findAll" resultMaop="userMapper">
	select * from (user u left join user_role ur on u.id=ur.uid) left join role r on r.id=ur.rid
</select>

2.嵌套查询

<resultMap id="baseUserMapper" type="User"><!--User是别名-->
	<id column="id" property="id"/>
	<result column="username" property="username"/>
</resultMap>

<resultMap id="baseRoleMapper" type="Role">
	<id column="id" property="id">
	<result column="rolename" property="rolename">
</resultMap>

<resultMap id="userMapper" type="User" extends="baseUserMapper">
	<collection 
		property="roles" 
		javaType="list" 
		ofType="Role" 
		column="id"  <!--同样是user表的id-->
		select="cn.wyu.mapper.RoleMapper.findRoleListByUid">
	</collection>
</resultMap>

<!--这里有必要贴一下findRoleListByUid方法的代码-->
<select id="findRoleListByUid" resultMap="baseRoleMapper" paramType="int">
	select * from user_role ur,role r where ur.rid = r.id and ur.uid=#{uid}
</select>

<select id="findAll" resultMaop="userMapper">
	select * from user
</select>

最后

以上就是怕黑电话为你收集整理的Mybatis基于xml的一对一、一对多、多对多嵌套结果查询和嵌套查询的全部内容,希望文章能够帮你解决Mybatis基于xml的一对一、一对多、多对多嵌套结果查询和嵌套查询所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部