1

最初に、長い投稿についてお詫びする必要があります。私は過度に冗長でありながら、常に十分に明確であるとは限らないことに苦労しています。また、問題のエレガントな解決策を広範囲に検索しました。見逃した場合は、そこに案内してください。

いくつかの背景:
標準の結果セットのセットに namedQueries を使用している grails アプリがあります。アプリは、当社のシステムで公開されている求人情報を見つけて、他のサイトに送信します。最近、namedQueries を引き続き使用したい場合、追加の要件が問題になりました。

簡単にするために、ドメイン モデルを次のように仮定します。

    class JobOrder {

  def getOpenAdJobsSql() {
    def qry = "select jo FROM JobOrder jo WHERE isOpen=1 AND publishedTo='All External' AND adCategory.isActive=1 AND jo.adLocation in (select zc.id from Zip zc)"

    JobOrder.executeQuery(qry)

  }

  static namedQueries = {

    openAdJobs {
      eq 'isOpen', true
      eq 'publishedTo', "All External"
      adCategory {
        eq 'isActive', true
      }
    }

  static mapping = {
    table 'dbo.JOBORDER'
    version false
    id generator: 'identity', column: 'JOBORDERID'
    isOpen column: 'ISOPEN'
    publishedTo column: 'customText15'
    adLocation column: 'PUBLISHEDZIP'
    adCategory column: 'customInt3'
  }

  Boolean isOpen
  String publishedTo
  String adLocation
  ClientCorporation client
  AdCategory adCategory

  static constraints = {
    adLocation(size: 0..100)
  }

}

    class AdCategory {    
  static mapping = {
    table 'dbo.AdCategory'
    version false
    id generator: 'identity', column: 'adCategory_ID'
    isActive column: 'active'
  }
}

    class Zip {
    static mapping = {
        table 'ZIP'
        version false
        id generator: 'identity', column: 'ZIPCODE'
        city  column: 'city'
        county  column: 'county'
        stateAbbr column: 'statecode'
    }

    String city
    String county
    String stateAbbr
}

問題となっている現在の namedQuery から始めます。

openAdJobs {
  eq 'isOpen', true
  eq 'publishedTo', "All External"
  adCategory {
    eq 'isActive', true
  }
}

このクエリは、AdCategory ドメイン オブジェクトとも関係がある JobOrder ドメイン オブジェクトに存在します。名前付きクエリは、次の呼び出しを使用して複数の場所で呼び出されます。

def openJobs = JobOrder.openAdJobs

私の新しい問題:
無効な郵便番号を持つ求人を公開しないようにする必要があります。zip 検証を含まない製品と統合していますが、製品のネイティブ ドメイン モデルを制御できません。スタンドアロンのカスタム Zip ドメイン オブジェクトを追加しました。次のクエリが返すものを達成するために、JobOrder オブジェクトの名前付きクエリで動作するコードを含める方法を見つけるのに苦労しました: (私は dbvisualizer で sql db に対してこのクエリを実行します)

  select * from dbo.JobOrder jo  
  inner join dbo.AdCategory ac on jo.adCategory=ac.adCategory_ID  
  where  
  jo.isOpen=1  
  and  
  jo.publishedTo='All External'  
  and  
  ac.isActive=1  
  and  
  jo.publishedZip in (  
        select zc.zipcode from dbo.Zip zc  
  ) 

あまりきれいではない解決策:
私と数人の同僚が目的の結果セットを取得する唯一の方法は、JobOrder オブジェクトで次のようなメソッドを作成することです。

def getOpenAdJobsSql() {
    def qry = "select jo FROM JobOrder jo WHERE isOpen=1 AND publishedTo='All External' AND adCategory.isActive=1 AND jo.adLocation in (select zc.id from Zip zc)"

    JobOrder.executeQuery(qry)
}  

もちろん、JobOrder をインスタンス化しない限り、このメソッドは使用できません。この時点で実際に JobOrders のリストを作成しようとしているので、結果セットを取得するための非常に食欲をそそるハックがあります。getOpenAdJobsSql() メソッドを呼び出せるように、既知の適切な JobOrder をフェッチする (または作成する) 必要があります。

何かのようなもの:

def jo = JobOrder.get(2)
def rset = jo.openAdJobsSql

現在openAdJobs名前付きクエリを呼び出しているすべての場所に追加する必要があります (現在 9 つ以上の使用法)。このアプローチを検討することさえ、私に精神的な警告のフレアを送信していますが、追加機能を追加する他の方法はありません.

繰り返しますが、最終的には名前付きクエリを呼び出したいのですが、追加の郵便番号 sql は、GORM + hibernate では処理できないようです。

誰かがよりエレガントな解決策を知っていることを願っています。そして、この投稿で欠落している場所を明確にするよう求めてください.

4

1 に答える 1

0

さて、私があなたの問題を理解していれば:

  1. JobOrder、より具体的には、基盤となるJOBORDERテーブルとそのテーブルにデータを入力するメカニズムは、サードパーティ製品です。どちらも変更できません。
  2. JOBORDERの行には、ZIPテーブルに存在しないPUBLISHEDZIP値が含まれている可能性があります。
  3. 現在のGORMモデルにはJOBORDERとZIPの関係が含まれていないため、Criteria/HQLを使用して有効なZIPコードのみを含むデータのサブセットを選択することはできません。

動作する可能性のあるオプション:

  • 基礎となるクラスのオブジェクトをインスタンス化する必要がないように、記述したメソッドを静的にします。
  • 名前付きクエリでinList制限を使用します(これはテストしていませんが、機能するはずです)。

openAdJobs {
    eq 'isOpen', true
    eq 'publishedTo', "All External"
    inList 'adLocation', Zip.list()
    adCategory {
      eq 'isActive', true
   }
 }

inListをExists句に置き換えるSubquery式を使用することで、よりパフォーマンスの高い代替手段があると思いますが、CriteriaBuilder /GORMCriteriaがそれをサポートしているかどうかはわかりません。これを行うには、Hibernateにアクセスする必要があるかもしれませんが、そのアプローチが名前付きクエリでどれほどうまく機能するかはわかりません。

于 2011-02-15T17:35:22.373 に答える