MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。
resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的数千行代码。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
1、constructor - 用于在实例化类时,注入结果到构造方法中
idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
arg - 将被注入到构造方法的一个普通结果
2、id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
3、result – 注入到字段或 JavaBean 属性的普通结果
4、association – 一个复杂类型的关联;许多结果将包装成这种类型
嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用
5、collection – 一个复杂类型的集合
嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用
6、discriminator – 使用结果值来决定使用哪个 resultMap
case – 基于某些值的结果映射
嵌套结果映射 – case 也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射
在一对多或者是多对一中我们都不可避免要使用 resultMap这个元素和标签,上面我们列出了resultMap的所有属性,但是经常用的就只有4个(id,result,association,collection)。
一对多:顾名思义一个对象对应多个对象,例如一个老师教多个学生,也就是说这个老师对象包含了多个学生对象。因此在我们编写实体类时应该要考虑到如何把多个学生对象作为老师对象的属性,我们很快就可以想到使用集合来解决这一问题,把所用学生对象都存放到一个集合当中,然后让这个集合老师对象的一个属性。
Teacher对象:
package com.my.pojo;
import java.util.List;
public class Teacher {
private int id;
private String name;
private List<Student> students;
@Override
public String toString() {
return "Teacher{" +
"id=" + id +
", name='" + name + '\'' +
", students=" + students +
'}';
}
public Teacher(int id, String name, List<Student> students) {
this.id = id;
this.name = name;
this.students = students;
}
public Teacher() {
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Student对象:
package com.my.pojo;
public class Student {
private int id;
private String name;
private int tid;
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", tid=" + tid +
'}';
}
public Student(int id, String name, int tid) {
this.id = id;
this.name = name;
this.tid = tid;
}
public Student() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getTid() {
return tid;
}
public void setTid(int tid) {
this.tid = tid;
}
}
<!--一对多,方法一:结果映射-->
<select id="teacher" resultMap="teacherstudent" >
SELECT s.id sid,s.name sname,t.id tid,t.name tname
FROM student s,teacher t WHERE t.id = #{id} AND t.id = s.tid
</select>
<resultMap id="teacherstudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" ofType="Student" >
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
这种方法的核心就是SQL语句的编写和ResultMap的结果集映射。
<select id="teacher2" resultMap="teacherstudent2">
select * from teacher where id = #{id}
</select>
<resultMap id="teacherstudent2" type="Teacher">
<collection property="students" javaType="ArrayList" column="id" ofType="Student" select="student"/>
</resultMap>
<select id="student" resultType="Student">
select * from student where tid = #{id}
</select>
多对一与一对多大致上是差不多的同样有与一对多一样的两种方法:嵌套结果映射和嵌套 Select 查询。大部分1知识点是一样的这里就不重复了。
多对一顾名思义就是多个对象都与一个对象有关系例如:多个学生对象都是由一个老师对象教的。因此我们在创建学生类时应该要考虑到如何体现这个学生类关联一个老师对象,所以我们可以把这个老师对象作为学生类的一个属性。
Teacher对象:
package com.my.pojo;
public class Teacher {
private int id;
private String name;
@Override
public String toString() {
return "Teacher{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public Teacher() {
}
public Teacher(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Student对象:
package com.my.pojo;
public class Student {
private int id;
private String name;
private Teacher teacher;
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", teacher=" + teacher.toString() +
'}';
}
public Student() {
}
public Student(int id, String name, Teacher teacher) {
this.id = id;
this.name = name;
this.teacher = teacher;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
<select id="student" resultMap="studentteacher">
SELECT s.id sid,s.name sname,t.id tid,t.name tname
FROM student s,teacher t WHERE s.tid = t.id
</select>
<resultMap id="studentteacher" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" column="tid" javaType="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
</association>
</resultMap>
<select id="student2" resultMap="studentteacher2">
select * from student
</select>
<resultMap id="studentteacher2" type="Student">
<association property="teacher" column="tid" javaType="Teacher" select="teacher2"/>
</resultMap>
<select id="teacher2" resultType="Teacher">
select * from teacher where id = #{tid}
</select>
结合前面的一对多进行理解,不再重复。
总的来说Mybatis的一对多与多对一并不难理解,只要我们理好每个对象之间的关系就会很容易了。