MyBatis学习

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>  
View Code

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>  
View Code

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>  
View Code

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>  
View Code

 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>  
View Code

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>  
View Code

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>  
View Code

参数为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>  
View Code

MyBatis主配置文件

http://limingnihao.iteye.com/blog/1060764

参考文献:

http://limingnihao.iteye.com/blog/781878

github中的mybatis文档:http://mybatis.github.io/mybatis-3/zh/index.html

原文地址:https://www.cnblogs.com/dobestself-994395/p/4274208.html