@OneToOne例項詳解
主要是這一截:
@Id // id自動生成 @GeneratedValue @Column(name = "id") private Long id; @Column(name = "name") private String name; //cascade:表的級聯操作 @OneToOne(fetch=FetchType.LAZY,cascade = CascadeType.ALL) //JPA註釋: 一對一 關係 //referencedColumnName:參考列名,預設的情況下是列表的主鍵 //nullable=是否可以為空, //insertable:是否可以插入, //updatable:是否可以更新 // columnDefinition=列定義, //foreignKey=外來鍵 @JoinColumn(name="pet_id",referencedColumnName="id",nullable=false) private Pet pet;
表的關聯查詢比較複雜,應用的場景很多,本文根據自己的經驗解釋@OneToOne註解中的屬性在專案中的應用。本打算一篇部落格把增刪改查寫在一起,但是在改的時候遇到了一些問題,感覺挺有意思,所以寫下第二篇專門講修改。
一、單向@OneToOne例項詳解
假設一個場景,一個人只能領養一隻寵物,根據人能夠找到寵物,並且檢視寵物的資訊,關係是單向的。
建立人與寵物的資料表結構。下載地址:Person,Pet資料庫建表。
建立實體。
Person.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
|
Pet.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
註解@OneToOne的介面定義如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
註解@OneToOne的屬性:
cascade:關聯屬性,這個屬性定義了當前類物件操作了之後,級聯物件的操作。本例中定義了:CascadeType.ALL,當前類增刪改查改變之後,關聯類跟著增刪改查。
fetch屬性:FetchType型別的屬性。可選擇項包括:FetchType.EAGER 和FetchType.LAZY。 FetchType.EAGER表示關係類(本例是OrderItem類)在主類載入的時候同時載入,FetchType.LAZY表示關係類在被訪問時才載入。預設值是FetchType.LAZY。
mappedBy:擁有關聯關係的域,如果關係是單向的就不需要,雙向關係表,那麼擁有關係的這一方有建立、解除和更新與另一方關係的能力,而另一方沒有,只能被動管理,這個屬性被定義在關係的被擁有方。雙向@OneToOne,雙向@OneToMany,雙向@ManyToMany。
註解@JoinColumn的介面定義:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
註解@JoinColumn的屬性:
name屬性:外來鍵列的名稱,預設情況下是:引用實體的欄位名稱 +“_”+ 被引用的主鍵列的名稱。一般也可以自定義,一般見名知意,就可以採用預設值。
referencedColumnName屬性:參考列,預設值是關聯表的主鍵。例如你可以定義pet_name為參考列,那麼就會將pet的name的值關聯到這一列。
建立類:TableRelationController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|
建立TableRelationService類:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
|
注意:這裡關聯表更改的時候要注意,如果沒有配置好會出現異常。
1 |
|
這是在spring的事務實現中需要判斷當前執行緒中的事務是否同步,而沒有事務的時候,那個判斷是否同步的方法會因為get返回初始的null值而返回false,最終導致throw一個Could not obtain transaction-synchronized Session for current thread的異常,解決方法有兩個:
1)加事物控制。
1 |
|
2)重新生成session。
1 |
|
配置檔案中:
1 |
|
測試:postMan傳送請求:
增加:
1 2 3 4 5 6 7 8 9 |
|
查詢:
1 2 3 |
|
1 2 3 4 5 6 7 8 9 |
|
刪除:
1 2 3 |
|
更改:
這裡更改了petName,petClass
1 2 3 4 5 6 7 8 |
|
問題:
在更新的時候存在這樣的問題,如果剛開是插入資料的時候,沒有插入從表Pet的資料。
1 2 3 4 5 |
|
此時如果想在更新資料,給King新增一個pet資料,那麼就會一直插入。
1 2 3 4 5 6 7 8 |
|
這是因為程式在執行save操作的時候,默默的執行了下面的語句。
1 2 3 4 5 |
|
第一條語句查出來是空,所以會執行插入操作。其實這邊也沒有完全搞懂,歡迎留言!
這個問題的解決方式,請參考雙向一對一對映@OneToOne。