mybatis结果映射
resultMap
元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets
数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap
能够代替实现同等功能的长达数千行的代码。ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。
-
你已经见过简单映射语句的示例了,但并没有显式指定
resultMap
。比如:<select id="selectUsers" resultType="map"> select id, username, hashedPassword from some_table where id = #{id} </select>
上述语句只是简单地将所有的列映射到
HashMap
的键上,这由resultType
属性指定。虽然在大部分情况下都够用,但是 HashMap 不是一个很好的领域模型。你的程序更可能会使用 JavaBean 或 POJO(Plain Old Java Objects,普通老式 Java 对象)作为领域模型。MyBatis 对两者都提供了支持。看看下面这个 JavaBean:package com.someapp.model; public class User { private int id; private String username; private String hashedPassword; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getHashedPassword() { return hashedPassword; } public void setHashedPassword(String hashedPassword) { this.hashedPassword = hashedPassword; } }
<select id="selectUsers" resultType="com.someapp.model.User"> select id, username, hashedPassword from some_table where id = #{id} </select> <!--查询到的列名将会映射到上述javaBean中-->
基于 JavaBean 的规范,上面这个类有 3 个属性:id,username 和 hashedPassword。这些属性会对应到 select 语句中的列名。
这样的
ResultSet
可以被映射到JavaBean中 ,就像映射到HashMap
一样简单。
1、如果JavaBean中的属性名和列名不一致,我们该如何映射?
方法①:在 SELECT 语句中对列使用别名
<select id="selectUsers" resultType="User">
select
user_id as "id",
user_name as "userName",
hashed_password as "hashedPassword"
from some_table
where id = #{id}
</select>
如果列名和属性名没有精确匹配,可以在 SELECT 语句中对列使用别名(这是一个基本的 SQL 特性)来匹配。
方法②:引用外部resultMap
<resultMap id="xxx" type="User">
<id property="id" column="user_id" />
<!--property:JavaBean的属性名 || column:数据库中的列名-->
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
<select id="selectUsers" resultMap="xxx">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
2、高级结果映射
association :用于对象
collection :用户集合
- 多对一
关联的Select嵌套处理:
接口:
List<Student> getStudentList2();
<select id="getStudentList2" resultMap="StudentList2">
select * from student
</select>
<resultMap id="StudentList2" type="com.xu.pojo.Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="tid" column="tid" javaType="com.xu.pojo.Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="com.xu.pojo.Teacher">
select * from teacher where id = #{tid}
</select>
<!--先查询全部学生做映射,在做到该属性的时候。通过关联的外建在内部再次查询,类似Sql子查询-->s
关联嵌套结果映射:
接口:
List<Student> getStudentList1();
<select id="getStudentList1" resultMap="StudentList1">
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="StudentList1" type="com.xu.pojo.Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="tid" javaType="com.xu.pojo.Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
</association>
</resultMap
- 一对多
集合的Select嵌套处理:
接口:
//查询指定老师下的所有学生
Teacher getIdTeacherByStudent2(@Param("tid") int id);
<select id="getIdTeacherByStudent2" resultMap="xxx2">
select * from teacher
</select>
<resultMap id="xxx2" type="com.xu.pojo.Teacher">
<collection property="student" javaType="ArrayList" ofType="com.xu.pojo.Student" column="id" select="ss"/>
</resultMap>
<select id="ss" resultType="com.xu.pojo.Student">
select * from student where tid=#{tid}
</select>
集合的嵌套结果映射:
接口:
//查询指定老师下的所有学生
Teacher getIdTeacherByStudent(@Param("tid") int id);
<select id="getIdTeacherByStudent" resultMap="TeacherStudent">
select s.id sid,s.name sname,t.id tid,t.name tname
from student s ,teacher t
where s.tid=t.id and t.id=#{tid}
</select>
<resultMap id="TeacherStudent" type="com.xu.pojo.Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="student" ofType="com.xu.pojo.Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>