2015-10-26 90 views
3

我有一個數據庫設計,我不能改變。數據庫具有表和視圖,它們具有一對一的關係。這些視圖包含一些從表格中計算出來的額外信息。相關信息是該行的狀態。爲這種關係設置的權限是視圖是隻讀的,因爲表格具有所有可用的CRUD操作。 JPA是選定的ORM映射到此設置。該應用程序是一個基本的CRUD應用程序,通過檢查視圖中的狀態和其他屬性進行驗證,然後插入/更新相應的表格。以下是我嘗試對這種情況建模的兩個認可的例子。我想知道哪一個更高效,更容易處理,和/或「正確的方式」來做到這一點。JPA映射視圖和繼承表

選項1 - 此選項很好,因爲我可以使用所有JPA提供的接口與數據庫交互。這個選項是不好的,因爲我有時需要加載一個表格和一個看起來非常冗餘的模型,每個表格有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 
    } 

回答

2

我指定view實體與只讀訪問你的模型對象內部的一對一的關係,如果所有的表都有着相應的視圖對象。你可以通過編寫沒有setter的getter來做到這一點,因爲解僱任何類型的設置然後保存將運行一個失敗的查詢。使用像這樣的繼承可以鎖定您必須在一個級別指定所有列,並且您不知道哪些列屬於哪個表或視圖。

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在這裏留下繼承作爲一個實際的選擇打開,你應該選擇使用它後面的行。每次加入視圖可能會對性能造成不良影響,這取決於您的視圖寫得如何,當然,如果不將它們全部放在同一對象中,則可以在此方面獲得更大的靈活性。

+0

謝謝你這個答案是有幫助的。作爲後續工作,我在表之間有一些多對一的關係,我想更新整個表的集合,表之間的連接和視圖是性能問題。 EAGER或LAZY取材會更好。我的工作流程爲1.獲取視圖來進行驗證2.如果驗證通過更新相應的表,那麼這是我需要JOIN發生的步驟 –

+0

您好我一直在閱讀越來越多關於JPA的內容,並偶然發現了@SecondaryTable註解,允許我將兩個表映射到一個添加了視圖列的類。如果我添加到視圖特定列insert = false和update = false,這是否與您的模型等效? –

+0

@ user3211617您可以使用它來實現您提出的輔助方案,以及我的insert/update = false建議,但是這也伴隨着您每次使用該實體時都會訪問該視圖的規定。考慮到你的應用程序的構建方式,這可能是一條路,但如果你正在訪問你的實體很多純粹的crud操作,例如在一個REST應用程序中,你會希望保持它們獨立。 (例如,當您發佈到,發佈到或刪除實體時,您不需要獲取視圖) –