首页 > 代码库 > 映射文件
映射文件
<?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.zln.mapper.StudentMapper"> <!--配置给定命名空间的缓存--> <!--<cache></cache>--> <!--从其他命名空间引用缓存配置--> <!--<cache-ref namespace=""/>--> <!--结果集映射--> <resultMap id="StudentResultMap" type="Student"> <id property="studId" column="stud_id" jdbcType="INTEGER"/> <result property="name" column="name" jdbcType="VARCHAR"/> <result property="email" column="email" jdbcType="VARCHAR"/> <result property="dob" column="dob" jdbcType="DATE"/> </resultMap> <!--可重用的SQL片段--> <sql id="selectStudents"> SELECT stud_id,name,email,dob </sql> <select id="findAllStudents" resultMap="StudentResultMap"> <include refid="selectStudents"/> FROM Student </select> <!-- select详解 id:查询id,如果使用Mapper形式编写,那么id值就是Mapper接口的方法名 parameterType:参数类型,一般就是一个pojo对象 或者 基本数据类型 或者 map 等 resultType:结果集映射类型 resultMap:结果集映射类型 flushCache:默认false,如果为true:无论语句何时被调用,都会导致缓存情况 timeout:超时时间 fetchSize:默认由驱动决定,每次批量返回的行数 statementType:STATEMENT,PREPARED 或 CALLABLE 的一种。这会让 MyBatis 使用选择使用 Statement,PreparedStatement 或 CallableStatement。 默认值:PREPARED。 resultSetType:FORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE中的一种。默认是不设置(驱动自行处理)。 --> <!-- #{property,javaType=int,jdbcType=NUMERIC},用这种方式来指定参数类型,一般如果是pojo,MyBatis是能够自动获取的 和iBatis一样,也有 ${} 这种写法,一般用于 order by --> <!-- 一对一映射:在resultMap中配置association 一对多映射:配置collection --> <!-- 缓存:默认情况没开启缓存 SQL映射文件中加上 <cache/> 就会开启二级缓存 --> <!-- if标签 where标签 trim标签 <select id="selectBySelective" resultType="xxx.UserInfo"> select <include refid="Base_Column_List"/> from uc_user <where> ( <if test="userName != null"> user_name = #{userName} </if> <if test="email != null"> or email = #{email} </if> <if test="phone != null"> or phone = #{phone} </if> <if test="weiboId != null"> or weibo_id = #{weiboId} </if> <if test="wxId != null"> or wx_id = #{wxId} </if> <if test="qqId != null"> or qq_id = #{qqId} </if>) </where> and status = 1 </select> 这样代码看似没有什么问题但是其实是有问题的。为什么呢? 如果userName 为空,后面某字段不为空,最后的sql语言会成为这样: select * from uc_user where(or email = "xxx") and status = 1 使用mybatis < where > 标签就是为了防止这种情况,mybatis会在第一个 userName 为空的情况下,帮我们去掉后面的语句的第一个”or” 但是我加了where标签中加入()后,语句会报错。因为自动去掉”or”会失效。 查看了mybatis官方文档发现了另一个标签 < trim >可以通过自定义 trim 元素来定制我们想要的功能 trim标签包围的内容可以设置几个属性: prefix :内容之前加的前缀 suffix :内容之后加的后缀 prefixOverrides: 属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要的,多个忽略序列用“|”隔开)。它带来的结果就是所有在 prefixOverrides 属性中指定的内容将被移除。 --> <!-- <select id="selectBySelective" resultType="xxx.UserInfo"> select <include refid="Base_Column_List"/> from uc_user <trim prefix="WHERE (" suffix=")" prefixOverrides="AND |OR "> <if test="userName != null"> user_name = #{userName} </if> <if test="email != null"> or email = #{email} </if> <if test="phone != null"> or phone = #{phone} </if> <if test="weiboId != null"> or weibo_id = #{weiboId} </if> <if test="wxId != null"> or wx_id = #{wxId} </if> <if test="qqId != null"> or qq_id = #{qqId} </if> </trim> and status = 1 </select> --> <!--choose when --> <!-- <select id="getStudentListChooseEntity" parameterType="StudentEntity" resultMap="studentResultMap"> SELECT * from STUDENT_TBL ST <where> <choose> <when test="studentName!=null and studentName!=‘‘ "> ST.STUDENT_NAME LIKE CONCAT(CONCAT(‘%‘, #{studentName}),‘%‘) </when> <when test="studentSex!= null and studentSex!= ‘‘ "> AND ST.STUDENT_SEX = #{studentSex} </when> <when test="studentBirthday!=null"> AND ST.STUDENT_BIRTHDAY = #{studentBirthday} </when> <when test="classEntity!=null and classEntity.classID !=null and classEntity.classID!=‘‘ "> AND ST.CLASS_ID = #{classEntity.classID} </when> <otherwise> </otherwise> </choose> </where> </select> --> <!--foreach 循环标签--> <!-- <select id="getStudentListByClassIDs" resultMap="studentResultMap"> SELECT * FROM STUDENT_TBL ST WHERE ST.CLASS_ID IN <foreach collection="list" item="classList" open="(" separator="," close=")"> #{classList} </foreach> </select> --> <!--SET 更新--> <!-- <update id="updateUserInfoBySet" parameterType="userInfo"> update userInfo <set> <if test="mobile!=null"> mobile=#{mobile}, </if> <if test="gender!=null"> gender=#{gender}, </if> <if test="position!=null"> position = #{position}, </if> </set> where userid=#{userid} </update> a.SQL语句的set被<set>标签替代。 b.每个<if>中语句最后都带有逗号,如果有写过SQL语句的同学就一定知道,最后的逗号是不能有的,因此,这里的<set>标签能够帮助我们自动的移除最后一个<if>中的逗号。 c.<trim>是一个非常强大的标签,因此,我们也可以通过<trim>来实现<set>的功能,如下:【这种写法的运行效果与<set>等价】 --> <!-- <update id="updateUserInfoBySet" parameterType="userInfo"> update userInfo <trim prefix="SET" suffixOverrides=","> <if test="mobile!=null"> mobile=#{mobile}, </if> <if test="gender!=null"> gender=#{gender}, </if> <if test="position!=null"> position = #{position}, </if> </trim> where userid=#{userid} </update> --> </mapper>
@font-face { font-family: "Courier New"; }@font-face { font-family: "Times"; }@font-face { font-family: "宋体"; }@font-face { font-family: "Cambria Math"; }@font-face { font-family: "@宋体"; }@font-face { font-family: "Calibri Light"; }@font-face { font-family: "Calibri"; }@font-face { font-family: "MS Mincho"; }@font-face { font-family: "Consolas"; }@font-face { font-family: "微软雅黑,Bold"; }@font-face { font-family: "Helvetica Neue"; }@font-face { font-family: "微软雅黑"; }@font-face { font-family: "Consolas,Bold"; }@font-face { font-family: "SimSun"; }@font-face { font-family: "@SimSun"; }@font-face { font-family: "@MS Mincho"; }@font-face { font-family: "@微软雅黑"; }p.MsoNormal, li.MsoNormal, div.MsoNormal { margin: 0cm 0cm 0.0001pt; text-align: justify; font-size: 12pt; font-family: Calibri; }h1 { margin: 17pt 0cm 16.5pt; text-align: justify; line-height: 240%; page-break-after: avoid; font-size: 22pt; font-family: Calibri; font-weight: bold; }h2 { margin: 13pt 0cm; text-align: justify; line-height: 173%; page-break-after: avoid; font-size: 16pt; font-family: "Calibri Light"; font-weight: bold; }h3 { margin: 13pt 0cm; text-align: justify; line-height: 173%; page-break-after: avoid; font-size: 16pt; font-family: Calibri; font-weight: bold; }p.MsoDocumentMap, li.MsoDocumentMap, div.MsoDocumentMap { margin: 0cm 0cm 0.0001pt; text-align: justify; font-size: 12pt; font-family: "Times New Roman"; }p { margin-right: 0cm; margin-left: 0cm; font-size: 12pt; font-family: "Times New Roman"; }pre { margin: 0cm 0cm 0.0001pt; font-size: 10pt; font-family: "Courier New"; }p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph { margin: 0cm 0cm 0.0001pt; text-align: justify; text-indent: 21pt; font-size: 12pt; font-family: Calibri; }span.a { font-family: "Times New Roman"; }span.HTML { font-family: "Courier New"; }span.tag { }span.pln { }span.atn { }span.pun { }span.atv { }span.apple-converted-space { }span.kwd { }span.typ { }span.com { }span.lit { }span.str { }.MsoChpDefault { font-family: Calibri; }div.WordSection1 { }ol { margin-bottom: 0cm; }ul { margin-bottom: 0cm; }
cache
配置给定命名空间的缓存。 ?
cache-ref
从其他命名空间引用缓存配置。 ?
resultMap
最复杂,也是最有力量的元素,用来描述如何从数据库结果集中来加载你的对象。 ? ?
<resultMap id="StudentResult" type="com.mybatis3.domain.Student">
<id property="studId" column="stud_id" />
<result property="name" column="name" />
<result property="email" column="email" />
<result property="phone" column="phone" />
</resultMap>
<select id="findAllStudents" resultMap="StudentResult">
SELECT * FROM STUDENTS
</select>
<select id="findStudentById" parameterType="int" resultMap="StudentResult">
SELECT * FROM STUDENTS WHERE STUD_ID=#{studId}
</select>
拓展 ResultMap
我们可以从从另外一个<resultMap>,拓展出一个新的<resultMap>,这样,原先的属性映射可以继承过来,以实现。
- <resultMap type="Student" id="StudentResult">
- <id property="studId" column="stud_id" />
- <result property="name" column="name" />
- <result property="email" column="email" />
- <result property="phone" column="phone" />
- </resultMap>
- <resultMap type="Student" id="StudentWithAddressResult" extends="StudentResult">
- <result property="address.addrId" column="addr_id" />
- <result property="address.street" column="street" />
- 10. <result property="address.city" column="city" />
- 11. <result property="address.state" column="state" />
- 12. <result property="address.zip" column="zip" />
- 13. <result property="address.country" column="country" />
14. </resultMap>
一对一
- public class Address
- {
- private Integer addrId;
- private String street;
- private String city;
- private String state;
- private String zip;
- private String country;
- // setters & getters
- 10. }
- public class Student
- {
- private Integer studId;
- private String name;
- private String email;
- private PhoneNumber phone;
- private Address address;
- //setters & getters
- }
- <resultMap type="Student" id="StudentWithAddressResult">
- <id property="studId" column="stud_id" />
- <result property="name" column="name" />
- <result property="email" column="email" />
- <result property="phone" column="phone" />
- <result property="address.addrId" column="addr_id" />
- <result property="address.street" column="street" />
- <result property="address.city" column="city" />
- <result property="address.state" column="state" />
- 10. <result property="address.zip" column="zip" />
- 11. <result property="address.country" column="country" />
12. </resultMap>
- <select id="selectStudentWithAddress" parameterType="int"
- resultMap="StudentWithAddressResult">
- SELECT STUD_ID, NAME, EMAIL, A.ADDR_ID, STREET, CITY, STATE,
- ZIP, COUNTRY
- FROM STUDENTS S LEFT OUTER JOIN ADDRESSES A ON S.ADDR_ID=A.ADDR_ID
- WHERE STUD_ID=#{studId}
- </select>
我们可以使用圆点记法为内嵌的对象的属性赋值。在上述的 resultMap 中,Student 的 address 属性使用了圆点记法 被赋上了 address 对应列的值。
上述样例展示了一对一关联映射的一种方法。然而,使用这种方式映射,如果 address 结果需要在其他的 SELECT 映射 语句中映射成 Address 对象,我们需要为每一个语句重复这种映射关系。MyBatis提供了更好地实现一对一关联映射的方 法:嵌套结果 ResultMap 和嵌套 select 查询语句。接下来,我们将讨论这两种方式。
使用嵌套结果 ResultMap 实现一对一关系映射
- <resultMap type="Address" id="AddressResult">
- <id property="addrId" column="addr_id" />
- <result property="street" column="street" />
- <result property="city" column="city" />
- <result property="state" column="state" />
- <result property="zip" column="zip" />
- <result property="country" column="country" />
- </resultMap>
- <resultMap type="Student" id="StudentWithAddressResult">
- 10. <id property="studId" column="stud_id" />
- 11. <result property="name" column="name" />
- 12. <result property="email" column="email" />
- 13. <association property="address" resultMap="AddressResult" />
14. </resultMap>
15. <select id="findStudentWithAddress" parameterType="int" resultMap="StudentWithAddressResult">
16. SELECT STUD_ID, NAME, EMAIL, A.ADDR_ID, STREET, CITY, STATE, ZIP, COUNTRY
17. FROM STUDENTS S LEFT OUTER JOIN ADDRESSES A ON S.ADDR_ID=A.ADDR_ID
- 18. WHERE STUD_ID=#{studId}
19. </select>
我们也可以使用<association 定义内联的 resultMap,代码如下所示:
- <resultMap type="Student" id="StudentWithAddressResult">
- <id property="studId" column="stud_id" />
- <result property="name" column="name" />
- <result property="email" column="email" />
- <association property="address" javaType="Address">
- <id property="addrId" column="addr_id" />
- <result property="street" column="street" />
- <result property="city" column="city" />
- <result property="state" column="state" />
- 10. <result property="zip" column="zip" />
- 11. <result property="country" column="country" />
- 12. </association>
13. </resultMap>
使用嵌套查询实现一对一关系映射
- <resultMap type="Address" id="AddressResult">
- <id property="addrId" column="addr_id" />
- <result property="street" column="street" />
- <result property="city" column="city" />
- <result property="state" column="state" />
- <result property="zip" column="zip" />
- <result property="country" column="country" />
- </resultMap>
- <select id="findAddressById" parameterType="int" resultMap="AddressResult">
- 10. SELECT * FROM ADDRESSES WHERE ADDR_ID=#{id}
11. </select>
12. <resultMap type="Student" id="StudentWithAddressResult">
- 13. <id property="studId" column="stud_id" />
14. <result property="name" column="name" />
- 15. <result property="email" column="email" />
- 16. <association property="address" column="addr_id" select="findAddressById" />
17. </resultMap>
18. <select id="findStudentWithAddress" parameterType="int"
19. resultMap="StudentWithAddressResult">
- 20. SELECT * FROM STUDENTS WHERE STUD_ID=#{Id}
21. </select>
在此方式中,<association>元素的 select属性被设置成了id为 findAddressById的语句。这里,两个分开的 SQL 语句将会在数据库中执行,第一个调用 findStudentById 加载 student 信息,而第二个调用 findAddressById 来 加载 address 信息。
Addr_id 列的值将会被作为输入参数传递给 selectAddressById 语句。
一对多
- public class Course
- {
- private Integer courseId;
- private String name;
- private String description;
- private Date startDate;
- private Date endDate;
- private Integer tutorId;
- //setters & getters
10. }
11. public class Tutor
12. {
- 13. private Integer tutorId;
- 14. private String name;
- 15. private String email;
- 16. private Address address;
- 17. private List<Course> courses;
- 18. / setters & getters
19. }
- <resultMap type="Course" id="CourseResult">
- <id column="course_id" property="courseId" />
- <result column="name" property="name" />
- <result column="description" property="description" />
- <result column="start_date" property="startDate" />
- <result column="end_date" property="endDate" />
- </resultMap>
- <resultMap type="Tutor" id="TutorResult">
- <id column="tutor_id" property="tutorId" />
- 10. <result column="tutor_name" property="name" />
- 11. <result column="email" property="email" />
- 12. <collection property="courses" resultMap="CourseResult" />
13. </resultMap>
14. <select id="findTutorById" parameterType="int" resultMap="TutorResult">
15. SELECT T.TUTOR_ID, T.NAME AS TUTOR_NAME, EMAIL, C.COURSE_ID,
16. C.NAME, DESCRIPTION, START_DATE, END_DATE
17. FROM TUTORS T LEFT OUTER JOIN ADDRESSES A ON T.ADDR_ID=A.ADDR_ID
18. LEFT OUTER JOIN COURSES C ON T.TUTOR_ID=C.TUTOR_ID
19. WHERE T.TUTOR_ID=#{tutorId}
20. </select>
这里我们使用了一个简单的使用了 JOINS 连接的 Select 语句获取讲师及其所教课程信息。<collection>元素的 resultMap 属性设置成了 CourseResult,CourseResult 包含了 Course对象属性与表列名之间的映射。
使用嵌套 Select 语句实现一对多映射
- <resultMap type="Course" id="CourseResult">
- <id column="course_id" property="courseId" />
- <result column="name" property="name" />
- <result column="description" property="description" />
- <result column="start_date" property="startDate" />
- <result column="end_date" property="endDate" />
- </resultMap>
- <resultMap type="Tutor" id="TutorResult">
- <id column="tutor_id" property="tutorId" />
- 10. <result column="tutor_name" property="name" />
- 11. <result column="email" property="email" />
- 12. <association property="address" resultMap="AddressResult" />
- 13. <collection property="courses" column="tutor_id" select="findCoursesByTutor" />
14. </resultMap>
15. <select id="findTutorById" parameterType="int" resultMap="TutorResult">
- 16. SELECT T.TUTOR_ID, T.NAME AS TUTOR_NAME, EMAIL
- 17. FROM TUTORS T WHERE T.TUTOR_ID=#{tutorId}
18. </select>
19. <select id="findCoursesByTutor" parameterType="int" resultMap="CourseResult">
- 20. SELECT * FROM COURSES WHERE TUTOR_ID=#{tutorId}
21. </select>
在这种方式中,<aossication>元素的 select 属性被设置为 id 为 findCourseByTutor 的语句,用来触发单独 的 SQL 查询加载课程信息。tutor_id 这一列值将会作为输入参数传递给findCouresByTutor 语句。
sql
可以重用的 SQL 块,也可以被其他语句引用。 ?
<sql id=”userColumns”> id,username,password </sql>
<select id=”selectUsers” parameterType=”int” resultType=”hashmap”>
select <include refid=”userColumns”/> from some_table?where id = #{id}
</select>
insert
映射插入语句 ?
允许的属性
id
parameterType
flushCache
statementType
keyProperty
(仅对 insert 有用)标记一个属性,MyBatis 会通过 getGeneratedKeys 或者通过 insert 语句的 selectKey 子元素设置它的值。默认:不设置。
useGeneratedKeys
(仅对 insert 有用)这会告诉 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据(比如:像 MySQL 和 SQL Server 这样的数据库管理系统的自动递增字段)内部生成的主键。 默认值:false。
<insert id="insertAuthor" parameterType="domain.blog.Author" useGeneratedKeys=”true” keyProperty=”id”>?insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio})
</insert>
自定义生成一条主键、也可以是Oracle的序列
<insert id="insertAuthor" parameterType="domain.blog.Author">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
</selectKey>?
insert into Author?(id, username, password, email,bio, favourite_section)?values?(#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR}?)
</insert>
- <insert id="insertStudent" parameterType="Student">
- <selectKey keyProperty="studId" resultType="int" order="BEFORE">
- SELECT ELEARNING.STUD_ID_SEQ.NEXTVAL FROM DUAL
- </selectKey>
- INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL, PHONE)
- VALUES(#{studId},#{name},#{email},#{phone})
- </insert>
这里我们使用了<selectKey>子元素来生成主键值,并将值保存到 Student 对象的 studId 属性上。 属性 order=“before”表示 MyBatis 将取得序列的下一个值作为主键值,并且在执行 INSERT SQL 语句之前将值设置到 studId 属性上。
我们也可以在获取序列的下一个值时,使用触发器(trigger)来设置主键值,并且在执行INSERT SQL语句之 前将值设置到主键列上。如果你采取这样的方式,则对应的 INSERT 映射语句如下所示:
- <insert id="insertStudent" parameterType="Student">
- INSERT INTO STUDENTS(NAME,EMAIL, PHONE)
- VALUES(#{name},#{email},#{phone})
- <selectKey keyProperty="studId" resultType="int" order="AFTER">
- SELECT ELEARNING.STUD_ID_SEQ.CURRVAL FROM DUAL
- </selectKey>
- </insert>
timeout
update
映射更新语句 ?
id
parameterType
flushCache
statementType
timeout
delete
映射删除语句 ?
id
parameterType
flushCache
statementType
timeout
select
映射查询语句 ?
select允许的属性
id
唯一标识这条SQL,一般是Mapper接口的方法名
parameterType
参数的全限定名或别名
可以是自定义对象或int、map等
resultType
返回类型
resultMap
返回类型
resultMap的值是一个自己配置过的Map
flushCache
默认false
useCache
默认true
timeout
超时时间,默认不做处理
fetchSize
每次批量返回的行数
默认不做处理,由驱动自行决定
statementType
STATEMENT,PREPARED 或 CALLABLE 的一种。这会让 MyBatis 使用选择使用 Statement,PreparedStatement 或 CallableStatement。 默认值:PREPARED。
resultSetType
FORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE
中的一种。默认是不设置(驱动自行处理)。
参数
#{id}
#{id,jdbcType=NUMERIC,javaType=int}
#{user.id}
#{id,jdbcType=NUMERIC,javaType=int,typehandler=myhandler}
${sql},注意:这种形式可能引发SQL注入问题
动态SQL标签
if
- <resultMap type="Course" id="CourseResult">
- <id column="course_id" property="courseId" />
- <result column="name" property="name" />
- <result column="description" property="description" />
- <result column="start_date" property="startDate" />
- <result column="end_date" property="endDate" />
- </resultMap>
- <select id="searchCourses" parameterType="hashmap" resultMap="CourseResult"></select>
- SELECT * FROM COURSES
- 10. WHERE TUTOR_ID= #{tutorId}
- 11. <if test="courseName != null">
- 12. AND NAME LIKE #{courseName}
- 13. </if>
- 14. <if test="startDate != null">
- 15. AND START_DATE >= #{startDate}
- 16. </if>
- 17. <if test="endDate != null">
- 18. AND END_DATE <= #{endDate}
- 19. </if>
20. </select>
- <select id="searchCourses" parameterType="hashmap" resultMap="CourseResult">
- SELECT * FROM COURSES
- <choose>
- <when test="searchBy == ‘Tutor‘">
- WHERE TUTOR_ID= #{tutorId}
- </when>
- <when test="searchBy == ‘CourseName‘">
- WHERE name like #{courseName}
- </when>
- 10. <otherwise>
- 11. WHERE TUTOR start_date >= now()
- 12. </otherwise>
- 13. </choose>
14. </select>
MyBatis 计算<choose>测试条件的值,且使用第一个值为 TRUE 的子句。如果没有条件为 true,则使用<otherwise> 内的子句。
Where
有时候,所有的查询条件(criteria)应该是可选的。在需要使用至少一种查询条件的情况下,我们应该使用 WHERE 子句。并且, 如果有多个条件,我们需要在条件中添加AND或OR。MyBatis提供了<where>元素支持这种类型的动 态 SQL 语句。
在我们查询课程界面,我们假设所有的查询条件是可选的。进而,当需要提供一个或多个查询条件时,应该改使用 WHERE 子句。
- <select id="searchCourses" parameterType="hashmap"
- resultMap="CourseResult">
- SELECT * FROM COURSES
- <where>
- <if test=" tutorId != null ">
- TUTOR_ID= #{tutorId}
- </if>
- <if test="courseName != null">
- AND name like #{courseName}
- 10. </if>
- 11. <if test="startDate != null">
- 12. AND start_date >= #{startDate}
- 13. </if>
- 14. <if test="endDate != null">
- 15. AND end_date <= #{endDate}
- 16. </if>
- 17. </where>
18. </select>
<where>元素只有在其内部标签有返回内容时才会在动态语句上插入 WHERE 条件语句。并且,如果WHERE 子句以 AND 或者 OR 打头,则打头的 AND 或 OR 将会被移除。
如果 tutor_id 参数值为 null,并且 courseName 参数值不为 null,则<where>标签会将 AND name like #{courseName} 中的 AND 移除掉,生成的 SQL WHERE 子句为:where name like #{courseName}。
trim
<trim>元素和<where>元素类似,但是<trim>提供了在添加前缀/后缀 或者 移除前缀/后缀方面提供更大的灵活 性。
- <select id="searchCourses" parameterType="hashmap" resultMap="CourseResult">
- SELECT * FROM COURSES
- <trim prefix="WHERE" prefixOverrides="AND | OR">
<if test=" tutorId != null "> - TUTOR_ID= #{tutorId}
- </if>
- <if test="courseName != null">
- AND name like #{courseName}
- </if>
- </trim>
10. </select>
这里如果任意一个<if>条件为 true,<trim>元素会插入 WHERE,并且移除紧跟 WHERE 后面的 AND 或OR
foreach
- <select id="searchCoursesByTutors" parameterType="map"
- resultMap="CourseResult">
- SELECT * FROM COURSES
- <if test="tutorIds != null">
- <where>
- <foreach item="tutorId" collection="tutorIds">
- OR tutor_id=#{tutorId}
- </foreach>
- </where>
10. </if>
11. </select>
- <select id="searchCoursesByTutors" parameterType="map"
- resultMap="CourseResult">
- SELECT * FROM COURSES
- <if test="tutorIds != null">
- <where>
- tutor_id IN
- <foreach item="tutorId" collection="tutorIds"
- open="(" separator="," close=")">
- #{tutorId}
- 10. </foreach>
- 11. </where>
- 12. </if>
13. </select>
set
<set>元素和<where>元素类似,如果其内部条件判断有任何内容返回时,他会插入 SET SQL 片段。
- <update id="updateStudent" parameterType="Student">
- update students
- <set>
- <if test="name != null">name=#{name},</if>
- <if test="email != null">email=#{email},</if>
- <if test="phone != null">phone=#{phone},</if>
- </set>
- where stud_id=#{id}
- </update>
这里,如果<if>条件返回了任何文本内容,<set>将会插入set关键字和其文本内容,并且会剔除将末尾的 “,”。 在上述的例子中,如果 phone!=null,<set>将会让会移除 phone=#{phone}后的逗号“,”,
生成 set phone=#{phone} 。
注解SQL
- Insert
- public interface StudentMapper
- {
- @Insert("INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,ADDR_ID, PHONE)
- VALUES(#{studId},#{name},#{email},#{address.addrId},#{phone})")
- int insertStudent(Student student);
- }
使用了@Insert 注解的 insertMethod()方法将返回 insert 语句执行后影响的行数。
[自动生成主键]
MySQL
- @Insert("INSERT INTO STUDENTS(NAME,EMAIL,ADDR_ID, PHONE)
- VALUES(#{name},#{email},#{address.addrId},#{phone})")
- @Options(useGeneratedKeys = true, keyProperty = "studId")
- int insertStudent(Student student);
Oracle
- @Insert("INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,ADDR_ID, PHONE)
- VALUES(#{studId},#{name},#{email},#{address.addrId},#{phone})")
- @SelectKey(statement="SELECT STUD_ID_SEQ.NEXTVAL FROM DUAL",
- keyProperty="studId", resultType=int.class, before=true)
- int insertStudent(Student student);
如果你使用序列作为触发器来设置主键值,我们可以在 INSERT 语句执行后,从 sequence_name.currval 获取数据 库产生的主键值。
- @Insert("INSERT INTO STUDENTS(NAME,EMAIL,ADDR_ID, PHONE)
- VALUES(#{name},#{email},#{address.addrId},#{phone})")
- @SelectKey(statement="SELECT STUD_ID_SEQ.CURRVAL FROM DUAL",
- keyProperty="studId", resultType=int.class, before=false)
- int insertStudent(Student student);
@font-face { font-family: "Courier New"; }@font-face { font-family: "宋体"; }@font-face { font-family: "Cambria Math"; }@font-face { font-family: "@宋体"; }@font-face { font-family: "Calibri"; }@font-face { font-family: "Menlo"; }p.MsoNormal, li.MsoNormal, div.MsoNormal { margin: 0cm 0cm 0.0001pt; text-align: justify; font-size: 12pt; font-family: Calibri; }h1 { margin: 17pt 0cm 16.5pt; text-align: justify; line-height: 240%; page-break-after: avoid; font-size: 22pt; font-family: Calibri; }pre { margin: 0cm 0cm 0.0001pt; font-size: 10pt; font-family: "Courier New"; }span.HTML { font-family: "Courier New"; }.MsoChpDefault { font-family: Calibri; }div.WordSection1 { }
Dao
StudentDao
package org.zln.dao;
import java.io.IOException;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.zln.domain.Student;
import org.zln.mapper.StudentMapper;
import org.zln.utils.DBAccess;
/**
* Created by sherry on 16/7/15.
*/
public class StudentDao {
public List<Student> findAllStudents() throws IOException {
SqlSession sqlSession = DBAccess.getSqlSession();
try{
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
return studentMapper.findAllStudents();
} finally{
sqlSession.close();
}
}
public Student findStudentById(Integer studId) throws IOException {
SqlSession sqlSession = DBAccess.getSqlSession();
try {
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
return studentMapper.findStudentById(studId);
} finally {
sqlSession.close();
}
}
public void createStudent(Student student) throws IOException {
SqlSession sqlSession = DBAccess.getSqlSession();
try {
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
studentMapper.insertStudent(student);
sqlSession.commit();
}finally{
sqlSession.close();
}
}
}
Mapper接口
StudentMapper
package org.zln.mapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.zln.domain.Student;
import java.util.List;
/**
* Created by sherry on 16/7/15.
* Student的Mapper接口
*/
public interface StudentMapper {
List<Student> findAllStudents();
@Select("SELECT stud_id AS studId, name, email, dob FROM Student WHERE STUD_ID=#{Id}")
Student findStudentById(Integer id);
@Insert("INSERT INTO Student(stud_id,name,email,dob) VALUES(#{studId},#{name},#{email},#{dob})")
void insertStudent(Student student);
}
映射文件