MyBatis动态SQL的示例
创始人
2024-12-17 19:02:30
0次

动态 SQL

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。

动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。

准备

首先创建User实体类

public class User {
    private Integer id;
    private String username;
    private String userEmail;
    private String userCity;
    private Integer age;}

创建user表

CREATE TABLE user (
  id int(11) NOT NULL AUTO_INCREMENT,
  username varchar(255) DEFAULT NULL,
    user_email varchar(255) DEFAULT NULL,
    user_city varchar(255) DEFAULT NULL,
    age int(11) DEFAULT NULL,
  PRIMARY KEY (id))

if

定义接口方法

public List findByUser(User user);

接口对应的 Mapper.xml 定义如下所示


    select
    id, username, user_email userEmail, user_city userCity, age
    from user
    where    
        username = #{username}    
    
        and user_email = #{userEmail}    
    
        and user_city = #{userCity}    

如果if标签上的test为true,那么if标签里面的SQL语句将会被拼接。

如果username、userEmail、userCity都不为空,那么SQL将会拼接成如下所示

select id, username, user_email userEmail, user_city userCity, age 
from user where username = ? and user_email = ? and user_city = ?

如果只有username不为空,那么SQL将会拼接成如下所示

select id, username, user_email userEmail, user_city userCity, age 
from user where username = ?

但是这种方式存在一个缺点,假设此时username为空,userEmail、userCity都不为空。

我们来分析动态 SQL 代码,现在没有给 username 赋值,即 username==null,所以 “username=#{username}” 这段代码不会添加到 SQL 语句中,那么最终拼接好的动态 SQL 是这样的:

select id, username, user_email userEmail, user_city userCity, age 
from user where and user_email = ? and user_city = ?

where 后面直接跟 and,很明显的语法错误,此时应该把紧跟在where后面的and删掉。为了解决这个问题,可以使用where标签。

where

将上面的SQL改成如下所示

    
        select
        id, username, user_email userEmail, user_city userCity, age        from user
        
            
                username = #{username}
            
            
                and user_email = #{userEmail}
            
            
                and user_city = #{userCity}
            
        
    

如果where标签里面的if标签有满足条件的,那么where标签就会被拼接成where语句,若if标签拼接的SQL最前面有and语句,那么这个and将会被删除。使用这种方法, 会自动删除SQL中不需要的关键字,所以一般 if 标签和 where 标签会组合起来使用。

trim

trim标签中的 prefix和 suffix属性会被用于生成实际的 SQL 语句,会和标签内部的语句拼接。

如果语句的前面或后面遇到 prefixOverrides或 suffixOverrides属性中指定的值,MyBatis 会自动将它们删除。在指定多个值的时候,别忘了每个值后面都要有一个空格,保证不会和后面的 SQL 连接在一起。

prefix:给拼接的SQL语句加一个前缀

suffix:给拼接的SQL语句加一个后缀

prefixOverrides:拼接的SQL语句前面遇到 prefixOverrides,MyBatis 会自动将它们删除

suffixOverrides:拼接的SQL语句后面遇到 suffixOverrides,MyBatis 会自动将它们删除

下面使用trim标签来实现where标签的功能


        select
        id, username, user_email userEmail, user_city userCity, age
        from user        
            
                username = #{username}            
            
                and user_email = #{userEmail}            
            
                and user_city = #{userCity}            
        
    

如果username为空,userEmail和userCity不为空,那么if 标签拼接的SQL语句如下所示

and user_email = #{userEmail} and user_city = #{userCity}

因为trim标签设置了prefixOverrides=”and”,而上面的SQL前面有and语句,所以需要将上面的and语句删掉,又因为trim标签设置了prefix=”where”,所以需要在拼接的SQL语句前面加一个where语句

最后trim标签的SQL语句被拼接成如下所示

where user_email = #{userEmail} and user_city = #{userCity}

choose

有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。


        select
        id, username, user_email userEmail, user_city userCity, age
        from user        
            
                
                    username = #{username}                
                
                    and user_email = #{userEmail}                
                
                    and user_city = #{userCity}                
            
        
    

set

set 标签用于 Update 操作,会自动根据参数选择生成 SQL 语句。

接口定义如下

public int updateUser(User user);

接口对应的 Mapper.xml 定义如下所示


       update user       
           
               username=#{username},           
           
               user_email=#{userEmail},           
           
               user_city=#{userCity},           
           
              age=#{age}           
       
       where id=#{id}    

foreach

foreach 标签可以迭代生成一系列值

*用于 SQL 的 in 语句 *

接口定义如下所示

public List getUsersByIds(List ids);

接口对应的 Mapper.xml 定义如下所示


    select * from user
    where id in    
        #{id}    

用于批量插入

接口定义如下所示

public int addUserList(List users);

接口对应的 Mapper.xml 定义如下所示


    insert into user
    (username, user_email, user_city, age)
    values    
        (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age})    
    insert into user
    (username, user_email, user_city, age)
    values    
        (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age})    
    
        insert into user
        (username, user_email, user_city, age)
        values
        (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age})    
    
        insert into user
        (username, user_email, user_city, age)
        values
        (#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age});    

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...