MyBatis--8.关联关系查询(1)

754 阅读4分钟

1.引言

关联关系的查询在数据库查询中十分常见的操作。

例子:一个国家有多个部长,一个部长只属于一个国家,所以国家和部长的关系是多对一的;

形式 标签
一对多查询 对一方可见,将多方的集合对象作为属性,resultMap中使用collection标签
多对一查询 对多方可见,将一方的对象作为属性,resultMap中使用association标签

2.一对多查询(对一方可见,将多方的集合对象作为属性)

​ 在查询的时候是通过resultMap将查询出来的数据进行封装,因为是将Minister的集合作为Country的属性,所以使用的collection标签;在查询的时候有两种方式,1)多表连接查询;2)多表单独查询;

public class Country {
	private Integer cid;
	private String cname;
    //将Minister的集合作为属性
	private Set<Minister> minister;
	//省略了setter 和 getter 方法
}
	<!--通过多表连接进行查询-->
	<resultMap type="Country" id="countryMapper">
		<id column="cid" property="cid"/>
		<result column="cname" property="cname"/>
		<collection property="minister" ofType="Minister">
			<id column="mid" property="mid"/>
			<result column="mname" property="mname"/>
		</collection>
	</resultMap>

	<select id="selectCountryById" resultMap="countryMapper">
		select cid,cname,mid,mname 
		from country,minister 
		where cid = countryId and cid = #{cid}		
	</select>
=========================================================================================
	<!--通过两个表单独查询-->
	<select id="selectMinisterById" resultType="Minister">
		select mid,mname from minister where countryId = #{cid}
	</select>
	
	<resultMap type="Country" id="countryMapper2">
		<id column="cid" property="cid"/>
		<result column="cname" property="cname"/>
		<collection property="minister" 
					ofType="Minister" 
					select="selectMinisterById"
					column="cid"/>
	</resultMap>
	
	<select id="selectCountryById2" resultMap="countryMapper2">
		select cid,cname from country where cid = #{cid} 		
	</select>

3.多对一查询(多方可见,将一方的对象作为属性)

​ 在查询的时候是通过resultMap将查询出来的数据进行封装,因为是将Country的对象作为Minister的属性,所以使用的association标签;在查询的时候有两种方式,1)多表连接查询;2)多表单独查询;

//对多方可见:将一方的对象作为属性
public class Minister {
	private Integer mid;
	private String mname;
	private Country country;
	//省略setter 和 getter 方法
}
	<!--多表连接查询-->
	<resultMap type="Minister" id="ministerMapper1">
		<id column="mid" property="mid" />
		<result column="mname" property="mname" />
		<association property="country" javaType="Country">
			<id column="cid" property="cid" />
			<result column="cname" property="cname" />
		</association>
	</resultMap>
	<select id="selectMinisterById1" resultMap="ministerMapper1">	
		select mid,mname,cid,cname 
		from minister,country 
		where cid = countryId and mid = #{mid}
	</select>
=========================================================================================
	<!--通过多表单独查询-->
	<select id="selectCountryById" resultType="Country">
		select cid,cname from country where cid = #{cid}
	</select>
	<resultMap type="Minister" id="ministerMapper2">
		<id column="mid" property="mid" />
		<result column="mname" property="mname" />
		<association property="country" 
						javaType="Country" 
						select="selectCountryById"
						column="countryId"/>
	</resultMap>
	<select id="selectMinisterById2" resultMap="ministerMapper2">	
		select mid,mname,countryId from minister where mid = #{mid}
	</select>

4.自关联查询(单表)

​ 在很多情况下,一个表的外键可能还是指向其本身,比如在公司里,老板也算员工中的一员,它们之间的区别在于,普通员工的领导是老板,而老板没有领导,所以没有必要为老板单独设置一个表,类似的例子还有菜单,一级菜单和二级菜单都属于菜单的范畴;例题以菜单为例;

4.1.一对多查询

​ 例:1)查询该菜单下的所有子孙菜单;2)查询该菜单以及菜单下的所有子孙菜单;

​ 实体类:

public class NewsLabel {
	private Integer id;
	private String name;
	private Set<NewsLabel> children;
	//省略了setter 和 getter 方法	
}
	<!--1)查询该菜单下的所有子孙菜单-->	
<!--这里原本是要写一个查询子类对象的方法的,但因为和原select方法完全一样,所以collection的select指向原select方法-->
	<!-- 
	<select id="" resultMap="">
		select id,name,pid from newslabel where pid = #{id}
	</select>
		 -->
	<resultMap type="NewsLabel" id="newsLabelMapper">
		<id column="id" property="id"/>
		<result column="name" property="name"/>
		<collection property="children" 
					ofType="NewsLabel"
					select="selectNewsLabelChildrenByParent"
					column="id"/>
	</resultMap>
	<select id="selectNewsLabelChildrenByParent" resultMap="newsLabelMapper">
		select id,name,pid from newslabel where pid = #{id}
	</select>
=========================================================================================
	<!--2)查询该菜单及菜单下的所有子孙菜单-->
	<select id="selectNewsLabelById" resultMap="newsLabelMapper">
		select id,name from newslabel where id = #{id}
	</select>
	<resultMap type="NewsLabel" id="newsLabelMapper">
		<id column="id" property="id"/>
		<result column="name" property="name"/>
		<collection property="children" 
					ofType="NewsLabel"
					select="selectNewsLabelChildrenByParent"
					column="id"/>
	</resultMap>
	<select id="selectNewsLabelChildrenByParent" resultMap="newsLabelMapper">
		select id,name,pid from newslabel where pid = #{id}
	</select>

4.2.多对一查询

​ 例:查询该菜单以及菜单的父菜单;

​ 实体类:

public class NewsLabel {
	private Integer id;
	private String name;
	private NewsLabel parent;
	//省略setter 和 getter 方法	
}
	<!--查询该菜单的父菜单-->
	<resultMap type="NewsLabel" id="newsLabelMapper">
		<id column="id" property="id"/>
		<result column="name" property="name"/>
		<association property="parent" 
					javaType="NewsLabel"
					select="selectNewsLabelParentByChild"
					column="pid"/>
	</resultMap>

	<select id="selectNewsLabelParentByChild" resultMap="newsLabelMapper">
		select id,name,pid from newslabel where id = #{id}
	</select>