gpt4 book ai didi

java - 通用 hibernate 对象的面向对象设计

转载 作者:行者123 更新时间:2023-12-02 06:51:12 26 4
gpt4 key购买 nike

我目前正在研究良好的面向对象原则,并且 hibernate ,我有这个 POJO,其中的属性将被动态填充。这是我读过的一种良好的面向对象设计的设计模式,在这种设计模式中,可以很容易地向特定对象添加属性,而不会破坏应用程序。 我的问题是,当您的属性被认为是动态的时,如何将其映射到表,我使用枚举来限制映射的键值对,但理想情况下它仍然可以增长。我仅使用内存数据库 (h2),并且不会将代码用于生产用途。这仅用于学习目的。请参阅下面的代码:

public class Transaction {

private static Map<Object, Object> properties;

public Transaction(){
if(null != properties)
properties = new LinkedHashMap<Object, Object>();
}

public Transaction(Map<Object, Object> properties){
if(null != properties)
setProperties(properties);
}

public void setProperties(Map<Object, Object> prop){
properties = prop;
}
public void setProperties(Properties property, String value){
properties.put(property, value);
}

public Map<Object, Object> getProperties(){
return properties;
}

public String getProperties(Properties property){
return (String) properties.get(property);
}


}

所以我希望能够动态地创建一个具有此属性的表,我的枚举:

public enum Properties {
Entry("Entry"), Id("Entry_ID"), Name("Name"), Credit("Credit");

private final String description;

private Properties(final String description){
this.description = description;
}
@Override
public String toString(){
return description;
}
}

我有这个 hibernate 映射,但是正如您所看到的,每次更新字段时都需要更新,我需要一个通用映射,以便当我更改/添加属性、注释时或者 xml 就可以了,见下文:

 <class name="Transaction" table="TRANSACTION">
<id name="id" column="ENTRY_ID">
<generator class="increment"/>
</id>
<property name="name"/>
<property name="credit" type="boolean" column="IS_CREDIT"/>
</class>

最佳答案

UserDefinedField Marin Fowler 网站上的文章可能是探索此问题一般答案的完美起点。

至于 Hibernate:它实际上是为将表静态绑定(bind)到对象而设计的,如果在运行时更改架构,则可能会遇到严重问题。不过,您可以实现以下解决方案:

  • 序列化 LOB(将映射序列化为二进制字段或 - 使用 JSON/XML - 文本字段)。这是一种一半一半的方法 - 一半是表格/规范形式/SQL,一半是非 SQL。因此,如果这种方法很有吸引力,您可能需要考虑全面使用 NoSQL 数据库,如下文所述
  • 属性表,您的自定义属性存储在连接到主表的键值对表中。这可以在 Hibernate 中使用 Indexed Collections 进行映射。 (请参阅第 7.2.2.2 节“ map ”),您最终会得到与问题中类似的结果:

    @Entity 
    public class Transaction {

    @Id @GeneratedValue public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    private Integer id;

    // ... snip ...

    @OneToMany(mappedBy="transaction")
    @MapKey(name="name")
    public Map<String, String> getProperties(){
    return properties;
    }
    public void setProperties(Map<String, String> prop){
    properties = prop;
    }
    private Map<String, String> properties; // NB: Type has to be <String, String> because the column name is a String and you have defined the property value to be a String.

    public void setProperty(Properties property, String value){
    properties.put(property, value);
    }
    public String getProperty(String name){
    return (String) properties.get(property);
    }
    }

    @Entity
    public class Property {
    @Id @GeneratedValue public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    private Integer id;

    @ManyToOne
    public Transaction getTransaction() { return transaction; }
    public void setTransaction(Transaction transaction) { this.transaction = transaction; }
    private Transaction transaction;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    private String name;

    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
    private String description;

    }
  • 预定义的自定义字段,您可以从一个非常宽的表格开始,其中包含大量未使用的列。在此实现中,您最终定义了任意属性名称和预定义列名称(getString1()getString10() 等)之间的映射

但是,对您来说更好的解决方案可能是使用 NoSQL 数据库 - 特别是基于文档的数据库。这些允许您存储和检索任意数据结构( map 和列表)。有趣的是,使用这种方法可以使绑定(bind)到数据存储显着变得更加容易。

MongoDBRedis (Jedis 处的 Java 绑定(bind))是示例。

关于java - 通用 hibernate 对象的面向对象设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18010068/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com