广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Mybatis如何使用ognl表达式实现动态sql
  • 822
分享到

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

2024-04-02 19:04:59 822人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

本文讲述在mybatis中如何使用ognl表达式实现动态组装sql语句 新建Users实体类: public class Users { private Integer

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

新建Users实体类:


public class Users {
    private Integer uid;
    private String userName;
    private String tel;
    //添加上面私有字段的get、set方法
}

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


public interface UserDao {
    
    List<Users> listUser(Users user);
    
    List<Users> listUser2(Users user);
    
    List<Users> listUser3(Integer[] uids);
    
    void updateUser(Users user);
    
    void addBatch(List<Users> list);
    
    void deleteBatch(int[] ids);
    
    void updateBatch1(List<Users> list);
    
    void updateBatch2(List<Users> list);
}

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


<?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指定Dao接口的完整类名,
因为mybatis在解析的时候要根据这个类名找到相应dao方法执行 --><mapper namespace="">   </mapper>

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


<!-- 动态查询(使用if拼接条件,适用于多选多的形式) -->
<select id="listUser" parameterType="users" resultMap="userMap">
    select u_id, u_name, u_tel from user_info4 user_info
    <where>
        <if test="userName != null and userName !=''">
            u_name = #{userName}
        </if>
        <if test="tel != null and tel !=''">
            and u_tel = #{tel}
        </if>
    </where>
</select>

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

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


<!-- 动态查询(使用choose选择条件,适用于多选一) -->
<select id="listUser2" parameterType="users" resultMap="userMap">
    select u_id, u_name, u_tel from user_info4
    <choose>
        <when test="userName != null and userName != ''">
            where u_name = #{userName}
        </when>
        <when test="tel != null and tel != ''">
            where u_tel = #{tel}
        </when>
        <otherwise>
            order by u_id desc
        </otherwise>
    </choose>
</select>

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

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


<!-- 动态查询(使用foreach范围查询,适用于in和or语句) -->
<!-- int[] ids = new int[]{1,2,3,4}; -->
<select id="listUser3" parameterType="collection" resultMap="userMap">
    select u_id, u_name, u_tel from user_info4
    <where>
        u_id in
        <if test="array != null">
            <foreach collection="array" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </if>
    </where>
</select>

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


<!-- 动态更新(使用set动态更新字段) -->
<update id="updateUser" parameterType="users" >
    update user_info4
    <trim prefix="set" suffixOverrides=",">
        <if test="userName != null and userName != ''">
            u_name = #{userName},
        </if>
        <if test="tel != null and tel != ''">
            u_tel = #{tel}
        </if>
    </trim>
    <!-- where u_id = #{uid} -->
    <where>
        u_id = #{uid}
    </where>
</update>

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


<!-- 批量添加,利用sql的特性 -->
<insert id="addBatch" parameterType="list">
    insert into user_info4(u_id, u_name, u_tel) values
    <foreach collection="list" item="user" separator=",">
        (#{user.uid}, #{user.userName}, #{user.tel})
    </foreach>
</insert>

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

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


<!-- 批量更新1,这一种方式兼容性较好,当数据量大时 -->
<update id="updateBatch1" parameterType="list">
    <foreach collection="list" item="user" separator=";">
        update user_info4
        <set>
            u_name = #{user.userName}
        </set>
        where u_id = #{user.uid}
    </foreach>
</update>

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


<!-- 批量更新2,使用MySQL的case when语句 -->
    <update id="updateBatch2" parameterType="list">
        update user_info4 set u_name = case u_id
        <foreach collection="list" item="user" separator=" ">
            when #{user.uid} then #{user.userName}
        </foreach>
        end
        where u_id in
        <foreach collection="list" item="user" open="(" close=")" separator=",">
            #{user.uid}
        </foreach>
    </update>

这里使用的是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表达式;

举个栗子:


<code class="language-xml hljs  has-numbering"><span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"demo1"</span> <span class="hljs-attribute">...</span>></span>
</code><pre name="code" class="prettyprint"><code class="language-xml hljs  has-numbering">    select id, name from users
    <span class="hljs-tag"><<span class="hljs-title">bind</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"nameLike"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"'%' + name + '%'"</span>/></span>
    <span class="hljs-tag"><<span class="hljs-title">where</span>></span>
        <span class="hljs-tag"><<span class="hljs-title">if</span> <span class="hljs-attribute">test</span>=<span class="hljs-value">"name != null and name != ''"</span>></span>
            name like '${nameLike}'
        <span class="hljs-tag"></<span class="hljs-title">if</span>></span>
    <span class="hljs-tag"></<span class="hljs-title">where</span>></span>
<span class="hljs-tag"></<span class="hljs-title">select</span>></span></code>

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

2)${param}参数中


<code class="language-xml hljs  has-numbering"><span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"demo2"</span> <span class="hljs-attribute">...</span>></span>
    select id,name from users
    <span class="hljs-tag"><<span class="hljs-title">where</span>></span>
        <span class="hljs-tag"><<span class="hljs-title">if</span> <span class="hljs-attribute">test</span>=<span class="hljs-value">"name != null and name != ''"</span>></span>
            name like '${'%' + name + '%'}'
        <span class="hljs-tag"></<span class="hljs-title">if</span>></span>
    <span class="hljs-tag"></<span class="hljs-title">where</span>></span>
<span class="hljs-tag"></<span class="hljs-title">select</span>></span></code>

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

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

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

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


    <select id="getRecentQuestionTitle" parameterType="java.lang.String" resultType="java.lang.String">  
            select title from song_question where questionState = #{value}   
            <if test="@Ognl@isSolve(value[0],0)">  
            order by questionTime desc   
            </if>  
            <if test="@Ognl@isSolve(value[0],1)">  
            order by answerTime desc   
            </if>                
            limit 0,1  
      </select>  

静态方法如下:


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排序。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: Mybatis如何使用ognl表达式实现动态sql

本文链接: https://www.lsjlt.com/news/127976.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Mybatis如何使用ognl表达式实现动态sql
    本文讲述在mybatis中如何使用ognl表达式实现动态组装sql语句 新建Users实体类: public class Users { private Integer ...
    99+
    2022-11-12
  • Mybatis怎么使用ognl表达式实现动态sql
    这篇文章主要为大家展示了“Mybatis怎么使用ognl表达式实现动态sql”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Mybatis怎么使用ognl表达式实现动态sql”这篇文章吧。新建Us...
    99+
    2023-06-15
  • Mybatis中的动态sql怎么利用OGNL表达式进行处理
    Mybatis中的动态sql怎么利用OGNL表达式进行处理?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。常用的Mybatis动态sql标签有6种:  &nb...
    99+
    2023-05-31
    mybatis ognl表达式 动态sql
  • MyBatis动态SQL表达式怎么使用
    本篇内容介绍了“MyBatis动态SQL表达式怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!动态 sql 简单来讲就是我们能通过条件...
    99+
    2023-07-04
  • 如何正确的使用OGNL表达式
    如何正确的使用OGNL表达式?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一.OGNL中的#、%和$符号    &nbs...
    99+
    2023-05-31
    ognl表达式 og
  • 如何理解CASE表达式作用及使用SQLServerCASE 表达式代替动态SQL
    本篇文章为大家展示了如何理解CASE表达式作用及使用SQLServerCASE 表达式代替动态SQL,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。  SQLServ...
    99+
    2022-10-19
  • java如何利用JEXL实现动态表达式编译
    小编给大家分享一下java如何利用JEXL实现动态表达式编译,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!背景做项目突然遇到这样的需求:系统要获取多个数据源的数据...
    99+
    2023-06-14
  • Mybatis在注解上如何实现动态SQL
    目录在注解上实现动态SQL注解的动态语句支持以下注解方式动态sql写法和注意事项判断字符串为空串 用单引号大于等于用小于等于用在注解上实现动态SQL 使用Mybatis注解实现sql...
    99+
    2022-11-13
  • java利用JEXL实现动态表达式编译
    背景 做项目突然遇到这样的需求: 系统要获取多个数据源的数据,并进行处理,最后输出多个字段。字段的计算规则一般是简单的取值最多加一点条件判断。 而且需要动态变动!!例如一个字段a的取...
    99+
    2022-11-12
  • 使用MyBatis如何动态调用SQL标签
    今天就跟大家聊聊有关使用MyBatis如何动态调用SQL标签,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、动态SQL片段通过SQL片段达到代码复用 <!--&nb...
    99+
    2023-05-31
    mybatis sql标签
  • MyBatis-Plus动态表名如何使用
    本篇内容介绍了“MyBatis-Plus动态表名如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!MyBatis-Plus实现动态表名M...
    99+
    2023-07-05
  • MyBatis在注解上如何使用动态SQL
    这篇文章主要介绍了MyBatis在注解上如何使用动态SQL的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇MyBatis在注解上如何使用动态SQL文章都会有所收获,下面我们一起来看看吧。MyBatis在注解上使用...
    99+
    2023-07-02
  • sql server 中如何使用公共表达式
    sql server 中如何使用公共表达式,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、前言    现在做项目数据访问基本...
    99+
    2022-10-18
  • Mybatis如何实现@Select等注解动态组合SQL语句
    目录一、背景说明二、实现方案三、 实现自定义注解1、自定义Select注解2、自定义Select in注解3、自定义Update的注解4、自定义Insert的注解 同理四、...
    99+
    2022-11-13
  • MyBatis动态SQL如何实现前端指定返回字段
    目录动态SQL实现前端指定返回字段问题描述解决方案MyBatis如何返回部分字段.xml文件中resultMap的type改为第二种很笨的方法动态SQL实现前端指定返回字段 问题描述...
    99+
    2022-11-13
  • SpringBoot使用Mybatis注解实现分页动态sql开发教程
    目录一、环境配置二、Mybatis注解三、方法参数读取1.普通参数读取2.对象参数读取四、分页插件的使用五、动态标签六、完整示例一、环境配置 1.引入mybatis依赖 co...
    99+
    2022-11-13
  • 利用Java如何获取Mybatis动态生成的sql接口实现
    目录前言1、编写xml: SqlGenarate.mapper.xml2、定义接口3、实现接口总结前言 如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 S...
    99+
    2022-11-12
  • 如何在MyBatis动态SQL项目中使用trim标签
    这期内容当中小编将会给大家带来有关如何在MyBatis动态SQL项目中使用trim标签,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。具体方法如下:select * from user   <...
    99+
    2023-05-31
    mybatis sql trim
  • T-SQL中如何使用正则表达式函数
    今天就跟大家聊聊有关T-SQL中如何使用正则表达式函数,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。首先,我们在VSTS中创建一Database P...
    99+
    2022-10-18
  • C#如何使用表达式树动态更新类的属性值
    本篇内容介绍了“C#如何使用表达式树动态更新类的属性值”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!C#的&lambda;表达式树是...
    99+
    2023-06-26
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作