6

私はcreateCriteria動的に構築することに取り組んでいます。ここまでは順調ですね:

objは、

rulesList検索対象のフィールド、使用する演算子、および検索対象の値を保持するマップのリストです。

def c = obj.createCriteria()
l = c.list (max: irows, offset: offset) {
    switch(obj){           //constrain results to those relevant to the user
        case Vehicle:
            eq("garage", usersGarage)
            break
        case Garage:
            users {
                idEq(user.id)
            }
            break
    }
    rulesList.each { rule ->
        switch(rule['op']){
            case 'eq':
                eq("${rule['field']}", rule['value'])
                break
            case 'ne':
                ne("${rule['field']}", rule['value'])
                break
            case 'gt':
                gt("${rule['field']}", rule['value'])
                break;
            case 'ge':
                ge("${rule['field']}", rule['value'])
                break
            case 'lt':
                lt("${rule['field']}", rule['value'])
                break
            case 'le':
                le("${rule['field']}", rule['value'])
                break
            case 'bw':
                ilike("${rule['field']}", "${rule['value']}%")
                break
            case 'bn':
                not{ilike("${rule['field']}", "${rule['value']}%")}
                break
            case 'ew':
                ilike("${rule['field']}", "%${rule['value']}")
                break
            case 'en':
                not{ilike("${rule['field']}", "%${rule['value']}")}
                break
            case 'cn':
                ilike("${rule['field']}", "%${rule['value']}%")
                break
            case 'nc':
                not{ilike("${rule['field']}", "%${rule['value']}%")}
                break
            }
        }
    }
}

上記のコードは正常に機能し、switchステートメントでは少し冗長に見えます。しかし、ルールのいずれかまたはすべてに一致するように選択する機能を追加したい場合はどうなりますか?条件付きでルールをに入れる必要がありますor{}。私は次のようなことはできません

if(groupOp == 'or'){
    or{
}

rulesListを通過する前に

if(groupOp == 'or'){
    }
}

その後。私が考えることができるのは、条件ごとにコードを繰り返すことだけです。

if(groupOp == 'or'){
    or{
        rulesList.each { rule ->
            switch(rule['op']){
                ...
            }
        }
    }
}
else{
    rulesList.each { rule ->
        switch(rule['op']){
            ...
        }
    }

現在、コードはかなりずさんで反復的に見えています。ドメインオブジェクトのプロパティのプロパティを検索したいとしますか?(例:タイヤが特定のブランドである車両; Vehicle.tires.brand、またはドライバーが名前と一致する車両; Vehicle.driver.name)を返品したい)。私は次のようなことをしなければなりませんか?

switch(rule['op']){
    case 'eq':
        switch(thePropertiesProperty){
            case Garage:
                garage{
                    eq("${rule['field']}", rule['value'])
                }
                break
            case Driver:
                driver{
                     eq("${rule['field']}", rule['value'])
                }
                break
        }
        break
    case 'ne':
        ...
}
4

1 に答える 1

9

まず、メソッド名にGStringを使用することで、大きなスイッチを単純化できます。

case ~/^(?:eq|ne|gt|ge|lt|le)$/:
  "${rule['op']}"("${rule['field']}", rule['value'])
  break

同じトリックがおよび/または:に対して機能します。

"${(groupOp == 'or') ? 'or' : 'and'}"() {
  rulesList.each { rule ->
    switch(rule['op']){
        ...
    }
  }
}

または、最初にクロージャを変数に割り当ててから、or(theClosure)または必要and(theClosure)に応じて呼び出すことができます。最後に、「プロパティのプロパティ」検索では、追加すると

createAlias('driver', 'drv')
createAlias('garage', 'grg')

基準クロージャの一番上にeq('drv.name', 'Fred')、介在driver {...}またはgarage {...}ノードを追加することなく、などのクエリを実行できます。

于 2012-07-18T22:00:35.647 に答える