Mybatis一对多,多对一关系实现(2)
上一章我们说完了多对一关联关系的实现,这里我们开始写一对多关联关系的实现。
步骤还是相同先写实体类,写基本框架。数据库表的话还是用的上一章中的表。
1).Student.java
package com.nf.domain;
import lombok.Data;
@Data//取代GET,SET,ToString,有参,无参构造
public class Student {
private int id;
private String name;
}
2).Teacher.java
package com.nf.domain;
import lombok.Data;
@Data //取代GET,SET,ToString,有参,无参构造
public class Teacher {
private int id;
private String name;
}
写好两个实体类之后我们开始写接口,不管两个接口有没有用我们都写上,形成一个好习惯。
3).TeacherMapper.java
package com.nf.mapper;
public interface StudentMapper {
}
4).StudentMapper.java
package com.nf.mapper;
public interface TeacherMapper {
}
写好了接口那接下来就需要编写接口所需要的xml文件。
5).TeacherMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nf.mapper.StudentMapper">
</mapper>
6).StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nf.mapper.TeacherMapper">
</mapper>
这里我们开始写一对多关系的实现,那么一对多关系的实现就是一名老师对应多名学生,那我们就在老师的实体类中定义一个学生列表,因为一个老师对应多名学生。所以用列表表示多名学生
Teacher.java
//一个老师可以拥有多个学生‘
private List<Student> students;
写完了实体类我们就开始写接口,因为我们意思是一名老师对应多名学生,所以我们应该根据老师的id查询这个id下有多少学生与之关联。
TeacherMapper.java
//获取指定老师下的所有学生及其老师信息;
Teacher getTeacher(@Param("tid") int id);
写完了接口我们就开始写接口对应的mapper.xml,我们先根据查询嵌套处理sql语句进行查询,这里我们就用到了collection这个标签来处理学生集合。还是老样子用resultMap去写。
TeacherMapper.xml
<select id="getTeacher" resultMap="Teacher|Student">
select s.id sid,s.name sname,t.name tname,t.id tid
from student s,teacher t
where s.tid = t.id and t.id=#{tid}
</select>
<resultMap id="Teacher|Student" type="com.cjn.domain.Teacher">
<result property="id" column="tid"></result>
<result property="name" column="tname"></result>
<!--复杂属性我们需要单独处理,对象的话要用assaciation ,集合的话要用collection
java type=""用于指定属性的类型
集合中的泛型信息,我们使用ofType获取
-->
<collection property="students" ofType="com.cjn.domain.Student">
<result property="id" column="sid"></result>
<result property="name" column="sname"></result>
<result property="tid" column="tid"></result>
</collection>
</resultMap>
接下来我们开始测试:
@Test
public void getTeacher(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teachers = mapper.getTeacher(1);
if(teachers != null){
System.out.println(teachers);
}else {
System.out.println("无用户信息");
}
sqlSession.close();
}
测试结果:
接下来我们用根据结果进行嵌套处理,也是用到了分步查询。
先定义接口:(跟上面的一样所以我们就直接加了个1换个名字)
TeacherMapper.java
Teacher getTeacher1(@Param("tid") int id);
写好了接口开始写接口对应的xml文件:
TeacherMapper.xml
我们先根据id查询老师,在根据该id查询学生
<!--第二种方式-->
<!--javatype 用来指定实体类型中属性的类型--> <!--oftype用来指定映射到list或者集合中的实体类型,泛型中的约束类型-->
<select id="getTeacher1" resultMap="Teacher||Student">
select * from teacher where id = #{tid}
</select>
<resultMap id="Teacher||Student" type="com.cjn.domain.Teacher">
<collection property="students" javaType="ArrayList" ofType="com.cjn.domain.Student" select="getStudentByTeacherID" column="id" ></collection>
</resultMap>
<select id="getStudentByTeacherID" resultType="com.cjn.domain.Student">
select *from student where tid = #{tid}
</select>
开始测试:
@Test
public void getTeacher1(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teachers = mapper.getTeacher1(1);
if(teachers != null){
System.out.println(teachers);
//System.out.println(teachers.getId());
}else {
System.out.println("无用户信息");
}
sqlSession.close();
}
测试结果:
接下来我们讲一种懒加载模式,上面分布查询他会执行两个sql语句,那如果我们只想执行一个,那该如何实现?接下来就用到了我们的懒加载模式
懒加载一共有两种配置方式:
懒加载第一种配置方式就是局部配置
就是在xml文件中的collection中加入fetchType=“lazy”
例如:
<!--第二种方式-->
<!--javatype 用来指定实体类型中属性的类型-->
<!--oftype用来指定映射到list或者集合中的实体类型,泛型中的约束类型-->
<!--懒加载局部配置只在collection标签中添加fetchType="lazy"-->
<select id="getTeacher1" resultMap="Teacher||Student">
select * from teacher where id = #{tid}
</select>
<resultMap id="Teacher||Student" type="com.cjn.domain.Teacher">
<!--懒加载局部配置在下标签中加入fetchType="lazy"-->
<collection property="students" javaType="ArrayList" ofType="com.cjn.domain.Student" select="getStudentByTeacherID" column="id" fetchType="lazy" ></collection>
</resultMap>
<select id="getStudentByTeacherID" resultType="com.cjn.domain.Student">
select *from student where tid = #{tid}
</select>
</mapper>
那么我们查询测试一下(只获取老师的id):
@Test
public void getTeacher1(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teachers = mapper.getTeacher1(1);
if(teachers != null){
//System.out.println(teachers);
System.out.println(teachers.getId());
}else {
System.out.println("无用户信息");
}
sqlSession.close();
}
测试结果:
懒加载的第二种配置就是全局配置
如果嫌局部配置太过于麻烦,那我们就可以进行全局配置,全局配置就是在mybtais-config.xml中加入
<!--懒加载全部配置-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
那在TeacherMapper.xml中的fetchType="lazy"就可以删除了
下面我们还是用获取老师的id进行测试:
@Test
public void getTeacher1(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teachers = mapper.getTeacher1(1);
if(teachers != null){
//System.out.println(teachers);
System.out.println(teachers.getId());
}else {
System.out.println("无用户信息");
}
sqlSession.close();
}
测试结果:
好了,到这里Mybatis一对多,多对一关系实现就结束了(以上均是个人笔记,如有错误欢迎指正,谢谢)