【问题标题】:Using enum parameters in myBatis dynamic SQL在 myBatis 动态 SQL 中使用枚举参数
【发布时间】:2012-10-17 11:58:33
【问题描述】:

myBatis 3.1.1如何基于枚举常量参数做动态SQL?

【问题讨论】:

  • After MyBatis 3.4.1,如果你的 mapper 方法只有一个参数是 enum 类型并且你没有用 @Param 注释它,例如,那个 enum 类型是 Gender,你可以使用test="name == 'MALE'".

标签: string enums ibatis dynamic-sql mybatis


【解决方案1】:

如何根据枚举常量做动态SQL

public enum Test {
    A, B;
}

Mapper.java:
    int test(@Param("t") Test t);

Mapper.xml:
    <select id="test" resultType="int">
        select
        <choose>
            <when test='t.name().equals("A")'>65</when>
            <when test='t.name().equals("B")'>66</when>
            <otherwise>0</otherwise>
        </choose>
    </select>   

备注

  • 测试表达式必须使用双引号而不是单引号引用字符串。
  • 不能比较常量,只能比较字符串。

【讨论】:

  • 如果 t 为 null,则会抛出 NullPointerException
【解决方案2】:

MyBatis 允许== 代替equals 用于if(或when)语句中的字符串。所以以下也可以工作(引号无关紧要):

public enum Test {
    A, B;
}

Mapper.java:

int test(@Param("t") Test t);

Mapper.xml:

<select id="test" resultType="int">
    select
    <choose>
        <when test="t.name() == 'A'">65</when>
        <when test="t.name() == 'B'">66</when>
        <otherwise>0</otherwise>
    </choose>
</select>

【讨论】:

    【解决方案3】:

    除了 Tomer 的回答(效果很好)之外,您还可以使用 OGNL 表示法比较枚举值。

    (直接比较枚举值具有编译时优势,即如果更改枚举成员,查询将很快失败。)

    如果 Test 枚举作为公共类 Test.java 存在于 full.package.name 中,那么在 mapper.xml 中,您将拥有:

    <when test='t == @full.package.name.Test@A'>
    

    如果测试枚举在另一个类中,像这样:

    package full.package.name;
    
    public class ExampleClass {
        public enum Test {
            A, B
        }
    }
    

    然后,在 mapper.xml 中,您将拥有:

    <when test='t == @full.package.name.ExampleClass$Test@A'>
    

    $ 符号在 OGNL 规范中没有记录,我找到了 in the MyBatis issues page

    PS:如果 OGNL 字符串不正确(如 NullPointerException),旧版本的 MyBatis(例如 3.2.3)会显示丑陋的错误。较新的版本显示更容易理解的错误。

    【讨论】:

      【解决方案4】:
      public enum Test {
          A, B;
      }
      
      Mapper.java:
          int test(@Param("t") Test t);
      
      Mapper.xml:
          <select id="test" resultType="int">
              select
              <choose>
                  **<when test='t.name() == &quot;A&quot;'>65</when>
                  <when test='t.name() == &quot;A&quot;'>66</when>**
                  <otherwise>0</otherwise>
              </choose>
          </select>   
      
      is another solution.
      

      【讨论】:

        猜你喜欢
        • 2019-07-22
        • 1970-01-01
        • 2011-02-22
        • 1970-01-01
        • 2011-10-27
        • 2021-09-13
        • 2012-04-16
        • 1970-01-01
        • 2020-08-11
        相关资源
        最近更新 更多