MyBatis - как создать динамическое предложение WHERE - PullRequest
4 голосов
/ 19 мая 2011

Служба получает неизвестный объект, содержащий список из трех значений [столбец, оператор, значение] Например, Электронная почта - как - "ТЕСТ"

На основе полученного списка для построения предложения WHERE, которое я имею, но я также смог бы построить такое условие следующим образом (например)

ГДЕ (электронная почта типа 'test' И user_id <> 5) ИЛИ (trans_id <100 AND session_id> 500)

Кто-нибудь может мне помочь, как это сделать?

Ответы [ 2 ]

8 голосов
/ 26 сентября 2011

Я заново открывал MyBatis после долгого отсутствия сам (одно время я был знаком с iBatis). Пример Рольфа выглядит так, как будто это может быть реализация .Net, я могу ошибаться, но я не думаю, что нотация Java выглядит сейчас так. Совет Рольфа о буквальных строках очень полезен.

Я создал небольшой класс для хранения ваших столбцов, операторов и значения и передаю их в 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>
1 голос
/ 01 июля 2011

Этот ответ состоит из двух ключевых частей. Одним из них является «динамический» элемент, а другим - буквальные элементы $$ вокруг «оператора» в вашем вопросе.

  <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 по этой теме.

...