0

私のコードでは、いくつかの文字列フィールドを持つクラス「Book」と、いくつかの静的メソッドを持つ「BookKey」フィールドと、文字列「キー」値を持つフィールドが1つだけあります。私の質問は、この「キー」値のみ (BookKey ID による関係ではない)、値を「Book」テーブルに保存する方法です。

データベースにテーブル「BookKey」を作成したくありません。「キー」、「タイトル」、および「説明」の列を持つテーブル「ブック」のみが必要です。「キー」はBookKeyオブジェクトの文字列値です。テーブルを作成したくない場合は static transients=['key'] を使用する必要があることはわかっていますが、異なるオブジェクトの値を 1 つのテーブルに格納する方法がわかりません。

class BookKey{
    public final String key;

    public BookKey(){
        this.key="key-undefined"
    }

    public BookKey(String key){
        this.key=key;
    }

    static BookKey generate(){
        String uuid = UUID.randomUUID().toString();
        String key="book-"+uuid;
        return new BookKey(key)
    }

    static BookKey from(String key){
        return new BookKey(key)
    }
}

public class Book {
    BookKey key=BookKey.generate();
    String title;
    String description;

    static transients = ['key']

    static mapping = {
        key column: 'bKey'
    }
}
4

4 に答える 4

0

使用static embeddedは問題ありませんが、私の状況では、独自に定義"user-type"して GORM マッピングに追加する方が適切でした。

私のクラスには、ランダムに生成されたビジネス キーを持つフィールドが1 つしかないStringため、この値を varchar として db に格納したいと考えました。解決策は次のとおりです。

Config.groovy定義では:

grails.gorm.default.mapping={
  "user-type" (type: my.package.persistence.PersistentBookKey, class: BookKey)
}

インターフェイスPersistentBookKeyを実装するクラスを作成し、いくつかのメソッドをオーバーライドします。UserType

final class PersistentBookKey implements UserType
{
    @Override
    protected BookKey createKeyFromString(String key) {
        BookKey.from(key)
    }

    @Override
    Class returnedClass() {
        BookKey
    }

    private static int [] SQL_TYPES=[Types.VARCHAR] as int[]

    @Override
    int[] sqlTypes() {
        return SQL_TYPES
    }

    @Override
    boolean equals(Object x, Object y) throws HibernateException {
        return x.equals(y);
    }

    @Override
    int hashCode(Object x) throws HibernateException {
        return x.hashCode()
    }

    @Override
    Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
        def key=rs.getString(names[0])
        return this.createKeyFromString(key);
    }

    @Override
    void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
        BookKey persistent=value as BookKey
        st.setString(index,persistent?.getKey())
    }

    @Override
    Object deepCopy(Object value) throws HibernateException {
        return value
    }

    @Override
    boolean isMutable() {
        return false  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    Serializable disassemble(Object value) throws HibernateException {
        return value as Serializable
    }

    @Override
    Object assemble(Serializable cached, Object owner) throws HibernateException {
        return cached
    }

    @Override
    Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original
    }


}

現在、BookKey オブジェクトは Varchar としてデータベースに保存されていますが、取得すると BookKey オブジェクトに変換されます。

詳細については、次を参照してください。

http://grails.org/doc/2.0.x/ref/Database%20Mapping/Usage.html

http://grails.1312388.n4.nabble.com/Working-example-of-user-type-td1377468.html

于 2013-10-19T22:02:22.900 に答える