Mybatis中的ognl表达式。及myabtis where标签/if test标签/trim标签
1.mybatis默认支持使用ognl表达式来生成动态sql语句
MyBatis中可以使用OGNL的地方有两处:
- 动态SQL表达式中
- ${param}参数中
上面这两处地方在MyBatis中处理的时候都是使用OGNL处理的。

<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 会变成这样:
SELECT * FROM BLOG
WHERE
这会导致查询失败。如果仅仅第二个条件匹配又会怎样?这条 SQL 最终会是这样:
SELECT * FROM BLOG
WHERE
AND title like ‘yiibai.com’
这个查询也会失败。这个问题不能简单的用条件句式来解决,如果你也曾经被迫这样写过,那么你很可能从此以后都不想再这样去写了。
MyBatis 有一个简单的处理,这在90%的情况下都会有用。而在不能使用的地方,你可以自定义处理方式来令其正常工作。一处简单的修改就能得到想要的效果:

<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 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。
如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制我们想要的功能。比如,和 where 元素等价的自定义 trim 元素为:
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
今天遇到一个场景需要写一个这样的查询语句:
用户对象userInfo包含下面几个字段:
userName phone email qqId weiboId wxId
现在新注册用户,传过来一个注册userInfo对象,现在要到数据库中验证状态status=1 (表示激活的用户)的用户中,是否存在一个用户,只要它这些字段中至少有一个与新注册的对象对应的字段内容相同,那就说明重复注册。
翻译成sql语句表示一下的意思大概就是:
select * from tablename where
(
userName=”xxx”
or phone =”xxx”
or …
)
and status=1
一开始我是这样写的,在mybatis中的代码就是这样:
<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>
ok搞定。
- <select id="getStudentList_if" resultMap="resultMap_studentEntity" parameterType="liming.student.manager.data.model.StudentEntity">
- SELECT ST.STUDENT_ID,
- ST.STUDENT_NAME,
- ST.STUDENT_SEX,
- ST.STUDENT_BIRTHDAY,
- ST.STUDENT_PHOTO,
- ST.CLASS_ID,
- ST.PLACE_ID
- FROM STUDENT_TBL ST
- WHERE
- <if test="studentName !=null ">
- ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')
- </if>
- <if test="studentSex != null and studentSex != '' ">
- AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}
- </if>
- <if test="studentBirthday != null ">
- AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}
- </if>
Mybatis中的ognl表达式。及myabtis where标签/if test标签/trim标签的更多相关文章
- MyBatis中使用OGNL表达式与操作符
String与基本数据类型 _parameter 自定义类型(对象) 属性名 集合 数组 array List list Map _parameter 获取集合中的一条数据 数组 array[索引] ...
- Mybatis中关于OGNL表达式冲突
注意设计表字段不能用bor xor and band eq neq lt gt lte gte shl shr ushr
- MyBatis中的OGNL教程
MyBatis中的OGNL教程 有些人可能不知道MyBatis中使用了OGNL,有些人知道用到了OGNL却不知道在MyBatis中如何使用,本文就是讲如何在MyBatis中使用OGNL. 如果我们搜索 ...
- struts2框架之OGNL表达式概述(在代码中使用OGNL表达式)
1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写 * 所谓对象图,即以任意一个对象为根,通过OGNL可以访问与这个对象关联的其它对象 * 通 ...
- Struts2中的OGNL表达式
一.OGNL表达式简介 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目.所谓对象图,即以任意一个对象为根,通过OGNL可以访问 ...
- (补充)9.Struts2中的OGNL表达式
OGNL表达式概述 1. OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写 * 所谓对象图,即以任意一个对象为根,通过OGNL可以访问与这个对象关 ...
- struts2中使用ognl表达式时各种符号的使用规则$,#,%
OGNL表达式struts2标签“%,#,$” 一.什么是OGNL,有什么特点? OGNL(Object-Graph Navigation Language),大概可以理解为:对象图形化导航语言.是一 ...
- 在Struts2框架中使用OGNL表达式(在jsp页面中使用OGNL表达式)
1. Struts2引入了OGNL表达式,主要是在JSP页面中获取值栈中的值 2. 具体在Struts2中怎么使用呢?如下步骤 * 需要先引入Struts2的标签库(在JSP页面的最上面位置) > ...
- 2018.11.24 struts2中的OGNL表达式及两者的结合
OGNL表达式 OGNL:对象视图导航语言. ${user.addr.name} 这种写法就叫对象视图导航. OGNL不仅仅可以视图导航.支持比EL表达式更加丰富的功能. 理解图示 使用OGNL准备工 ...
随机推荐
- 掌握Spark机器学习库-05-spark中矩阵与向量的使用
1)介绍 矩阵: Matrix,看做二维表,基本运算(+,-,*,T) 向量: Vectors,方向和大小,基本运算,范数 2)spark中向量的使用(主要使用breeze.linalg) 3)spa ...
- asp.net 实现treeview 选中父节点其子节点也选种中 选中子节点其父节点与根节点也被选中
1.在 Page_Load(object sender, EventArgs e) 里面加入: TreeView1.Attributes.Add("onclick", " ...
- Asp.Net 设计模式 之 “简单工厂”模式
主要思想: public static Operation CreateFactory(string ope) { //实例化空父类,让父类指向子类 ...
- redis 其他特性
1.消息订阅与发布 subscribe my1 订阅频道 psubscribe my1* 批量订阅频道,订阅以my1开头的所有频道 publish my1 hello 在指定频道中发布消息,返回值为接 ...
- USB设备请求命令详解
USB设备请求命令 :bmRequestType + bRequest + wValue + wIndex + wLength 编号 值 名称 (0) 0 GET_STATUS:用来返回特定接收者 ...
- 2.10.3 nav 元素
nav <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <tit ...
- JFinal项目eclipse出现the table mapping of model: com.gexin.model.scenic.Scenic not exists or the ActiveRecordPlugin not start.
JFinal项目eclipse出现the table mapping of model: com.gexin.model.scenic.Scenic not exists or the ActiveR ...
- pytorch: Variable detach 与 detach_
pytorch 的 Variable 对象中有两个方法,detach和 detach_ 本文主要介绍这两个方法的效果和 能用这两个方法干什么. detach 官方文档中,对这个方法是这么介绍的. 返回 ...
- 2D热力图实例
<div style="height: 100px; width: 200px" id="heatmap"></div> <scr ...
- HTML5页面直接调用百度地图API,获取当前位置,直接导航目的地
<!DOCTYPE html> <html lang="zh-cmn-Hans"> <meta charset="UTF-8"&g ...