xml映射解析
- 1. 结果映射
- 1.1 简单的结果映射
- 2. 高级结果映射
- 2.1 多对一
- 方法1:关联的嵌套 Select 查询
- 方法2:关联的嵌套结果映射
- 2.2 一对多
- 方法1:集合的嵌套结果映射
- 方法2:集合的嵌套 Select 查询
1. 结果映射
用于实体类(user)内定义的属性名与字段的属性名不同的情况。
1.1 简单的结果映射
当将实体类中的某一属性设置的和数据库字段属性不同的情况下,实现查询时该字段查询的值为0或NULL。(但是当实体类中此属性的set方法名称正确时结果就是正确的)
public int getPassword() {
return password;
}
public void setPwd(int password) {
this.password = password;
}
解决方法;
- 在sql语句中为不一样的字段设置与实体类中属性名称相同的别名。
select id,name,pwd as password from mybatis.user where id = #{id}
- 使用 结果集映射 resultMap
resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。
ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
我们在前面使用时用resultType设置返回值的类型,当其为某个对象(user)时,MyBatis 会在幕后自动创建一个 ResultMap,再根据属性名来映射列到 对象 的属性上。(如果列名和属性名不能匹配上,可以在 SELECT 语句中设置列别名来完成匹配。)
就是 ResultMap 的优秀之处——你完全可以不用显式地配置它们。
显式使用外部的 resultMap:
column:数据库的列(字段)
property:属性(实体类的属性)
<resultMap id="usermap" type="User">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result column="pwd" property="password" />
</resultMap>
<select id="getuserbyid" parameterType="int" resultMap="usermap">
select id,name,pwd from mybatis.user where id = #{id}
</select>
2. 高级结果映射
实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的数千行代码。resultmap的子标签:
resultmap标签的属性:
result和id属性:
2.1 多对一
多对一使用关联 association。
关联(association)属性:
列如:多个学生关联一个老师
public interface StudentMapper {
List<Student> getNamebyTeacher();
}
方法1:关联的嵌套 Select 查询
相当于子查询(由两条sql语句组成,并且是一个可独立执行的sql语句)
- 查询结果为老师对象
实体类:
public class Student {
private int id;
private String name;
private Teacher teacher;
...
association的select属性:会从column属性指定的列中检索数据,作为参数传递给目标select语句。
在下面的代码中就是将搜索到的tid值传入到 teachermapper 的 sql语句中去。
<mapper namespace="com.wu.dao.StudentMapper">
<select id="getNamebyTeacher" resultMap="studentmap">
select * from student
</select>
<resultMap id="studentmap" type="com.wu.pojo.Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" column="tid" javaType="com.wu.pojo.Teacher" select="TeacherMapper"/>
</resultMap>
<select id="TeacherMapper" resultType="teacher">
select * from teacher where id=#{id}
</select>
</mapper>
结果:
- 查询结果为老师姓名
实体类:
public class Student {
private int id;
private String name;
private String teacherName;
...
<mapper namespace="com.wu.dao.StudentMapper">
<select id="getNamebyTeacher" resultMap="studentmap">
select * from student
</select>
<resultMap id="studentmap" type="student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacherName" column="tid" javaType="String" select="TeacherMap"/>
</resultMap>
<select id="TeacherMap" resultType="String">
select name from teacher where id=#{id}
</select>
</mapper>
结果:
注意:每个标签后的type属性内应该是全类名,只有设置在配置文件内设置类型别名后才是简单的类名。忘记设置会报错。
方法2:关联的嵌套结果映射
相当于连表查询:
select s.id sid, sname, tname
from student as s ,teacher as t
where s.tid=;
<select id="getNamebyTeacher" resultMap="studentmap">
select s.id sid, sname, tname from student as s ,teacher as t where s.tid=;
</select>
<resultMap id="studentmap" type="student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacherName" javaType="String">
<result property="tid" column="tname"/>
</association>
</resultMap>
相当于
<resultMap id="studentmap" type="student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacherName" javaType="String" resultMap="teachernamemap"/>
</resultMap>
<resultMap id="teachernamemap" type="String">
<result property="tid" column="tname"/>
</resultMap>
2.2 一对多
一对多使用集合collection
例如:一个老师拥有多个学生
需求:输出老师信息和他教的学生信息,此时的学生信息就是由List集合存储的。
方法1:集合的嵌套结果映射
public interface TeacherMapper {
Teacher getteacher(@Param("tid") int id);
}
public class Teacher {
private int id;
private String name;
private List<Student> students;
<mapper namespace="com.wu.dao.TeacherMapper">
<select id="getteacher" resultMap="teachermap">
select tid, tname,s.id sid, sname
from student s,teacher t
where s.tid = and = #{tid}
</select>
<resultMap id="teachermap" type="teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" ofType="student" javaType="ArrayList">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
</collection>
</resultMap>
</mapper>
注:一个新的 “ofType” 属性。这个属性非常重要,它用来将 实体类(或字段)属性的类型和集合存储的类型区分开来。
<collection property="students" ofType="student" javaType="ArrayList">
读作: “students 是一个存储 student 的 ArrayList 集合”
在一般情况下,MyBatis 可以推断 javaType 属性,因此并不需要填写。所以很多时候你可以简略成:
<collection property="students" ofType="student">
输出结果:
方法2:集合的嵌套 Select 查询
关键是 teacher 的 id 与 student 的 tid 相对应。
<select id="getteacher" resultMap="teachermap">
select id,name from teacher where id = #{tid}
</select>
<resultMap id="teachermap" type="teacher">
<result property="id" column="id"/>
<result property="name" column="name"/>
<collection property="students" ofType="student" javaType="ArrayList" column="id" select="studentmap"/>
</resultMap>
<select id="studentmap" resultType="student">
select id,name from student where tid = #{tid}
</select>