【问题标题】:Grails CriteriaBuilder add RestrictionsGrails CriteriaBuilder 添加限制
【发布时间】:2016-04-19 18:01:50
【问题描述】:

我想创建我的条件对象并添加一些依赖于其他属性的限制。

我尝试过类似的东西......

    long from, to;
    use(TimeCategory) {
        from = (1.month.ago).getTime() / 1000L
        to = (new Date()).getTime() / 1000L
    }

    def crit = Map.createCriteria()       

    // set date range
    crit.between("appear", from, to)

    // if testParam1 is present
    if (params.testParam1 && !(params.testParam1.equals("all") || params.testParam1.isEmpty())) {
        crit.eq("test1", testParam1)
    }

    // if testParam2 is present
    if (params.testParam2 && !(params.testParam2.equals("all") || params.testParam2.isEmpty())) {
        crit.eq("test2", testParam2)
    }

但是每次我得到一个 java.lang.IllegalArgumentException

此异常来自 validateSimpleExpression 测试失败的 HibernateCriteriaBuilder 类

/**
 * Creates a "between" Criterion based on the property name and specified lo and hi values
 * @param propertyName The property name
 * @param lo The low value
 * @param hi The high value
 * @return A Criterion instance
 */
public Object between(String propertyName, Object lo, Object hi) {
    if(!validateSimpleExpression()) {
        throwRuntimeException( new IllegalArgumentException("Call to [between] with propertyName ["+propertyName+"]  not allowed here."));
    }
    propertyName = calculatePropertyName(propertyName);
    return addToCriteria(Restrictions.between(propertyName, lo, hi));
}


private boolean validateSimpleExpression() {
    if(this.criteria == null) {
        return false;
    }
    return true;
}

知道如何动态添加一些限制吗?

【问题讨论】:

    标签: hibernate grails criteria


    【解决方案1】:

    总是有可能使用 Hibernate 条件查询

        Criteria criteria = sessionFactory.currentSession.createCriteria(Map.class)
            .add(Restrictions.between('appear', from, to))
    
        // if testParam1 is present
        if (params.testParam1 && !(params.testParam1.equals("all") || params.testParam1.isEmpty())) {
            criteria.add(Restrictions.eq("test1", testParam1))
        }
    

    我最终这样做是为了让函数在使用之前返回一个 Criteria,由调用者扩充。

    【讨论】:

      【解决方案2】:

      感谢两位的建议。它引导我走向正确的方向。这是我的最终方法

      long from, to;
      use(TimeCategory) {
          from = (1.month.ago).getTime() / 1000L
          to = (new Date()).getTime() / 1000L
      }
      
      def records = Map.withCriteria {       
      
          // set date range
          between("appear", from, to)
      
          // if testParam1 is present
          if (params.testParam1 && !(params.testParam1.equals("all") || params.testParam1.isEmpty())) {
              eq("test1", testParam1)
          }
      
          // if testParam2 is present
          if (params.testParam2 && !(params.testParam2.equals("all") || params.testParam2.isEmpty())) {
              eq("test2", testParam2)
          }
      
      }
      

      【讨论】:

        【解决方案3】:

        @RomanRomanovsky 的答案的替代方法是传递 Closure,然后将 HibernateCriteriaBuilder 的 delagate 分配给添加的闭包的 delegate

        def additionalRestrictions = {
           if(params.testParam1){
               eq("test1", testParam1)
           }
           ...
        }
        
        // usage
        def result = criteria.list(){
            additionalRestrictions.delegate = delegate
            additionalRestrictions()       
        }
        

        @RomanRomanovsky 的方式对我来说实际上是新的,我想我更喜欢它。需要注意的一点是,使用 delegate 不需要在闭包中的方法(eq、createAlias 等)前添加任何前缀。

        【讨论】:

          【解决方案4】:

          你必须使用 Closure 并在条件中传递它,让我举个简单的例子:

          def criteria = Map.createCriteria()   
          
          
          Closure closure = {builder ->
             if(params.testParam1){
                 builder.eq("test1", testParam1)
             }
             if(params.testParam2){
                 builder.eq("test2", testParam2)
             }
             builder.beetwen("appear", from, to)
          }
          

          比:

           def result = criteria.list(){
              closure(criteria)        
           }
          

          【讨论】:

          • 你可以随意添加。
          • 你知道closure() 方法是HibernateCriteriaBuilder 独有的还是适用于整个groovy?这对我来说是新的......
          • 对我来说这不是唯一的,我错了会尝试查找更多信息
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多