Mybatis如何使用ognl表达式实现动态sql

网友投稿 1168 2023-01-11

Mybatis如何使用ognl表达式实现动态sql

Mybatis如何使用ognl表达式实现动态sql

本文讲述在mybatis中如何使用ognl表达式实现动态组装sql语句

新建Users实体类:

public class Users {

private Integer uid;

private String userName;

private String tel;

//添加上面私有字段的get、set方法

}

新建一个Dao接口类,mybatis配置文件在配置namespace属性时需要加入这个类的完整类名,找到这个类里的方法执行:

public interface UserDao {

/**

* 依据userName查询用户信息

* @param user

bUzCZX * @return

*/

List listUser(Users user);

/**

* 动态选择条件

* @param user

* @return

*/

List listUser2(Users user);

/**

* 动态范围查询

* @param uids

* @return

*/

List listUser3(Integer[] uids);

/**

* 动态更新用户信息

* @param user

*/

void updateUser(Users user);

/**

* 批量添加

* @param list

*/

void addBatch(List list);

/**

* 批量删除

* @param ids

*/

void deleteBatch(int[] ids);

/**

* 批量更新

* @param list

*/

void updateBatch1(List list);

/**

* 批量更新

* @param list

*/

void updateBatch2(List list);

}

新建mybatis的配置文件(下面代码可以作为mybatis配置文件的模板,这里的namespace属性可以设置为上面的dao类的完整类名):

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

在mybatis配置文件中写一条条件查询sql语句:

select u_id, u_name, u_tel from user_info4 user_info

u_name = #{userName}

and u_tel = #{tel}

这里使用了where和if标签,意思就是sql语句中的where,当然,where直接在sql中写出来也可以,标签就是条件判断,test属性中写条件语句,如果test中的条件语句为true,那么标签中的sql语句就会拼接到上面的sql语句中,所以这条sql语句的意思就是如果传过来的Users对象中,userName字段不为null,或字段值不为空,那么就添加一个对userName的查询,tel也是如此。

注意:在对tel字段的判断时,标签中的sql语句前加了一个and,如果前一条判断为false,那么mybatis会自动将and关键字删除。

select u_id, u_name, u_tel from user_info4

where u_name = #{userName}

where u_tel = #{tel}

order by u_id desc

这里使用的是choose-when-otherwise标签,有点类似于java中的switch-case-default选择条件语句,相比于if标签,这里只能选择一个,即多选一。

在这条sql语句中,会按顺序判断when子句,如果所有的when子句都为false,则会执行otherwise子句中的sql语句。

select u_id, u_name, u_tel from user_info4

u_id in

#{id}

foreach标签适用于范围查询(in和or语句),如遍历一个id集合,查询出集合中所有id对应的用户。在foreach标签中,collection属性指定需要遍历的集合的名称,这里只有一个参数,所以可以随意取;item指定遍历的每一项的别名,open指定在遍历前需要加上的内容,separator指定每遍历一个后加上的内容,close指定遍历完后需要加上的内容,如遍历上面的ids集合,那么最终得到的内容就是 (1,2,3,4) 。

update user_info4

u_name = #{userName},

u_tel = #{tel}

u_id = #{uid}

trim标签用于动态设值,例如在更新数据时,可以动态将改变的字段设置。在trim标签中,prefix属性表示在更新字段之前添加set关键字,suffixOverrides表示将最后一个更新字段的逗号替换成suffix指定的空格符,如果不指定suffix默认就是空格。

insert into user_info4(u_id, u_name, u_tel) values

(#{user.uid}, #{user.userName}, #{user.tel})

foreach标签不仅可以用于范围查询,还可以遍历集合用于批量添加。

因为可以利用sql的特性,例如:insert into user_info4(u_name, u_tel) values('', ''), ('', ''), ('', '');这样执行这条sql语句就可以实现批量添加。

update user_info4

u_name = #{user.userName}

where u_id = #{user.uid}

foreach还可以用于遍历出多条sql语句,使得一次可以执行多条sql,当然,如果需要mysql执行多条批量操作时,需要开启批量查询功能,即在MySql的url中加入 allowMultiQueries=true 。

update user_info4 set u_name = case u_id

when #{user.uid} then #{user.userName}

end

where u_id in

#{user.uid}

这里使用的是MySql中的case when语句来更新的,基本语法:

update user_info4 set u_name = case u_id

  when 3 then '游客1'

  when 4 then '游客2'

  end

  where u_id in(3,4);

Mybatis中的ognl使用总结

经常在写mapper中用到一些OGNL,但是没怎么总结,使用方法一直模模糊糊的。抽点时间,查了别人的blog,做个简单的总结

1.概念

OGNL,Object Graph Navigation Language,是一种强大的表达式语言,网上搜索这个概念,多是和structs有关的。但是在mybatis中OGNL应用很广的;

2.基本参数

Mybatis中常用的OGNL表达式有以下:

e1 or e2

e1 and e2

e1 == e2,e1 eq e2

e1 != e2,e1 neq e2

e1 lt e2:小于

e1 lte e2:小于等于,其他gt(大于),gte(大于等于)

e1 in e2

e1 not in e2

e1 + e2,e1 * e2,e1/e2,e1 - e2,e1%e2

!e,not e:非,求反

e.method(args)调用对象方法

e.property对象属性值

e1[ e2 ]按索引取值,List,数组和Map

@class@method(args)调用类的静态方法

@class@field调用类的静态字段值

更加详细的介绍可以参考官网的介绍:https://commons.apache.org/proper/commons-ognl/language-guide.html

在一定意义上说,mybatis中的动态sql也是基于OGNL表达式的。其中常用的元素有如下几种:

if

choose(when,otherwise)

trim

where

set

foreach

3.应用;

OGNL在mybatis中的应用,主要有两种;

1)动态SQL表达式;

举个栗子:

&lhttp://t;code class="language-xml hljs has-numbering"><select id="demo1" ...>

<bind name="nameLike" value="'%' + name + '%'"/>

<where>

<if test="name != null and name != ''">

name like '${nameLike}'

if>

where>

select>

其中的bind中的value值会使用OGNL计算,ps,其中bind的参数调用只能用$获取;

2)${param}参数中

<select id="demo2" ...>

select id,name from users

<where>

<if test="name != null and name != ''">

name like '${'%' + name + '%'}'

if>

where>

select>

此处写的是 ${'%' + name + '%'},而不是 %${name}%,这两种方式的结果一样,但是处理过程不一样。

ps,说明一下#和$的区别:${} 为原样输出,你传什么,sql里就填入什么,比如有引号它也会原样填到sql里。#{} 会使用 PreparedStatement,变量处用 ? 代替。

在能使用 #{} 尽量使用它吧,可以防止sql注入。

以下是一个OGNL的调用静态方法的示例:

select title from song_question where questionState = #{value}

order by questionTime desc

order by answerTime desc

limit 0,1

静态方法如下:

public static boolean isSolve(Object o,String soleState){

if(o == null)

return false;

String str = null;

if(o instanceof String[]){

String[]objects = (String[])o;

str = objects[0];

}else if(o instanceof Character){

Character c = (Character) o;

str = Character.toString(c);

}

if(StringUtils.equals(str, soleState))

return true;

return false;

}

如果值为0,则order by questionTime desc 根据字段questionTime排序。

如果值为1,则order by answerTime desc根据字段answerTime排序。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:小程序生态流量监控怎么用(小程序监控软件)
下一篇:解析ConcurrentHashMap:成员属性、内部类、构造方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~