對JPA實體關係管理雙向關聯的一些思考
現象
在使用JPA進行實體關係管理的時候,會產生無限迴圈的情況,如果使用fastjson來進行序列化,則表現形式如下:{ "address":{ "id":63, "name":"1address name", "person":{"$ref":".."}, "zipCode":"ZipCode01" }, "firstName":"0firstName", "id":69, "lastName":"0lastName" }, { "address":{ "id":64
重點是
address.person
的值:{"$ref":".."}
如果你用的不是fastjson(它預設會檢查該物件是否已經存在在json文字中)而是其他一些json類庫,比如jackson,則會丟擲java.lang.StackOverflowError
但是,哪怕你用的是fastjson,你也無法用js來解析{"$ref":".."}
.解決思路
- 使用fastjson自帶的
JSON.toJSONString(page,SerializerFeature.DisableCircularReferenceDetect)
- 優點:解決快速
- 缺點:
- 序列化後的json文字包含太多不需要的資訊,冗雜程度太高
- 方式太死板,沒有相應的註解來實現(jackson有一個),介面只能返回String型別了.
重新設計實體關係,儘量避免雙向關聯,使用RESTful進行介面的暴露.(舉個例子來說)
- 優點:邏輯清晰,結構更合理
- 缺點:
- 對老程式碼改動較大.
- 實現較複雜,要對整體業務邏輯有清晰的認識.
實體類Person
public class Person { private String name; @Id @GeneratedValue private Long id; @ManyToMany @JoinColumn(name = "address_id") private List<Address> addresses; // ...... getter and setter }
實體類Address
public class Address { @Id @GeneratedValue private Long id; private String name; private String zipCode; // ...... getter and setter }
兩個實體類之間的關係為Many Person To Many Address,只在Person實體類中進行關係的配置,避免雙向關聯.
下面舉例說明使用RESTful來對資源進行訪問的情況.
對於Person:
- 1 查詢所有Person:
/persons
- 2 查詢某一個Person:
/persons/{person_id}
- 3 查詢某一個Person的所有Address:
/persons/{person_id}/addresses
4 查詢某一個Person的某一個Address:
/persons/{person_id}/addresses/{address_id}
如果要查詢一個Address有幾個Person:
/persons?address.id=xxx
(帶分頁,自己設定pageSize)
對於Address:
- 1 查詢所有Address:
/addresses
- 2 查詢某一個Address:
/addresses/{address_id}
以上是Person和Address的一些簡單介面.其中粗體部分為關聯查詢.
設計的思路就是要儘量避免雙向關聯,然後把Person作為一個資源,把Address作為Person的一個子資源或者屬性.
上述Person中的1 2 將Address作為了屬性,查詢時可以通過引數傳遞進去.而上述Person中的3 4 兩個介面則將Address作為一個子資源進行管理.如果要用Address來作為一個資源反查Person怎麼辦?
在一個Address管理頁面,需求要求列出某一個住址下的Person:- 點選某一項:
Address發起/persons?address.id=xxx
請求,取得List<Person>
. - 預設顯示:
在controller層對/persons?address.id_in=xxx1,xxx2,xxx3
介面的返回值進行處理,取得List<Address>
和其對應的List<Person>
- 使用fastjson自帶的
總結
儘量避免雙向關聯,使用更合理的API設計方式,合理區分子資源和屬性.
大大減少資料庫壓力!
相關推薦
對JPA實體關係管理雙向關聯的一些思考
現象 在使用JPA進行實體關係管理的時候,會產生無限迴圈的情況,如果使用fastjson來進行序列化,則表現形式如下: { "address":{ "id":63,
QQA: Hibernate 為什麼需要手工管理雙向關聯
Hibernate/JPA 中如果兩個 Entity 之間的關聯是雙向的(不論是 @ManyToMany、 @OneToMany 還是 @OneToOne),都需要手動管理關聯,為什麼? 呼叫 entityManager.persist 儲存物件時 Hibernate/JPA 不會直接執行 SQL,而會等到
Hibernate 對映關係 ---Many2Many 雙向關聯
以Student和Course為例,一個學生可以選多門課程,一門課程也可以被多個學生選取; 持久化類Student: [java] view plain copy
Hibernate 對映關係 ---One2Many 雙向關聯
一種商品類別下有多個商品,多個商品對應同一個商品類別,這種關係就是一對多雙向關聯。 商品類: [java] view plain copy p
客戶關係管理系統的一些心得和感受分享
這個專案呢,感覺還挺難哦,主要是通過這個系統完成對客戶基本資訊、聯絡人資訊、客戶服務資訊、公司銷售情況、產品、庫存的充分共享和規範化管理;在客戶將要流失時系統及時預警,以便銷售人員及時採取措施,降低損失。並通過系統提供
JPA實體關係對映
實體關係是指實體與實體之間的關係,從方向上分為單向關聯和雙向關聯,從實體數量上分為一對一、一對多、多對多等。對於任何兩個實體,都要從這兩個方面區分它們之間的關係。 單向關聯是一個實體中引用了另外一個實體,也即通過一個實體可以獲取另一個實體物件的引用;雙向關聯是兩個實體之間
對研發團隊裡技術分享的一些思考
這是我最近看到的一篇關於公司技術分享的比較好的文章 就粘過來大家一起學習吧 https://www.iteye.com/blog/aoyouzi-2342659 分享目的 做任何事情,要明確目的,才能清晰、順利實施。目的包括這件事能幫大家帶來什麼、能給公司帶來什麼、預期結果是什麼、成
對CROS OPTIONS預檢請求的一些思考
前後端分離模大勢所趨,跨域問題更是老生常談。 問題背景: > 瀏覽器最基本的安全規範-**同源策略**。所謂同源是指域名、協議、埠相同。不同源的瀏覽器指令碼(javascript、ActionScript、canvas)在沒有明確授權的情況下,不能讀寫對方的資源。 CORS就是w3c和瀏覽器廠商為解決跨
Hibernate,關係對映的多對一單向關聯、多對一雙向關聯、一對一主鍵關聯、一對一外來鍵關聯、多對多關係關聯
2018-11-10 22:27:02開始寫 下圖內容ORM、Hibernate介紹、hibername.cfg.xml結構: 下圖內容hibernate對映檔案結構介紹 下圖內容hibernate
JPA中多對多表關係的刪除操作,如何刪除放棄維護關聯關係的一方和中間表的紀錄
資料庫中的表 使用者表:在配置實體類的時候放棄了維護關聯關係的權利 角色表: 中間表: 需求:刪除t_user表中的user_id 為1的使用者,並刪除相關的中間表紀錄。 程式碼: @Test public
JPA實體關聯關係對映之概述
一、簡介 首先來說關聯關係是面向物件分析,面向物件設計最重要的部分,JPA是完全可以通過對映來簡化資料持久化到資料,和Hibernate一樣,JPA的關聯關係也分為兩種,一種是單向關聯,一種是雙向關聯: 單向關聯:只需要單向訪問關聯端,比如說:我們只能通過某一學期訪
JPA之JPA中的多對多雙向關聯
如果要搭建JPA開發環境,請從JPA第一篇部落格看起。 下面的例子以老師和學生的例子進行多對多關係的編碼講解。 1、Student.java中的程式碼 package cn.sunft.bean; import java.util.HashSet; import j
hibernate的映射之四(多對多雙向關聯)
als oot bean odi 生成 指定 數據庫方言 映射文件 格式化sql Many-to-Many 多對多的映射可以使用一組Java集合不包含任何重復的元素來實現。我們已經看到了Hibernate如何設置映射集合。 集(SET)被映射到與映射表中<set&g
Hibernate,關系映射的多對一單向關聯、多對一雙向關聯、一對一主鍵關聯、一對一外鍵關聯、多對多關系關聯
nat 延遲加載 alt ima orm 雙向關聯 映射文件 結構 spa 2018-11-10 22:27:02開始寫 下圖內容ORM、Hibernate介紹、hibername.cfg.xml結構: 下圖內容hibernate映射文件結構介紹
一對多|多對一關係 ---- Hibernate之關聯對映
敘:hibernate中的關聯對映存在一對多多對一關係和多對多關係;本章節電蟲就關聯對映的一對多多對一關係進行學習和總結記錄; Hibernate的關聯對映之“一對多|多對一”關係 準備工作 需要有兩個實體類以及實體類所對應的對映檔案,由於之前建立
Hibernate多對多的雙向關聯
Hibernate多對多關係:可以看作是兩個一對多,比如書籍與類別,書籍可以有多個類別,類別下可以有多本書籍 既然多對多可以看作兩個一對多,那麼維護只能交給一方進行維護,比如我做級聯新增時,如果雙方都維護,就會造成資料重複 準備: SessionFactoryU
JPA中多對多表關係的刪除操作,如何只刪除一方和中間表的紀錄
資料庫中的表 使用者表: 角色表: 中間表: 需求:刪除t_user表中的user_id 為1的使用者,並刪除相關的中間表紀錄。 程式碼: @Test public void testRemove() {
MyEclipse開發教程:使用REST Web Services管理JPA實體(三)
MyEclipse 線上訂購年終抄底促銷!火爆開搶>> MyEclipse最新版下載 使用REST Web Services來管理JPA實體。在逆向工程資料庫表後生成REST Web服務,下面的示例建立用於管理部落格條目的簡單Web服務。你將學會: 利用資料庫逆向工程開
MyEclipse開發教程:使用REST Web Services管理JPA實體(二)
MyEclipse 線上訂購年終抄底促銷!火爆開搶>> MyEclipse最新版下載 使用REST Web Services來管理JPA實體。在逆向工程資料庫表後生成REST Web服務,下面的示例建立用於管理部落格條目的簡單Web服務。你將學會: 利用資料庫逆向工程開
MyEclipse開發教程:使用REST Web Services管理JPA實體(一)
MyEclipse 線上訂購年終抄底促銷!火爆開搶>> MyEclipse最新版下載 使用REST Web Services來管理JPA實體。在逆向工程資料庫表後生成REST Web服務,下面的示例建立用於管理部落格條目的簡單Web服務。你將學會: 利用資料庫逆向工程開