Grails 如何在一个表中存储来自不同对象的值

Grails 如何在一个表中存储来自不同对象的值,grails,gorm,Grails,Gorm,在我的代码中,类“Book”包含一些字符串字段,“BookKey”字段包含一些静态方法,只有一个字段包含字符串“key”值。我的问题是如何在“Book”表中只存储这个“key”值(而不是BookKey ID的关系) 我不想在数据库中创建表“BookKey”。我只需要表'Book',其中包含列:'Key','Title'和'Description',其中'Key'是BookKey对象的字符串值。 我知道如果我不想创建表,我必须使用statictransients=['key'],但我不知道如何在一

在我的代码中,类“Book”包含一些字符串字段,“BookKey”字段包含一些静态方法,只有一个字段包含字符串“key”值。我的问题是如何在“Book”表中只存储这个“key”值(而不是BookKey ID的关系)

我不想在数据库中创建表“BookKey”。我只需要表'Book',其中包含列:'Key','Title'和'Description',其中'Key'是BookKey对象的字符串值。 我知道如果我不想创建表,我必须使用statictransients=['key'],但我不知道如何在一个表中存储来自不同对象的值

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'
    }
}

将BookKey类放入
src/groovy
并配置要使用的域类。文档中的示例:

class Person {
    String name
    Country bornInCountry
    Country livesInCountry

    static embedded = ['bornInCountry', 'livesInCountry']
}

// If you don't want an associated table created for this class, either
// define it in the same file as Person or put Country.groovy under the
// src/groovy directory.
class Country {
    String iso3
    String name
}

将BookKey类放入
src/groovy
并配置要使用的域类。文档中的示例:

class Person {
    String name
    Country bornInCountry
    Country livesInCountry

    static embedded = ['bornInCountry', 'livesInCountry']
}

// If you don't want an associated table created for this class, either
// define it in the same file as Person or put Country.groovy under the
// src/groovy directory.
class Country {
    String iso3
    String name
}

您应该查看Grails域类的
embedded
属性:

 static embedded = ['key']

有关更多详细信息,请参见

您应该查看Grails域类的
嵌入式
属性:

 static embedded = ['key']

有关更多详细信息,请参见

我已经处理了相同的任务。我从Droolgormplugin impl那里得到了一个主意。其想法是使用uniqueBusinessKey。例如,id=123的书籍具有“book@123'BusinessKey&&Author with id='q23s'具有'author@q23s“业务密钥。然后这些业务密钥可以在任何地方使用。例:

class LogDomain{
  String businessKey
  ...
}  
你不必为每个Damains都设置关键表。
Spring安全性中使用了另一种方法来确定ACL

我处理过同样的任务。我从Droolgormplugin impl那里得到了一个主意。其想法是使用uniqueBusinessKey。例如,id=123的书籍具有“book@123'BusinessKey&&Author with id='q23s'具有'author@q23s“业务密钥。然后这些业务密钥可以在任何地方使用。例:

class LogDomain{
  String businessKey
  ...
}  
你不必为每个Damains都设置关键表。
Spring安全性中使用了另一种方法来确定ACL

使用
静态嵌入式
是可以的,但在我的情况下,最好定义自己的
“用户类型”
并将其添加到GORM映射中

在我的类中,我只有一个带有随机生成的业务键的
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对象

有关更多信息,请参见此处:


使用
静态嵌入式
是可以的,但在我的情况下,最好定义自己的
“用户类型”
并将其添加到GORM映射中

在我的类中,我只有一个带有随机生成的业务键的
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对象

有关更多信息,请参见此处:


它有效,但只有在BookKey类中使用“字符串键”时才有效。当我使用“最终字符串键”时,我在运行应用程序时遇到一个错误:
原因:org.hibernate.PropertyNotFoundException:在类domain.model.keys.BookKey中找不到属性键的setter,但只有当我在BookKey类中使用“字符串键”时,它才会工作。当我使用“最终字符串键”时,我在运行应用程序时遇到一个错误:
,原因是:org.hibernate.PropertyNotFoundException:在类domain.model.keys.BookKey中找不到属性键的setter