MyBatis-动态SQL
2018-09-24 11:37
375 查看
目录
一、概述
-
动态SQL是MyBatis的强大特性之一。极大的简化了我们拼装SQL的操作
-
动态SQL元素和使用JSTL或其它类似的基于XML的文本处理器类似
-
MyBatis采用功能强大的基于OGNL的表达式来简化操作
if
-
choose(when,otherwise)
-
trim(where,set)
foreach
二、if
1.格式
[code]<if test=""></if>
2.实例
[code]<!-- 查询员工,要求,携带了哪个字段查询条件就带上这个字段的值 --> <!-- public List<Employee> getEmpsByConditionIf(Employee employee); --> <select id="getEmpsByConditionIf" resultType="com.itheima.domain.Employee"> select * from tbl_employee <!-- where --> <where> <!-- test:判断表达式(OGNL) OGNL参照PPT或者官方文档。 c:if test 从参数中取值进行判断 遇见特殊符号应该去写转义字符: &&: --> <if test="id!=null"> id=#{id} </if> <!-- &为& "为'--> <if test="lastName!=null && lastName!="""> and last_name like #{lastName} </if> <if test="email!=null and email.trim()!="""> and email=#{email} </if> <!-- ognl会进行字符串与数字的转换判断 "0"==0 --> <if test="gender==0 or gender==1"> and gender=#{gender} </if> </where> </select>
三、choose(when,otherwise)
1.格式
[code]<choose> <when test=""></when> <when test=""></when> <otherwise></otherwise> </choose>
2.实例
[code]<!-- public List<Employee> getEmpsByConditionChoose(Employee employee); --> <select id="getEmpsByConditionChoose" resultType="com..itheima.domain.Employee"> select * from tbl_employee <where> <!-- 如果带了id就用id查,如果带了lastName就用lastName查,都不带就查询gender=0的所有数据;只会进入其中一个 --> <choose> <when test="id!=null"> id=#{id} </when> <when test="lastName!=null"> last_name like #{lastName} </when> <otherwise> gender = 0 </otherwise> </choose> </where> </select>
四、trim(where,set)
1.where
在使用if表达式进行查询时,有可能会发生一个问题。
[code]<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE <if test="state != null"> state = #{state} </if> <if test="title != null"> AND title like #{title} </if> <if test="author != null and author.name != null"> AND author_name like #{author.name} </if> </select>
如果这些条件都没能匹配上,最终的SQL语句会变成:
[code]SELECT * FROM BLOG WHERE
如果仅仅第二个条件匹配成功,最终的SQL语句会变成:
[code]SELECT * FROM BLOG WHERE AND title like ‘someTitle’
这时,就可以使用where标签来处理上述问题
[code]<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG <where> <if test="state != null"> state = #{state} </if> <if test="title != null"> AND title like #{title} </if> <if test="author != null and author.name != null"> AND author_name like #{author.name} </if> </where> </select>
where元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。
2.trim
我们也可以用自定义trim元素来定制where元素的功能。
[code]<!-- prefix给拼串后的整个字符串加一个前缀 prefixOverrides="": 前缀覆盖: 去掉整个字符串前面多余的字符 suffix="":后缀 suffix给拼串后的整个字符串加一个后缀 suffixOverrides="" 后缀覆盖:去掉整个字符串后面多余的字符 --> <trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
3.set
-
set元素可以用于动态包含需要更新的列,而舍去其它的
[code]<update id="updateAuthorIfNecessary"> update Author <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </set> where id=#{id} </update>
这里,set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的 SQL 语句的后面留下这些逗号。
set元素的底层为:
[code]<trim prefix="SET" suffixOverrides=","> ... </trim>
五、foreach
1.in(x,y,z...)条件查询
[code]<!-- collection:指定要遍历的集合: list类型的参数会特殊处理封装在map中,map的key就叫list item:将当前遍历出的元素赋值给指定的变量 separator:每个元素之间的分隔符 open:遍历出所有结果拼接一个开始的字符 close:遍历出所有结果拼接一个结束的字符 index:索引。遍历list的时候是index就是索引,item就是当前值 遍历map的时候index表示的就是map的key,item就是map的值 #{变量名}就能取出变量的值也就是当前遍历出的元素 --> <!--public List<Employee> getEmpsByConditionForeach(@Param("ids") List<Integer> ids); --> <select id="getEmpsByConditionForeach" resultType="com.itheima.domain.Employee"> SELECT * FROM tb1_employee WHERE id IN <foreach collection="ids" close=")" separator="," item="items" open="(" > #{items} </foreach> </select>
2.批量保存
[code] <!-- 批量保存 --> <!--public void addEmps(@Param("emps")List<Employee> emps); --> <!--MySQL下批量保存:可以foreach遍历 mysql支持values(),(),()语法--> <insert id="addEmps"> INSERT INTO tb1_employee(NAME,gender,email,did) VALUES <foreach collection="emps" item="items" separator="," > (#{items.name},#{items.gender},#{items.email},#{items.dept.id}) </foreach> </insert>
六、bind
-
bind元素可以从OGNL表达式中创建一个变量并将其绑定到上下文。
[code]<!--public List<Employee> getEmpsTestInnerParameter(Employee employee); --> <select id="getEmpsTestInnerParameter" resultType="com.itheima.domain.Employee"> <bind name="_name" value="'%' + name + '%'" /> SELECT * FROM BLOG WHERE title LIKE #{_name} </select> <!--可以对传过来的Employee的name参数直接进行模糊查询而不需要自己加% -->
七、可重用的sql片段
[code]!-- 抽取可重用的sql片段。方便后面引用 1、sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用 2、include来引用已经抽取的sql: 3、include还可以自定义一些property,sql标签内部就能使用自定义的属性 --> <sql id="insertColumn"> <if test="_databaseId=='oracle'"> employee_id,last_name,email </if> <if test="_databaseId=='mysql'"> last_name,email,gender,d_id </if> </sql> <insert id="addEmps" databaseId="mysql"> insert into tbl_employee( <include refid="insertColumn"></include> ) values <foreach collection="emps" item="emp" separator=","> (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id}) </foreach> </insert>
[code]<sql id="columns"> #{profix}.id,#{profix}.name,#{profix}.age </sql> <select id="getUser"> select <include refid="columns"> <property name="prefix" value="u" /> </include> from user u where r.id=#{id} </select>
八、多数据库支持
一个配置了“_databaseId”变量的 databaseIdProvider 可用于动态代码中,这样就可以根据不同的数据库厂商构建特定的语句。
[code]<insert id="insert"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> <if test="_databaseId == 'oracle'"> select seq_users.nextval from dual </if> <if test="_databaseId == 'db2'"> select nextval for seq_users from sysibm.sysdummy1" </if> </selectKey> insert into users values (#{id}, #{name}) </insert>
阅读更多
相关文章推荐
- MyBatis学习笔记(六)动态sql
- Mybatis动态构建Sql(无实体类)
- MyBatis入门(四)---动态SQL
- MyBatis动态SQL <trim></trim>标签的明白理解
- 工作笔记(一)关于mybatis动态sql,MultipartFile,jsp页面404
- 五,MyBatis动态SQL
- mybatis的动态sql-if和sql片段 foreach的使用
- 一双跑鞋的mybatis(四)---动态sql语句
- 【MyBatis学习07】动态sql
- mybatis动态SQL
- MyBatis的动态SQL详解
- mybatis动态SQL之trim
- MyBatis的动态SQL详解
- mybatis系列-动态 SQL(四)
- MyBatis动态SQL之一使用 if 标签和 choose标签
- Mybatis之动态sql
- MyBatis 动态SQL语句
- MyBatis 动态SQL
- MyBatis的动态sql
- 【JavaEE】之MyBatis动态SQL