系列文章目录
第一篇:3分钟快速了解Mybatis的基础配置
第二篇:带你3分钟了解Mybatis映射文件(sql,resultMap等映射)
前言
原创不易,如若喜欢,请点一点赞吧!!!!!!!!
动态sql语句是mybatis的强大特性之一,通过sql动态语句,可以简化sql语句写法的复杂性,减少sql语句代码量。可以帮助开发人员在编写sql功能语句时事倍功半。
一、动态sql语句中的元素
- 主要动态sql语句如下:
元素 | 说明 |
---|---|
<if> | 判断语句,用于单条件分支判断 |
<choose>(<when>,<otherwise>) | 相当于java中的switch语句,用于多条件分支判断 |
<where>(<trim>,<set>) | 辅助元素,用于处理一些sql拼装,特殊字符问题 |
<foreach> | 循环语句,常用于in语句等列举条件中 |
<bind> | 从OGNL 表达式中创建一个变量,并将主主绑定到上下文,常用于模糊查询的sql 中 |
二、动态sql
语句用法分析
创建项目,并完成mybatis 基础配置,创建mapper.xml文件,修改mapper.xml文件进行配置。
1.if 动态查询语句
1) 案例分析
在实际应用中,我们可能会通过多个条件来精确地查询某个数据。例如,要查找某个客户的信息,可以通过姓名和职业来查找客户,也可以不填写职业直接通过姓名来查找客户,还可以都不填写而查询出所有客户,此时姓名和职业就是非必须条件。但类似于这种情况,在My8atis中就可以通过
<if>
元素来实现。
<select id="findcustomerByusername" parameterType="org.mybatis.beans.Customer"
resultType="org.mybatis.beans.Customer">
<!-- sql语句中的where 1=1不能省略-->
select * from customer where 1=1
<!-- 通过if条件语句来判断,执行第一条还是第二条或都不执行-->
<if test="username!=null and username!=''">
<!-- 模糊查询concat('%',#{username},'%')-->
and username like concat('%',#{username},'%')
</if>
<if test="jobs!=null and jobs!=''">
and jobs=#{jobs}
</if>
</select>
2)if语句使用分析:
使用<if>
元素的test 属性分别对username 和jobs 进行了非空判断,如果传入的查询条件非空就进行动态SOL 组装。从而查询相应语句。使用if条件语句需要注意,所有的if语句均会被判断,而不是当第一个if语句为真时,则第二条if语句就不会被执行。当两个if语句都不满足条件时,程序会执行select * from customer where 1=1
语句,即将数据表中的所有数据查出。
2. <choose>(<when>,<otherwise>)
动态查询语句
1) 案例分析
"当客户名称不为空,则只根据客户名称进行客户筛选;
当客户名称为空,而客户职业不为空,则只根据客户职业进行客户筛选。
当客户名称和客户职业都为空,则要求查询出所有电话不为空的客户信息。"
在这种情况下,显然使用if语句是不合理的,在mybatis中提供了 `<choose>(<when>,<otherwise>)`语句来实现多分支条件查询
<!--<choose>语句类似于java中的switch语句-->
<select id="findcustomerByusername" parameterType="org.mybatis.beans.Customer"
resultType="org.mybatis.beans.Customer">
select * from customer where 1=1
<!--当满足username不为空时,则拼接username like concat('%',#{username},'%')-->
<!--当满足jobs不为空时,则拼接jobs=#{jobs}-->
<!--当username,jobs均为空时,则拼接and phone is not null-->
<choose>
<when test="username!=null and username!=''">
and username like concat('%',#{username},'%')
</when>
<when test="jobs!=null and jobs!=''">
and jobs=#{jobs}
</when>
<otherwise>
and phone is not null
</otherwise>
</choose>
</select>
2)<choose>(<when>,<otherwise>)
语句使用分析:
- 当满足username不为空时,则拼接username like concat(’%’,#{username},’%’)
- 当满足jobs不为空时,则拼接jobs=#{jobs} ,
- 当username,jobs均为空时,则拼接and phoneis not null
3. <where>(<trim>)>
动态查询语句
1) 案例分析
在前两个案例中,映射文件中编写的sql后面都加入了"where 1 =1" 的条件,如果将"where 1 =1"
条件去掉,则sql语句会出现语法错误那么在MyBatis 中,有没有什么办法不用加入"1 =1" 这样的条件,也能使拼接后的SQL 成立呢?
<!--<where>可以用来抵消select * from customer where 后1=1语句
<select id="findcustomerByusername" parameterType="org.mybatis.beans.Customer"
resultType="org.mybatis.beans.Customer">
<!--where 语句通过标签来写-->
select * from customer
<where>
<if test="username!=null and username!=''">
and username like concat('%',#{username},'%')
</if>
<if test="jobs!=null and jobs!=''">
and jobs=#{jobs}
</if>
</where>
</select>
2)<where>(<trim>)>
语句使用分析:
使用
<where>
元素对"where 1 =1" 条件进行了替换,<where>
元素会自
动判断组合条件下拼装的SQL 语句,只有<where>
元素内的条件成立时,才会在拼接SQL 中加入where 关键字,否则将不会添加;即使where 之后的内容有多余的"AND" 或"OR" ,<where>
元素也会自动将它们去除。
4. <set>
动态查询语句
1) 案例分析
如果想要更新某一个对象,就需要发送所有的字段给持久化对象,然而实际应用中,大多数情况下都是更新的某一个或几个字段。如果更新的每一条数据都要将其所有的属性都更新一遍,那么其执行效率是非常差的。MyBatis 中提供了
<set>
元素来完成这一工作。<set>
元素主要用于更新操作,其主要作用是在动态包含的SOL 语句前输出一个SET关键字,并将SOL 语句中最后一个多余的逗号去除。
<!--set元素主要用于更新数据-->
<update id="updateCustomer" parameterType="org.mybatis.beans.Customer">
update customer
<set>
<if test="username!=null and username!=''">
username = #{username},
</if>
<if test="jobs!=null and jobs!=''">
jobs = #{jobs},
</if>
<if test="phone!=null and phone!=''">
phone = #{phone},
</if>
</set>
where id=#{id}
</update>
2)<set>
语句使用分析:
将set语句与if语句结合起来,可以动态更新想要更新的数据,如果传入的更新字段非空,就将此字段进行动态SOL 组装,并更新此字段,否则此字段不执行更新。
需要注意的是: 在映射文件中使用
<set>
和<if>
元素组合进行update 语句动态SQL 组装时,如果元素内也含的内容都为空,则会出现SQL 语法错误。所以在使用〈忧。元素进行字段信息更新时,要确保传入的更新字段不能都为空。
5. <foreach>
动态查询语句
1) 案例分析
在实际开发中,有时可能会遇到这样的情况:假设在一个客户表中有1000 条数据,现在需要将id 值小于100 的客户信息全部查询出来,一条一条的查询显然是不可取的,mybatis框架中提供了这样一种语句来进行多条数据查询。那就是
<foreach>
动态查询语句
<!-- MyBatis 中已经提供了一种用于数组和集合循环遍历的方式,那就是使用<foreach>元素
<select id="findcustomerByusername" parameterType="org.mybatis.beans.Customer"
resultType="org.mybatis.beans.Customer">
select * from customer where id in
<foreach item="id" index="index" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>
2)<foreach>
语句使用分析:
在上述代码中,使用了元素对传入的集合进行遍历并进行了动态SOL组装。关于
<foreach>
元素中使用的几种属性的描述具体如下。
• item: 配置的是循环中当前的元素。
• index:配置的是当前元素在集合的位置下标。 • collection: 配罩的list 是传递过来的参数类型(首字母小写),它可以是一个array 、list(或collection )、Map 集合的键、POJO 包装类中数组或集合类型的属性名等。
• open 和close:配置的是以什么符号将这些集合元素包装起来。
• separator: 配置的是各个元素的间隔符。
6. <bind>
动态查询语句
1) 案例分析
在进行模糊查询编写SO L 语句的时候,如果使用" ${}"进行字符串拼接,则无法防止SOL注入问题;如果使用concat 函数进行拼接,则只针对MySOL 数据库有效,其他数据库则是不同的写法,因此,很不利于项目的移植,为此, MyBatis 提供了
<bind>
元素来解决这一问题,我们完全不必使用数据库语言,只要使用MyBatis 的语言即可与所需参数连接。
<!-- MyBatis 提供了<bind>元素来解决模糊查询问题,我们完全不必使用数据库语言,
只要使用MyBatis 的语言即可与所需参数连接。
-->
<select id="findcustomerByusername" parameterType="org.mybatis.beans.Customer"
resultType="org.mybatis.beans.Customer">
<bind name="p_username" value="'%'+username+'%'"/>
select * from customer
where
username like #{p_username}
</select>
2)<bind>
语句使用分析:
上述配置代码中,使用
<bind>
元素定义了一个name 为pattern_username 的变量,<bind>
元素中value 的属性值就是拼接的查询字符串,在SOL 语句中,直接引用<bind>
元素的name 属性值即可进行动态SOL 组装。