MyBatis联表CRUD
I.多表连接查询方式 :
<!-- 结果的映射及关联关系的映射-->
<resultMap type="City" id="cityMapper">
<id column="ctid" property="ctid"/>
<result column="ctname" property="ctname"/>
<!-- <association>表示多对一关联关系的说明,property:在多方实体类中包含的一方关联属性的名称,javaType:一方关联属性的类型 -->
<association property="country" javaType="Country">
<id column="cid" property="cid"/>
<result column="cname" property="cname"/>
</association>
</resultMap>
<!-- 多表连接查询方式 -->
<select id="selectCityByCtid" resultMap="cityMapper">
select * from city ct,country c where ct.country_id=c.cid and ct.ctid=#{xxx}
</select>
II.多表单独查询方式:
<!-- 多表单独查询方式 -->
<select id="selectCountryByCountryId" resultType="Country">
select * from country where cid=#{xxx}
</select>
<resultMap type="City" id="cityMapperSingle">
<id column="ctid" property="ctid"/>
<result column="ctname" property="ctname"/>
<association property="country" javaType="Country" select="selectCountryByCountryId" column="cid"></association>
</resultMap>
<select id="selectCityByCtidSingle" resultMap="cityMapperSingle">
select ctid,ctname,country_id cid from city where ctid=#{xxx}
</select>
2.自关联:反应到数据库查询中用自连接来表示,即一张当成多张表来进行连接查询。
自关联可以以一对多来处理(如通过主菜单找到该主菜单下面所有的子菜单),也可以以多对一来处理(如给出一个文件位置,找出这个文件的所有上级目录的路径)。
(1)自关联以一对多的方式处理
开发步骤:
I.创建菜单表,设置关系,指明外键,由于自连接是连接同一张表,所以多方的外键是在同一张表中,外键指向父元素的id,一级元素的外键为null,而其他子元素的外键不为空,为它的上一级元素的id。
-- 菜单表
create table menu
(
mid int primary key auto_increment, -- 主菜单id
mname varchar(20), -- 菜单的名字
pid int, -- 父菜单的id
foreign key(pid) references menu(mid)
);
II.创建实体类
//一方
public class Menu {
private int mid;
private String mname;
// 以一对多方式处理,此时的Menu看到的子菜单Menu是多个
// 关联属性:表示子菜单
private Set<Menu> menus;// 多方
...
}
III.创建MenuDao
IV.创建映射文件
A.以一对多的方式:使用递归调用,将本次查询的id作为下一次查询父id进行递归搜索。比如菜单。
只找父菜单下面的子菜单:
<resultMap type="Menu" id="menuMapper">
<id column="mid" property="mid"/>
<result column="mname" property="mname"/>
<!-- 通过select属性递归调用selectMenuByParentId查询,并将上一次找到的mid作为本次的pid动态参数,这样递归后就可以遍历所有的子菜单 -->
<collection property="menus" ofType="Menu" select="selectMenuByParentId" column="mid"></collection>
</resultMap>
<select id="selectMenuByParentId" resultMap="menuMapper">
select mid,mname,pid from menu where pid=#{xxx}
</select>
找出父菜单及其子菜单:
<select id="selectMenuByParentId" resultMap="menuMapper">
select mid,mname,pid from menu where pid=#{xxx}
</select>
<resultMap type="Menu" id="menuMapperByMid">
<id column="mid" property="mid"/>
<result column="mname" property="mname"/>
<!-- 通过select属性递归调用selectMenuByParentId查询,并将上一次找到的mid作为本次的pid动态参数,这样递归后就可以遍历所有的子菜单 -->
<collection property="menus" ofType="Menu" select="selectMenuByParentId" column="mid"></collection>
</resultMap>
<select id="selectMenuByMId" resultMap="menuMapperByMid">
select mid,mname,pid from menu where mid=#{xxx}
</select>
B.以多对一的方式处理:使用递归处理,将找到的当前菜单的pid作为下一次查询的mid的,比如确定某一个文件的位置。