【问题标题】:MyBatis - how to create w dynamic WHERE ClauseMyBatis - 如何创建 w 动态 WHERE 子句
【发布时间】:2011-08-28 17:52:15
【问题描述】:

服务获取一个未知对象,其中包含三个值的列表[column, operator, value] 例如, EMAIL - 喜欢 - “测试”

根据结果列表构建我拥有的 WHERE 子句,但我也可以构建如下条件(例如)

WHERE(像“test”这样的电子邮件 AND user_id 5)或(trans_id 500)

有人可以帮我怎么做吗?

【问题讨论】:

    标签: java ibatis mybatis


    【解决方案1】:

    久违的我自己一直在重新发现MyBatis(我曾经熟悉iBatis)。 Rolf 的示例看起来可能是 .Net 实现,我可能错了,但我不认为 Java 表示法现在看起来像那样。 Rolf 关于文字字符串的提示非常有用。

    我创建了一个小类来保存您的列、运算符和值,并将它们传递给 MyBatis 进行处理。列和运算符是字符串文字,但我将值保留为 sql 参数(我想 MyBatis 将能够进行任何必要的类型转换)。

    public class TestAnswer {
        public static void main(String[] args) {
                ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
                SqlSessionFactory sqlFactory = (SqlSessionFactory) ctx.getBean("sqlSessionFactory");            
                MappedStatement statement = sqlFactory.getConfiguration().getMappedStatement("testAnswer");                        
    
                ArrayList<Clause> params1 = new ArrayList<Clause>();
                params1.add(new Clause("email","like","test"));
                params1.add(new Clause("user","<>",5));
    
                ArrayList<Clause> params2 = new ArrayList<Clause>();
                params2.add(new Clause("trans_id","<",100));
                params2.add(new Clause("session_id",">",500));
    
                HashMap params = new HashMap();
                params.put("params1", params1);
                params.put("params2", params2);
    
                BoundSql boundSql = statement.getBoundSql(params);
                System.out.println(boundSql.getSql());             
        }
    
        static class Clause{        
            private String column;
            private String operator;
            private Object value;
    
            public Clause(String column, String operator, Object value){
                this.column = column;
                this.operator = operator;
                this.value = value;
            }
    
            public void setColumn(String column) {this.column = column;}
            public void setOperator(String operator) {this.operator = operator;}
            public void setValue(Object value) {this.value = value;}
            public String getColumn() {return column;}
            public String getOperator() {return operator;}
            public Object getValue() {return value;}        
        }    
    }
    

    如您所见,我使用 Spring,但我希望类似的东西可能会在 Spring 环境之外工作。

    <?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="com.stackoverflow.TestMapper">
    
        <select id="testAnswer" parameterType="map" resultType="hashmap">
          select *
        FROM somewhere
            <where>
                <foreach item="clause" collection="params1" separator=" AND " open="(" close=")"> 
                    ${clause.column} ${clause.operator} #{clause.value} 
                </foreach>            
                OR
                <foreach item="clause" collection="params2" separator=" AND " open="(" close=")"> 
                    ${clause.column} ${clause.operator} #{clause.value} 
                </foreach>    
            </where>
        </select>
    
    </mapper>
    

    【讨论】:

    • 这将需要一个 4 个参数子句(列、运算符、value1、value2) - 或者至少需要某种方式将您的 2 个日期转换为合适的值。也许创建一个 BetweenClause 类。恐怕这不是一个特别优雅的解决方案,因为日期格式(对于值字段)很容易成为特定于数据库供应商的,除非您竭尽全力遵守 ANSI 标准。
    • 使用两个 SQL 子句实现 BETWEEN 会更简单...stackoverflow.com/questions/4809083/between-clause-versus-and
    • 嗨,马克...我实现了与 4 参数子句相同的方式...感谢您对此的投入!!!
    【解决方案2】:

    这个答案有两个关键部分。一个是“动态”元素,另一个是您问题中“运算符”周围的 $$ 文字元素。

      <select id="yourSelect" parameterClass="Map" resultMap="somethingsomething" >
        select * from YOURTABLE
          <dynamic prepend="WHERE">
            <isNotNull prepend="AND" property="email">
              email $operator$ #testvalue#
            </isNotNull>
          </dynamic>
      </select>
    

    另请参阅有关此主题的 DataMapper Dynamic SQL documentation

    【讨论】:

    • 我认为这是 iBatis 的方法,它不适用于 myBatis
    猜你喜欢
    • 2015-10-20
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多