MyBatis笔记:xml映射文件
xml映射文件指的是配置SQL的xml配置文件,它配置了操作实体类的接口方法与对应SQL的映射关系,本文只是简单记了一点学习笔记,想要了解更多,可以参考MyBatis中文文档 https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
1. parameterType配置
parameterType表示id属性所代表的方法需要传入的参数的类型。
int
数字类型。
类
当parameterType的值是一个类时,需要指定该类的完整路径(对maven项目来说的,就是相对于 src/main/java
的路径),表示传入的参数类型为该类。直接指定parameterType为类时有一个缺点:为了传递这个类的实例,不得不new一个实例出来,如果实例化这个类需要指定许多SQL中用不到的属性,代码就会变得非常麻烦,这时候可以考虑将parameterType指定为map类型。
map
当parameterType的值是一个map时,表示传入的参数是map类型,此时SQL中的 #{}
只需要填入map中的key即可。如果传入的实例在实例化时需要多个SQL用不到的参数,或者需要传递多个参数时,可以考虑使用map类型。
2. resultMap配置
mapper.xml映射文件中数据库字段名和实体类的属性名的映射关系是根据查询结果来进行映射的,如果结果集中字段名和属性名一致,则映射成功, 不一致则会给对应的对象属性赋予null值。当数据库中的字段名和实体类的属性名不一致时,有两种处理方式:一种是使用 as
语法让查询结果的字段名与实体类的属性名保持一致,另一种是配置resultMap标签。具体见示例:
第一种方式:使用as
实体类的属性:id,name,password
public class User {
private int id;
private String name;
private String password;
}
数据库中的字段为:id,name,pwd。此时可以使用as对pwd的查询结果起一个别名password,与实体类的属性名保持一致。
<mapper namespace="com.mb.dao.UserMapper">
<select id="getUserList" resultType="com.mb.pojo.User">
select id,name,pwd as password from mybatis.user;
</select>
</mapper>
第二种方式:配置resultMap
使用resultMap进行映射,见如下示例:select标签的resultMap属性值就是resultMap标签的id属性值,resultMap标签的type属性值为对应实体类,result标签中column为数据库字段名,property为实体类的属性名。注意,如果字段名和属性名是一样的,则可以不用配置。
<mapper namespace="com.mb.dao.UserMapper">
<resultMap id="UserMap" type="com.mb.pojo.User">
<result column="pwd" property="password"/>
</resultMap>
<select id="getUserList" resultMap="UserMap">
select id, name, pwd from mybatis.user;
</select>
</mapper>
3. 多对一
多对一关系的配置需要用到 association
标签, association
标签表示当前对象关联的另一个对象,在实体类中体现为对象的属性是对象类型。以老师和和学生的关系举例,每个学生都有对应的老师,实体类和xml配置如下。
学生和老师的实体类如下:
package com.mb.pojo;
import lombok.Data;
/* lombok是一个插件,可以使用注解的方式帮助程序员免于编写繁琐的get、set等方法
使用之前需要现在pom.xml中进行配置依赖(maven)和IDEA中安装lombok插件(搜索不到就点击show all直接在列表中找),如:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
*/
@Data
public class Student {
private int id;
private String name;
// 学生对应的老师
private Teacher teacher;
}
package com.mb.pojo;
import lombok.Data;
@Data
public class Teacher {
private int id;
private String name;
}
实体类对应的Mapper接口我就不写了,直接展示xml映射文件的配置内容(使用方式和解释见xml注释):
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mb.dao.StudentMapper">
<!-- 配置方式一:通过结果集映射的方式进行查询 -->
<select id="getStudentList" resultMap="StudentTeacherMap">
select s.id sid, s.name sname, t.name tname
from student s, teacher t
where s.tid = t.id;
</select>
<resultMap id="StudentTeacherMap" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<!-- association表示关联对象:javaType表示关联对象的java类型,
因为关联对象只有一个,而不是集合,所以直接配置关联对象对应属性即可-->
<association property="teacher" javaType="Teacher">
<!-- 因为结果集中没有teacher的id,所以这里就不用配置id了 -->
<result property="name" column="tname"/>
</association>
</resultMap>
<!-- 配置方式二:通过子查询的方式进行查询,这种方式的缺点是,因为每个查询都要单独配置,所以不能直接使用完整的SQL去调试 -->
<select id="getStudentList2" resultMap="StudentTeacherMap2">
select * from student;
</select>
<select id="getTeacherById" resultType="Teacher">
select * from teacher where id = #{tid};
</select>
<resultMap id="StudentTeacherMap2" type="Student">
<result property="id" column="id"/>
<result property="name" column="id"/>
<!-- association表示关联对象: column表示要传入子查询的字段,javaType表示关联对象的java类型,
select表示子查询,这里表示将查询到的column="tid"传入子查询select="getTeacherById"作为参数#{tid}的值进行查询 -->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacherById"/>
</resultMap>
</mapper>
4. 一对多
一对多关系的配置需要用到 collection
标签, collection
标签表示对象的集合,在实体类中体现为对象的属性是集合类型。以老师和学生的关系举例,一个老师有多个学生,实体类和xml配置如下。
学生和老师的实体类如下:
package com.mb.pojo;
import lombok.Data;
/* lombok是一个插件,可以使用注解的方式帮助程序员免于编写繁琐的get、set等方法
使用之前需要现在pom.xml中进行配置依赖(maven),如:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
*/
@Data
public class Student {
private int id;
private String name;
// 学生对应的老师id
private int tid;
}
package com.mb.pojo;
import lombok.Data;
import java.util.List;
@Data
public class Teacher {
private int id;
private String name;
// 老师拥有的学生
private List<Student> studentList;
}
实体类对应的Mapper接口我就不写了,直接展示xml映射文件的配置内容(使用方式和解释见xml注释):
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mb.dao.TeacherMapper">
<!-- 配置方式一:按照查询结果进行嵌套配置(嵌套查询) -->
<select id="getTeacherById" resultMap="TeacherStudentMap">
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="TeacherStudentMap" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!-- collection表示集合:ofType表示集合中元素的类型 -->
<collection property="studentList" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
<!-- 配置方式二:按照子查询方式,这种方式的缺点是,因为每个查询都要单独配置,所以不能直接使用完整的SQL去调试 -->
<select id="getTeacherById2" resultMap="TeacherStudentMap2">
select * from teacher where id = #{tid};
</select>
<select id="getStudentListByTid" resultType="Student">
select * from student where tid = #{tid};
</select>
<resultMap id="TeacherStudentMap2" type="Teacher">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!-- collection表示集合:ofType表示集合中元素的类型,ArrayList表示java中的集合类型,
column则是用于传入子查询的参数,它的值是父查询结果的字段名,这里表示会将父查询(type="Teacher")
结果中的id列的值(column="id")传入子查询(select="getStudentListByTid")作为参数#{tid}的值进行查询 -->
<collection property="studentList" column="id" javaType="ArrayList" ofType="Student" select="getStudentListByTid">
<!-- result中如果property和column是一样的,不用配置也可以,
我这里只是为了更清晰地展示两个查询之间的关系-->
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
</mapper>