Mbatis是一个ORM框架,可以用XML配置文件或注解映射SQL语句,映射文件是MyBatis框架的核心,本文主要讲述XML 映射文件的结构和使用方法。
一、SQL映射文件
SQL映射文件就是mapperxml配置文件,主要实现SQL语句的配置和映射,同时实现JAVA 的POJO对象与数据库中的表和字段进行映射联系的功能。
1、mapper.xml的结构
以student 数据表为例,具体结构可以参看专栏的相关文章,下面是创建的StudentMapper.xml示例,代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.weiz.example01.mapper.StudentMapper">
<resultMap id="BaseResultMap" type="org.weiz.example01.model.Student">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
</resultMap>
<select id="selectAll" resultMap="BaseResultMap">
SELECT * FROM student
</select>
<select id="selectOne" parameterType="Long" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM student
WHERE id= #{id}
</select>
<sql id="Base_Column_List">
id,name,sex,age
</sql>
<insert id="insert" parameterType="org.weiz.example01.model.Student">
insert into student (name,sex,age) values (#{name},#{sex},#{age})
</insert>
<update id="update" parameterType="org.weiz.example01.model.Student">
UPDATE student
SET
<if test="name !=null">name=#{name},</if>
<if test="sex !=null">sex=#{sex},</if>
age=#{age}
WHERE id=#{id}
</update>
<delete id="delete" parameterType="Long">
DELETE FROM student
WHERE id=#{id}
</delete>
<resultMap id="StudentAndClassMap" type="org.weiz.example01.model.Student">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
<!--association用户关系映射,查询单个完整对象-->
<association property="classes"
javaType="org.weiz.example01.model.Classes">
<id column="id" property="id" />
<result column="class_name" property="name" jdbcType="VARCHAR"/>
<result column="memo" property="memo" jdbcType="VARCHAR" />
</association>
</resultMap>
<select id="selectStudentAndClass" parameterType="Long"
resultMap="StudentAndClassMap">
SELECT
s.id,s.name,s.sex,s.age,s.class_id,c.name as class_name, c.memo
FROM student s left join classes c on s.class_id=c.id
WHERE s.id=#{id}
</select>
</mapper>
如上述示例所示,mapper.xml主要分为4 部分:
(1)mapper.xml的语法声明,声明MyBatis语法。
(2)通过namespace指明mapper.xml文件对应的Mapper接口。
(3)通过XML标签定义接口方法对应的SQL语句,id属性对应Mapper接口的方法,resultMap属性为返回值类型。
(4)<resultMap>标签定义返回的结果类型与数据库表结构的对应关系。
2、mapper.xml的标签
映射文件提供了一些非常实用的标签,标签和功能说明如下所示:
二、定义SQL语句
MyBatis提供了insert、delete 、select、 update四个标签定义SQL语句,以下简要介绍每个标签的用法。
1、select
Select是Mybatis的常用元素之一,简单查询如下所示:
<select id="selectOne" parameterType="Long" resultType="hashMap">
SELECT name,age FROM student WHERE id=#{id}
</select>
Select标签允许配置参数类型、返回值类型等属性,具体属性如下所示:
标签虽然有很多属性,但常用的是id、parametrerType、 resultType、 resultMap这四个属性。
2、insert
insert标签用于定义插入数据的SQL语句,例如:
<insert id="insert" parameterType="org.weiz.example01.model.Student">
INSERT INTO
student(id,name,sex,age)
VALUES
(#{id},#{name},#{sex},#{age})
</insert>
如数据表包含自动生成主键的字段,可以修改为如下所示:
<insert id="insert" useGenerateKeys="true" keyProperty="id"
parameterType="org.weiz.example01.model.Student">
INSERT INTO
student(name,sex,age)
VALUES
(#{name},#{sex},#{age})
</insert>
insert标签包含属性如表所示:
常用属性有id、parameterType、useGenerateKeys、keyProperty等
3、update
它主要映射更新语句,示例代码如下:
<update id="update" parameterType="org.weiz.example01.model.Student">
UPDATE student
SET
name=#{name},
sex=#{sex},
age=#{age}
WHERE id=#{id}
</update>
如果需要根据传入参数来动态判断是否进行修改,可以使用if标签动态生成SQL语句,示例代码如下:
<update id="update" parameterType="org.weiz.example01.model.Student">
UPDATE student
SET
<if test="name !=null">name=#{name},</if>
<if test="sex !=null">sex=#{sex},</if>
age=#{age}
WHERE id=#{id}
</update>
update标签包含的属性和insert标签基本一致。
4、delete
它用来映射删除语句,示例代码如下:
<delete id="delete" parameterType="Long">
DELETE FROM student
WHERE id=#{id}
</delete>
delete标签包含的属性如表所示:
delete标签除了少了useGenerateKeys keyProperty keyColumn三个属性之外,其余的和insert\ update标签一致。
三、结果映射
结果映射是MyBatis重要功能之一,简单的SQL查询,使用resultType属性自动将结果转换成Java数据类型,如果是复杂语句,可使用resultMap映射将查询结果转换成数据实体关系。
1、resultType
示例一:
<select id="selectOne" parameterType="Long"
resultType="org.weiz.exampleo01.model.Student">
SELECT *
FROM student
WHERE id= #{id}
</select>
通过设置resultType属性,MyBatis会自动把查询结果集转换为Student实体对象。如果只查询部分字段,则可以返回HashMap,示例如下:
示例二:
<select id="selectOne" parameterType="Long" resultType="hashMap">
SELECT name,age FROM student WHERE id=#{id}
</select>
2、resultMap
resultMap标签定义SQL查询结果字段与实体属性的映射关系。示例如下:
<resultMap id="BaseResultMap" type="org.weiz.example01.model.Student">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
</resultMap>
设置selecct标签的resultMap=“BaseResultMap”,示例代码如下:
<select id="selectOne" parameterType="Long"
resultMap="BaseResultMap">
SELECT *
FROM student
WHERE id= #{id}
</select>
3、 resultMap的结构
它结构复杂,其主要属性如下:
id : 定义resultMap的唯一标识
type: 为返回值的类名
子标签:
(1)id标签设置主键字段与领域模型属性的映射关系
(2)result标签用于设置普通字段与领域模型的属性映射关系。
(3) associaation标签用于配置一对结果映射,可以关联resultMap中的定义,或者对其它结果映射 。
(4)collection标签用于配置一对多结果映射,可以关联resultMap结果映射中的定义或其它映射。
示例代码如下:
<resultMap id="StudentAndClassMap" type="org.weiz.example01.model.Student">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
<!--association用户关系映射,查询单个完整对象-->
<association property="classes"
javaType="org.weiz.example01.model.Classes">
<id column="id" property="id" />
<result column="class_name" property="name" jdbcType="VARCHAR"/>
<result column="memo" property="memo" jdbcType="VARCHAR" />
</association>
</resultMap>
四、关联关系
多表关联的复杂结果需要通过collection标签和association标签配置关联关系。
1、association(一对一)
它通常用于映射一对一的关系,比如一个(Student)对应一个班级(Classes),一个学生只能属于一个班级,下面以学生和班级为例演示association 配置一对一关系。
步骤如下:
(1)创建班级表classes,主要有id(主键、bigint、自增)、name(班级名称、varchar、长度255)、memo(班级简介、 varchar、长度为255)三个字段。
(2)新建classes的POJO类和mapper映射文件
(3)修改Student类,增加学生对应班级classes属性
private Classes classes;
(4)修改StudentMapper接口,增加查询班级信息的方法,示例如下:
Student selectStudentAndClass(Long id);
(5) 修改StudentMapper映射文件,配置实体映射关系,示例代码如下:
<resultMap id="StudentAndClassMap" type="org.weiz.example01.model.Student">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
<!--association用户关系映射,查询单个完整对象-->
<association property="classes"
javaType="org.weiz.example01.model.Classes">
<id column="id" property="id" />
<result column="class_name" property="name" jdbcType="VARCHAR"/>
<result column="memo" property="memo" jdbcType="VARCHAR" />
</association>
</resultMap>
(6)定义查询语句,示例代码如下:
<select id="selectStudentAndClass" parameterType="Long"
resultMap="StudentAndClassMap">
SELECT
s.id,s.name,s.sex,s.age,s.class_id,c.name as class_name, c.memo
FROM student s left join classes c on s.class_id=c.id
WHERE s.id=#{id}
</select>
2、collection(一对多)
collection用于映射一对多的关系,将关联查询信息映射到一个列表集合中。比如一个班级(Classes)对应多名学生Student,下面以此演示collection标签配置一对多关系。
步骤如下:
(1)修改Student表,增加class_id,表示班级ID。
(2)修改ClassMapper接口,查询班级和班级下的所有学生信息,代码如下:
Classes selectClassAndStudent(Long id);
(3) 在classMapper.xml映射文件中,定义返回数据resultMap,代码如下:
<resultMap id="ClassAndStudentMap" type="org.weiz.example01.model.Classes" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="createtime" property="createtime" jdbcType="DATE" />
<result column="memo" property="memo" jdbcType="VARCHAR" />
<collection property="students"
ofType="org.weiz.example01.model.Student">
<id property="id" column="student_id"/>
<result property="name" column="student_name" />
<result property="age" column="age" />
<result property="sex" column="sex" />
</collection>
</resultMap>
(4)创建SQL语句,示例代码如下:
<select id="selectClassAndStudent" parameterType="Long"
resultMap="ClassAndStudentMap">
SELECT c.id,c.name,c.memo,s.id as student_id ,s.name as student_name,s.age,s.sex
FROM classes c left join student s on s.class_id=c.id
WHERE c.id=#{id}
</select>
五、SQL代码片段
当多个SQL语句存在相同的部分,可以将其定义为公共的SQL代码片段,MyBatis提供了sql和include标签定义和引用sql代码片段。
例如:
<select id="selectOne" parameterType="Long" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM student
WHERE id= #{id}
</select>
<sql id="Base_Column_List">
id,name,sex,age
</sql>
在上面的示例中,使用include标签引用定义的base_Column_List代码片段。
sql标签也支持传入参数,可以对上面的示例进行如下修改:
<sql id="Base_Column_List">
${alias_s}.id,
${alias_s}.name,
${alias_s}.age,
${alias_s}.sex,
</sql>
<select id="selectOne" resultMap="BaseResultMap">
SELECT
<include refid="BaseResultMap">
<property name="alias_s" value="stu" />
</include>
FROM student stu
WHERE stu.id=#{id}
</select>
上面示例中,通过property定义传入的参数。