JPA映射视图和具有继承的表

时间:2015-10-26 18:14:46

标签: java mysql hibernate jpa

我有一个我无法改变的数据库设计。 db具有与一对一关系的表和视图。视图包含从表中计算的一些额外信息。相关信息是行的状态。为此关系设置的权限是视图是只读的,因为表具有所有可用的CRUD操作。 JPA是选定的ORM映射到此设置。该应用程序是一个基本的CRUD应用程序,通过检查视图中的状态和其他属性然后插入/更新相应的表进行一些验证。以下是我尝试对此案例进行建模的两个方面的示例。我想知道哪一个更有效,更容易使用,和/或正确的方式'这样做。

选项1 - 这个选项很好,因为我可以使用所有JPA提供的接口与DB交互。这个选项很糟糕,因为我有时需要加载一个表和一个看似非常冗余的模型,每个表有3个文件。

    Model.java
    package models;
    // relevant imports
    public abstract class Model {
       // columns that are shared with table and view
    }

    Table.java
    package models;
    // relevant imports
    @entity("table")
    public class Table extends Model {
       // Relationships with other tables 
    }

    View.java
    package models;
    // relevant imports
    @entity("view")
    public class View extends Model {
       // View specific columns ...
       // Relationships with other views
    }

选项2 - 这个选项很好,因为我只需要加载视图,每个表有一个文件。这个选项很糟糕,因为对于CUD操作,我必须编写本机SQL。

    Model.java
    package models;
    // relevant imports
    @entity("view")
    public class Model {
       // All VIEW + table columns
       // All relationships with other models
       // custom SQL to insert update or delete
    }

1 个答案:

答案 0 :(得分:2)

如果您的所有表都具有相应的视图对象,我会将您的view实体指定为模型对象内部的一对一关系,并且具有只读访问权限。您可以通过编写没有setter的getter来执行此操作,因为触发任何类型的set然后保存将运行失败的查询。使用这样的继承会将您锁定为必须在一个级别中指定所有列,并且您将不知道哪些列属于哪些表或视图。

    Table.java
    package models;
    // relevant imports
    @entity("table")
    public class Table{
        @OneToOne(mappedBy = "table")
        private View view;
        public string getVariable();
        public string setVaraible();
    }

    View.java
    package models;
    // relevant imports
    @entity("view")
    public class View{
       @OneToOne
       @JoinColumn(name = "table_id")
       private Table table;

       public string getVariable();
       public string getVariable2();
       public string getVariable3();//etc, No setters.

       //alternatively use insertable//updateable=false on all column annotation
       @Column(name="variable_4", insertable =  false, updateable=false)
       public string getVariable4();
    }

在模型对象中将它们全部集中在一起排除了首先在那里使用ORM的对象,因为现在你将不得不编写很多mysql代码来匹配ORM的基本CRUD功能。这将是你的冗余。

如果你选择稍后使用它,那么不使用inhertiance将继承打开作为实际选项。每次加入视图可能对性能有害,这取决于您的视图编写的程度,但是不能将它们全部放在同一个对象中,从而在这个意义上允许更多的灵活性。