Java 带有继承的JPA映射视图和表

Java 带有继承的JPA映射视图和表,java,mysql,hibernate,jpa,Java,Mysql,Hibernate,Jpa,我有一个数据库设计,我不能改变。db具有具有一对一关系的表和视图。这些视图包含一些从表中计算出来的额外信息。相关信息是行的状态。为该关系设置的权限是只读的,因为表中的所有CRUD操作都可用。JPA是映射到此设置的选定ORM。该应用程序是一个基本的CRUD应用程序,通过检查视图中的状态和其他属性,然后插入/更新相应的表进行验证。下面是我试图模拟这个案例的两种方法的一个例子。我想知道哪一个更有效、更容易使用,和/或“正确的方法”来做到这一点 选项1-这个选项很好,因为我可以使用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
    }

如果您的所有表都有相应的视图对象,我会将您的
视图
实体指定为具有只读访问权限的模型对象内的一对一关系。您只需编写不带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功能。这将是你那边的redundnacy


如果您以后选择使用继承,在这里不使用继承将使继承作为实际选项打开。当然,每次加入视图都可能会影响性能,这取决于您的视图写得有多好,但如果不将它们全部放在同一个对象中,则可以在这方面提供更大的灵活性。

谢谢。这个答案很有帮助。作为后续,我在表之间有一些多对一的关系,我想更新整个表集合。如果表和视图之间的连接是一个性能问题的话。急切或懒散的抓取会更好吗。我的工作流程是1。获取视图以执行验证2。如果验证通过,则更新相应的表,因此这是我需要连接到occurHi的步骤我已经阅读了越来越多关于JPA的内容,偶然发现了@SecondaryTable注释,该注释允许我将两个表映射到一个类,并添加了视图列。如果我在视图特定列中添加insert=false和update=false,这是否与您的模型等效?@user3211617您可以使用它来实现您提出的第二种方案,以及我的insert/update=false建议,但这也有一个规定,即每次使用实体时都要访问视图。考虑到应用程序是如何构建的,这可能是一个可行的方法,但是如果您要访问实体进行大量纯crud操作,例如在REST应用程序中,您希望将它们分开。(例如,在发布、放置或删除实体时,您不需要获取视图)非常感谢您的洞察力,是的,我的应用程序正在根据每个请求访问视图b/c它需要检查一些视图特定列,然后才能执行任何CRUD操作,因此我认为每次加入的开销都是必要的。再次感谢你。