resultMap标签:表字段与属性的映射。
返回对象是pojo:1,pojo的属性和表字段名字一样时,resultMap的配置可以省略。2,pojo的属性和表字段名字不一样时,需要通过resultMap配置pojo属性与表字段之间的映射 关系。
返回对象是Map:需要通过resultMap配置表字段和Map中的Key之间的映射关系。
关于resultMap使用的几种情况:
1,id、result:id、result是最简单的映射,id为主键映射;result其他基本数据库表字段到实体类属性的映射。
2,constructor
3,association联合:联合元素用来处理“一对一”的关系。
不同情况需要告诉MyBatis 如何加载一个联合。MyBatis 可以用两种方式加载:
1. select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;
2. resultsMap: 使用一个嵌套的结果映射来处理通过join查询结果集,映射成Java实体类型。
4,collection聚集:聚集元素用来处理“一对多”的关系。
不同情况需要告诉MyBatis 如何加载一个聚集。MyBatis 可以用两种方式加载:
1. select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;
2. resultsMap: 使用一个嵌套的结果映射来处理通过join查询结果集,映射成Java实体类型。
5,discriminator鉴别器:有时一个单独的数据库查询也许返回很多不同(但是希望有些关联)数据类型的结果集。鉴别器元素就是被设计来处理这个情况的,还有包括类的继承层 次结构。鉴别器非常容易理解,因为它的表现很像Java语言中的switch语句。
sql:
Sql元素用来定义一个可以复用的SQL 语句段,供其它语句调用。
<!-- 复用sql语句 查询student表所有字段 -->
<sql id="selectStudentAll">
SELECT ST.STUDENT_ID,
ST.STUDENT_NAME,
ST.STUDENT_SEX,
ST.STUDENT_BIRTHDAY,
ST.CLASS_ID
FROM STUDENT_TBL ST
</sql>
这样,在select的语句中就可以直接引用使用了,将上面select语句改成:
<!-- 查询学生,根据id -->
<select id="getStudent" parameterType="String" resultMap="studentResultMap">
<include refid="selectStudentAll"/>
WHERE ST.STUDENT_ID = #{studentID}
</select>
字符串代入法:
默认的情况下,使用#{}语法会促使MyBatis 生成PreparedStatement 属性并且使用PreparedStatement 的参数(=?)来安全的设置值。尽量这些是快捷安全,也是经常使用的。但有时候你可能想直接未更改的字符串代入到SQL 语句中。比如说,对于ORDER BY,你可能会这样使用:ORDER BY ${columnName}但MyBatis 不会修改和规避掉这个字符串。
注意:这样地接收和应用一个用户输入到未更改的语句中,是非常不安全的。这会让用户能植入破坏代码,所以,要么要求字段不要允许客户输入,要么你直接来检测他的合法性 。
cache缓存:
http://limingnihao.iteye.com/blog/781911
动态SQL:
if标签:
实例:
1 <!-- 2 if(判断参数) - 将实体类不为空的属性作为where条件 --> 2 <select id="getStudentList_if" resultMap="resultMap_studentEntity" parameterType="liming.student.manager.data.model.StudentEntity"> 3 SELECT ST.STUDENT_ID, 4 ST.STUDENT_NAME, 5 ST.STUDENT_SEX, 6 ST.STUDENT_BIRTHDAY, 7 ST.STUDENT_PHOTO, 8 ST.CLASS_ID, 9 ST.PLACE_ID 10 FROM STUDENT_TBL ST 11 WHERE 12 <if test="studentName !=null "> 13 ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%') 14 </if> 15 <if test="studentSex != null and studentSex != '' "> 16 AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER} 17 </if> 18 <if test="studentBirthday != null "> 19 AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE} 20 </if> 21 <if test="classId != null and classId!= '' "> 22 AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR} 23 </if> 24 <if test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' "> 25 AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR} 26 </if> 27 <if test="placeId != null and placeId != '' "> 28 AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR} 29 </if> 30 <if test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' "> 31 AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR} 32 </if> 33 <if test="studentId != null and studentId != '' "> 34 AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR} 35 </if> 36 </select>
if + where 的条件判断
“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。
实例:
1 <!-- 3 select - where/if(判断参数) - 将实体类不为空的属性作为where条件 --> 2 <select id="getStudentList_whereIf" resultMap="resultMap_studentEntity" parameterType="liming.student.manager.data.model.StudentEntity"> 3 SELECT ST.STUDENT_ID, 4 ST.STUDENT_NAME, 5 ST.STUDENT_SEX, 6 ST.STUDENT_BIRTHDAY, 7 ST.STUDENT_PHOTO, 8 ST.CLASS_ID, 9 ST.PLACE_ID 10 FROM STUDENT_TBL ST 11 <where> 12 <if test="studentName !=null "> 13 ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%') 14 </if> 15 <if test="studentSex != null and studentSex != '' "> 16 AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER} 17 </if> 18 <if test="studentBirthday != null "> 19 AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE} 20 </if> 21 <if test="classId != null and classId!= '' "> 22 AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR} 23 </if> 24 <if test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' "> 25 AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR} 26 </if> 27 <if test="placeId != null and placeId != '' "> 28 AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR} 29 </if> 30 <if test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' "> 31 AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR} 32 </if> 33 <if test="studentId != null and studentId != '' "> 34 AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR} 35 </if> 36 </where> 37 </select>
if + set 的更新语句
当update语句中没有使用if标签时,如果有一个参数为null,都会导致错误。
当在update语句中使用if标签时,如果前面的if没有执行,则或导致逗号多余错误。使用set标签可以将动态的配置SET 关键字,和剔除追加到条件末尾的任何不相关的逗号。
使用if+set标签修改后,如果某项为null则不进行更新,而是保持数据库原值。
实例:
1 <!-- 4 if/set(判断参数) - 将实体类不为空的属性更新 --> 2 <update id="updateStudent_if_set" parameterType="liming.student.manager.data.model.StudentEntity"> 3 UPDATE STUDENT_TBL 4 <set> 5 <if test="studentName != null and studentName != '' "> 6 STUDENT_TBL.STUDENT_NAME = #{studentName}, 7 </if> 8 <if test="studentSex != null and studentSex != '' "> 9 STUDENT_TBL.STUDENT_SEX = #{studentSex}, 10 </if> 11 <if test="studentBirthday != null "> 12 STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday}, 13 </if> 14 <if test="studentPhoto != null "> 15 STUDENT_TBL.STUDENT_PHOTO = #{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler}, 16 </if> 17 <if test="classId != '' "> 18 STUDENT_TBL.CLASS_ID = #{classId} 19 </if> 20 <if test="placeId != '' "> 21 STUDENT_TBL.PLACE_ID = #{placeId} 22 </if> 23 </set> 24 WHERE STUDENT_TBL.STUDENT_ID = #{studentId}; 25 </update>
if + trim代替where/set标签
trim是更灵活的去处多余关键字的标签,他可以实践where和set的效果。
trim代替where:
实例:
1 <!-- 5.1 if/trim代替where(判断参数) - 将实体类不为空的属性作为where条件 --> 2 <select id="getStudentList_if_trim" resultMap="resultMap_studentEntity"> 3 SELECT ST.STUDENT_ID, 4 ST.STUDENT_NAME, 5 ST.STUDENT_SEX, 6 ST.STUDENT_BIRTHDAY, 7 ST.STUDENT_PHOTO, 8 ST.CLASS_ID, 9 ST.PLACE_ID 10 FROM STUDENT_TBL ST 11 <trim prefix="WHERE" prefixOverrides="AND|OR"> 12 <if test="studentName !=null "> 13 ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%') 14 </if> 15 <if test="studentSex != null and studentSex != '' "> 16 AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER} 17 </if> 18 <if test="studentBirthday != null "> 19 AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE} 20 </if> 21 <if test="classId != null and classId!= '' "> 22 AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR} 23 </if> 24 <if test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' "> 25 AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR} 26 </if> 27 <if test="placeId != null and placeId != '' "> 28 AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR} 29 </if> 30 <if test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' "> 31 AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR} 32 </if> 33 <if test="studentId != null and studentId != '' "> 34 AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR} 35 </if> 36 </trim> 37 </select>
trim代替set:
实例:
1 <!-- 5.2 if/trim代替set(判断参数) - 将实体类不为空的属性更新 --> 2 <update id="updateStudent_if_trim" parameterType="liming.student.manager.data.model.StudentEntity"> 3 UPDATE STUDENT_TBL 4 <trim prefix="SET" suffixOverrides=","> 5 <if test="studentName != null and studentName != '' "> 6 STUDENT_TBL.STUDENT_NAME = #{studentName}, 7 </if> 8 <if test="studentSex != null and studentSex != '' "> 9 STUDENT_TBL.STUDENT_SEX = #{studentSex}, 10 </if> 11 <if test="studentBirthday != null "> 12 STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday}, 13 </if> 14 <if test="studentPhoto != null "> 15 STUDENT_TBL.STUDENT_PHOTO = #{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=org.apache.ibatis.type.BlobTypeHandler}, 16 </if> 17 <if test="classId != '' "> 18 STUDENT_TBL.CLASS_ID = #{classId}, 19 </if> 20 <if test="placeId != '' "> 21 STUDENT_TBL.PLACE_ID = #{placeId} 22 </if> 23 </trim> 24 WHERE STUDENT_TBL.STUDENT_ID = #{studentId} 25 </update>
choose (when, otherwise)
有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用if标签时,只要test中的表达式为true,就会执行if标签中的条件。MyBatis提供了choose 元素。if标签是与(and)的关系,而choose比傲天是或(or)的关系。
choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则choose结束。当choose中所有when的条件都不满则时,则执行otherwise中的sql。类似于Java 的switch 语句,choose为switch,when为case,otherwise则为default。
使用where将choose包起来,防止关键字多于错误。
实例:
1 <!-- 6 choose(判断参数) - 按顺序将实体类第一个不为空的属性作为where条件 --> 2 <select id="getStudentList_choose" resultMap="resultMap_studentEntity" parameterType="liming.student.manager.data.model.StudentEntity"> 3 SELECT ST.STUDENT_ID, 4 ST.STUDENT_NAME, 5 ST.STUDENT_SEX, 6 ST.STUDENT_BIRTHDAY, 7 ST.STUDENT_PHOTO, 8 ST.CLASS_ID, 9 ST.PLACE_ID 10 FROM STUDENT_TBL ST 11 <where> 12 <choose> 13 <when test="studentName !=null "> 14 ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%') 15 </when > 16 <when test="studentSex != null and studentSex != '' "> 17 AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER} 18 </when > 19 <when test="studentBirthday != null "> 20 AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE} 21 </when > 22 <when test="classId != null and classId!= '' "> 23 AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR} 24 </when > 25 <when test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' "> 26 AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR} 27 </when > 28 <when test="placeId != null and placeId != '' "> 29 AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR} 30 </when > 31 <when test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' "> 32 AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR} 33 </when > 34 <when test="studentId != null and studentId != '' "> 35 AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR} 36 </when > 37 <otherwise> 38 </otherwise> 39 </choose> 40 </where> 41 </select>
foreach
对于动态SQL 非常必须的,主是要迭代一个集合,通常是用于IN 条件。List 实例将使用“list”做为键,数组实例以“array” 做为键。
foreach元素是非常强大的,它允许你指定一个集合,声明集合项和索引变量,它们可以用在元素体内。它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符。这个元素是很智能的,它不会偶然地附加多余的分隔符。
注意:你可以传递一个List实例或者数组作为参数对象传给MyBatis。当你这么做的时候,MyBatis会自动将它包装在一个Map中,用名称在作为键。List实例将会以“list”作为键,而数组实例将会以“array”作为键。
这个部分是对关于XML配置文件和XML映射文件的而讨论的。下一部分将详细讨论Java API,所以你可以得到你已经创建的最有效的映射。
参数为array示例的写法:
实例:
public List<StudentEntity> getStudentListByClassIds_foreach_array(String[] classIds);
1 <!— 7.1 foreach(循环array参数) - 作为where中in的条件 --> 2 <select id="getStudentListByClassIds_foreach_array" resultMap="resultMap_studentEntity"> 3 SELECT ST.STUDENT_ID, 4 ST.STUDENT_NAME, 5 ST.STUDENT_SEX, 6 ST.STUDENT_BIRTHDAY, 7 ST.STUDENT_PHOTO, 8 ST.CLASS_ID, 9 ST.PLACE_ID 10 FROM STUDENT_TBL ST 11 WHERE ST.CLASS_ID IN 12 <foreach collection="array" item="classIds" open="(" separator="," close=")"> 13 #{classIds} 14 </foreach> 15 </select>
参数为list示例的写法:
实例:
public List<StudentEntity> getStudentListByClassIds_foreach_list(List<String> classIdList);
1 <!-- 7.2 foreach(循环List<String>参数) - 作为where中in的条件 --> 2 <select id="getStudentListByClassIds_foreach_list" resultMap="resultMap_studentEntity"> 3 SELECT ST.STUDENT_ID, 4 ST.STUDENT_NAME, 5 ST.STUDENT_SEX, 6 ST.STUDENT_BIRTHDAY, 7 ST.STUDENT_PHOTO, 8 ST.CLASS_ID, 9 ST.PLACE_ID 10 FROM STUDENT_TBL ST 11 WHERE ST.CLASS_ID IN 12 <foreach collection="list" item="classIdList" open="(" separator="," close=")"> 13 #{classIdList} 14 </foreach> 15 </select>
MyBatis主配置文件
http://limingnihao.iteye.com/blog/1060764
参考文献:
http://limingnihao.iteye.com/blog/781878
github中的mybatis文档:http://mybatis.github.io/mybatis-3/zh/index.html