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>