package domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Classes {
private Integer id;
private String name;
private String classNum;
private List<Student> studentList;
@Override
public String toString() {
return "Classes{" +
"ClassName='" + name + '\'' +
", classNum='" + classNum + '\'' +
'}';
}
}
package domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Integer id;
private String studentNum;
private String classNum;
private String name;
private String phone;
private String email;
private Byte sex;
private Date createTime;
private Date modifyTime;
private Map<String,Double> scoreMap;//学科-成绩
private Classes classes;
@Override
public String toString() {
return "Student{" +
"studentNum='" + studentNum + '\'' +
", classNum='" + classNum + '\'' +
", name='" + name + '\'' +
", phone='" + phone + '\'' +
", email='" + email + '\'' +
", sex=" + sex +
", createTime=" + createTime +
", modifyTime=" + modifyTime +
'}';
}
}
package domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Score {
private Integer id;
private String studentNum;
private Double score;
private String subjectName;
private Student student;
@Override
public String toString() {
return "Score{" +
"studentNum='" + studentNum + '\'' +
", score=" + score +
", subjectName='" + subjectName + '\'' +
'}';
}
}
resultMap中可以设置result的级联属性(例如student.name),示例代码如下
<sql id="MyColumnList">
score.id,score.student_num,score.score,score.subject_name,
student.name,student.phone,student.email,student.sex,student.create_time,student.modify_time,student.class_num
sql>
<resultMap id="MyResMap1" type="domain.Score">
<id column="id" property="id"/>
<result column="student_num" property="studentNum"/>
<result column="score" property="score"/>
<result column="subject_name" property="subjectName"/>
<result column="student_num" property="student.studentNum"/>
<result column="name" property="student.name"/>
<result column="phone" property="student.phone"/>
<result column="email" property="student.email"/>
<result column="sex" property="student.sex"/>
<result column="class_num" property="student.classNum"/>
<result column="create_time" property="student.createTime"/>
<result column="modify_time" property="student.modifyTime"/>
resultMap>
<select id="cascadeSelect" resultMap="MyResMap1">
select
<include refid="MyColumnList"/>
from mybatis.score
left join mybatis.student
on score.student_num=student.student_num
select>
association标签主要用来封装返回结果中的单个对象
其实可以理解为将级联属性换了一种更加简便的方式进行封装
示例代码如下
<sql id="MyColumnList">
score.id,score.student_num,score.score,score.subject_name,
student.name,student.phone,student.email,student.sex,student.create_time,student.modify_time,student.class_num
sql>
<resultMap id="MyResMap2" type="domain.Score">
<id column="id" property="id"/>
<result column="student_num" property="studentNum"/>
<result column="score" property="score"/>
<result column="subject_name" property="subjectName"/>
<association property="student" javaType="domain.Student">
<result column="student_num" property="studentNum"/>
<result column="name" property="name"/>
<result column="phone" property="phone"/>
<result column="email" property="email"/>
<result column="sex" property="sex"/>
<result column="class_num" property="classNum"/>
<result column="create_time" property="createTime"/>
<result column="modify_time" property="modifyTime"/>
association>
resultMap>
<select id="assoSelect" resultMap="MyResMap2">
select
<include refid="MyColumnList"/>
from mybatis.score
left join mybatis.student
on score.student_num=student.student_num
select>
应用场景如下:我在查询学生信息的时候,需要先将学生的基本信息查询出来,在根据基本信息中的班级编号查询出班级信息,然后将班级信息封装到学生对象中的classes属性中
与全部直接查询出来在进行封装(利用级联属性或者association标签)区别在于,分步查询不需要把所有需要的数据放在一条sql语句中查询
示例代码如下:
<select id="getByStudentNum" resultMap="MyResMap2">
select *
from mybatis.student
where student_num = #{studentNum};
select>
<resultMap id="MyResMap2" type="domain.Student">
<id column="id" property="id"/>
<result column="student_num" property="studentNum"/>
<result column="name" property="name"/>
<result column="phone" property="phone"/>
<result column="email" property="email"/>
<result column="sex" property="sex"/>
<result column="modify_time" property="modifyTime"/>
<result column="create_time" property="createTime"/>
<result column="class_num" property="classNum"/>
<association property="classes"
javaType="domain.Classes"
select="dao.ClassesDao.getByClassNum"
column="class_num"/>
resultMap>
应用场景如下:在查询班级信息的时候,我需要获取到该班级的所有同学信息,再将所有的同学信息封装至班级对象中的studentList属性中
resultMap如下:
<sql id="MyColumnList">
classes.id AS classes_id, classes.name AS classes_name, classes.class_num,
student.id AS student_id, student.student_num, student.name AS student_name,
student.phone, student.email, student.sex, student.create_time,
student.modify_time
sql>
<resultMap id="MyResMap2" type="domain.Classes">
<id column="classes_id" property="id"/>
<result column="classes_name" property="name"/>
<result column="class_num" property="classNum"/>
<collection property="studentList" ofType="domain.Student">
<id column="student_id" property="id"/>
<result column="student_num" property="studentNum"/>
<result column="student_name" property="name"/>
<result column="phone" property="phone"/>
<result column="email" property="email"/>
<result column="sex" property="sex"/>
<result column="modify_time" property="modifyTime"/>
<result column="create_time" property="createTime"/>
<result column="class_num" property="classNum"/>
collection>
resultMap>
<select id="getByClassNumPlus" resultMap="MyResMap2">
select
<include refid="MyColumnList"/>
from mybatis.classes
left join mybatis.student
on classes.class_num = student.class_num
where classes.class_num=#{classNum}
select>
resultMap如下:
<select id="getByClassNumPlusStep" resultMap="MyResMap3">
select * from mybatis.classes where class_num = #{classNum}
select>
<resultMap id="MyResMap3" type="domain.Classes">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="class_num" property="classNum"/>
<collection property="studentList"
select="dao.StudentDao.getStusByClassNum"
column="class_num">
collection>
resultMap>
延迟加载只需要在mybatis全局配置文件中设置好setting就可以了
只有在用到某个信息的时候才查询该信息
<settings>
<setting name="logImpl" value="LOG4J"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
settings>
实例如下:
测试代码块如下
@Test
public void test01(){
Classes wl171 = classesDao.getByClassNumPlusStep("WL171");
System.out.println(wl171.getName());
for (Student student : wl171.getStudentList()){
System.out.println(student);
}
}
在不用延迟加载的时候,sql语句执行如下:
一次性执行所有sql语句
在使用了延迟加载的时候,sql语句执行如下
因为==wl171.getName()这句代码不会用到查询学生数据库的代码,所有先执行第一条sql语句
在打印了wl171.getName()==之后,又打印了学生列表,这时候又再执行查询学生列表的sql语句
需要注意的是,延迟加载需要跟**分步查询**一起使用