多表查询
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 Menu menu;// 一方
...
}
III.创建MenuDao
IV.创建映射文件
<resultMap type="Menu" id="menuMapperByMid">
<id column="mid" property="mid"/>
<result column="mname" property="mname"/>
<!-- 通过select属性递归调用selectMenuByMid查询,并将上一次找到的pid作为本次的mid动态参数,这样递归后就可以遍历所有的父菜单 -->
<association property="menu" javaType="Menu" select="selectMenuByMid" column="pid"></association>
</resultMap>
<select id="selectMenuByMid" resultMap="menuMapperByMid">
select mid,mname,pid from menu where mid=#{xxx}
</select>
3.多对多关联关系:反应的数据库表中,会有一个中间 表,该表专门用于保存两张表的外键,反应到实体类中,两个实体类均持有对方的Set集合。
开发步骤:商家和供货商举例
(1)创建数据库表
(2)创建实体类
(3)创建映射文件
<resultMap type="Shop" id="shopMapper">
<id column="sid" property="sid"/>
<result column="sname" property="sname"/>
<collection property="suppliers" ofType="Supplier">
<id column="spid" property="spid"/>
<result column="spname" property="spname"/>
</collection>
</resultMap>
<select id="selectShopBySid" resultMap="shopMapper">
select * from shop s,supplier sp,middlemen m where s.sid=m.shop_id and sp.spid=m.sp_id and
s.sid=#{xxx}
</select>
三、延迟加载
1.延迟加载,也叫懒加载,对对象的查询采用延迟查询的策略,只会对有关联关系的关联对象有延迟加载的配置,对于主加载对象都是采用直接加载的策略。延迟加载可以减少数据库负担。
2.关联对象加载时机:注意:对于连接查询的关联关系对象,是将多表看作一张表来进行查询,所以该查询方式采用直接加载方式。
(1)直接加载:执行完对主加载对象的select 语句,马上执行对关联对象的select查询。
(2)侵入式延迟:当使用到主对象的详情时,就会发送对从对象(关联对象)的select语句。
(3)深度延迟:当使用到主对象的详情时,不会发送从对象的select语句,而在真正用到从对象的详情的时候才会发送从对象的select。
3.在主配置文件的<properties>和<typeAliases>之间配置
<!-- 对关联对象的延迟加载策略进行设置 -->
<settings>
<!-- 延迟加载的总开关:true:打开延迟,false:关闭延迟 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式加载的开关:true:侵入式延迟,false:深度延迟 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>