一对多
问题的引出
假设我们要去查一个班级的信息,包括班级的名字,班号以及这个班级的的所有学生。这就是一对多,一个班级对应多个学生。这个需求的话我们在mysql中查询的语句如下:
1. SELECT * FROM t_clazz 2. LEFT JOIN t_student 3. ON t_clazz.`cid`=t_student.`cid` 4. WHERE t_clazz.`cid`=2101
查询结果:
这个时候就要在Clazz类中添加List<Student> stus 属性。
1. @Data 2. public class Clazz { 3. private Long cid; 4. private String cname; 5. List<Student> stus; 6. }
collection处理
ClazzMappe编写r接口
1. /** 2. * 根据班级编号查询班级信息。同时班级中所有的学生信息也要查询。 3. * @param cid 4. * @return 5. */ 6. Clazz selectClazzAndStusByCid(@Param("cid") Long cid);
ClazztMapper.xml中实现
1. <resultMap id="clazzResultMap" type="com.study.pojo.Clazz"> 2. <id property="cid" column="cid"></id> 3. <result property="cname" column="cname"></result> 4. <collection property="stus" ofType="com.study.pojo.Student"> 5. <id property="sid" column="sid"></id> 6. <result property="sname" column="sname"></result> 7. </collection> 8. </resultMap> 9. <select id="selectClazzAndStusByCid" resultMap="clazzResultMap"> 10. SELECT * FROM t_clazz 11. LEFT JOIN t_student 12. ON t_clazz.`cid`=t_student.`cid` 13. WHERE t_clazz.`cid`=#{cid} 14. </select>
测试代码
1. @Test 2. public void test01(){ 3. SqlSession session = SqlSessionUtil.openSession(); 4. ClazzMapper mapper = session.getMapper(ClazzMapper.class); 5. Clazz clazz = mapper.selectClazzAndStusByCid(2101L); 6. System.out.println(clazz); 7. }
分步查询
这个过程同样可以分为俩步:
第一步根据cid在班级表中查询cname
第二步根据cid在学生表中查询每个学生的sid sname
具体实施
ClazzMapper.xml中修改
1. <resultMap id="clazzResultMap" type="com.study.pojo.Clazz"> 2. <id property="cid" column="cid"></id> 3. <result property="cname" column="cname"></result> 4. <collection property="stus" 5. select="com.study.mapper.StudentMapper.selectByCid" 6. column="cid"> 7. </collection> 8. </resultMap> 9. 10. <select id="selectClazzAndStusByCid" resultMap="clazzResultMap"> 11. select * from t_clazz where cid=#{cid} 12. </select>
StudentMapper接口
1. /** 2. * 根据班级编号获取所有的学生。 3. * @param cid 4. * @return 5. */ 6. List<Student> selectByCid(@Param("cid") Long cid);
StudentMapper.xml
1. <select id="selectByCid" resultType="com.study.pojo.Student"> 2. select * from t_student where cid=#{cid} 3. </select>
延迟加载解读
什么是延迟加载?
延迟加载也称为懒加载、惰性加载,使用延迟加载可以提高程序的运行效率,针对数据持久层的操作,在某些特定查询的情况下去访问特定的数据库,在其他情况下可以不访问某些数据表,尽量减少 SQL 的执行,从而达到提高速度的目的,是对数据库操作的一种优化。
说明:延迟加载只存在于分步查询
在mybatis中怎么开启延迟加载呢?
局部开启:
在association或者collection标签中添加fetchType="lazy"。
注意:默认是没有开启延迟加载的,而且这种在association或者collection中设置
延迟加载的方式,是局部的设置,只针对当前association或者collection所关联的SQL语句起作用。
测试代码
1. @Test 2. public void test01(){ 3. SqlSession session = SqlSessionUtil.openSession(); 4. ClazzMapper mapper = session.getMapper(ClazzMapper.class); 5. Clazz clazz = mapper.selectClazzAndStusByCid(2101L); 6. //没有用到stus属性 7. System.out.println(clazz.getCid()); 8. System.out.println(clazz.getCname()); 9. }
运行结果
我们可以很明显的看到延迟加载以后,只执行了一条sql语句
全局开启:
可以在mybatis核心配置文件中开启全局设置
在开发中大部分情况是需要用到延迟加载的,所以建议开启全局的延迟加载机制
在mybatis核心配置文件中添加<setting name="lazyLoadingEnabled" value="true"/>
实际中的开发模式:
把全局延迟加载打开。
如果某一步不需要延迟加载,设置fetchType="eager"。