close

Android Forgin Key

承接上篇Android Room(二)的資料範例

會很容易想到一個問題,如果我要刪除user時,也要一併刪除是該user的pet

這時候該怎麼辦呢?

Google 提出一個解決辦法,ForeginKey 來設定

當一個 Entity 的跟動會牽扯到另一個 Entity 時,這是便可以用ForginKey來設定更動的動畫

Google 文件上面寫了幾個onDelete/onUpdate的參數

Constants

int CASCADE

Possible value for onDelete() or onUpdate().

int NO_ACTION

Possible value for onDelete() or onUpdate().

int RESTRICT

Possible value for onDelete() or onUpdate().

int SET_DEFAULT

Possible value for onDelete() or onUpdate().

int SET_NULL

Possible value for onDelete() or onUpdate().

 

範例如下:

 @Entity(
     foreignKeys = [ForeignKey(
         entity = User::class,
         parentColumns = arrayOf("uid"), // uid of User Entity
         childColumns = arrayOf("uid"), // uid of Pet Entity
         onDelete = ForeignKey.CASCADE
     )]
 )
 class Pet(
     @Embedded(prefix = "pet_")
     var info: Info? = null
 ) {
     @PrimaryKey(autoGenerate = true)
     var pid = 0
     var kind: String? = null
     var uid = 0
 }

當我要刪除user時,User的所有Pet都會一併被刪除。 

entity: 根據的entity。這裡為User

parentColumns: 設定parent column key , 也就是 User 中的uid 

childColumns該entity鎖版定的欄位 

onDelete:某個user 被刪除時,會需要做什麼事情。以下說明參數

 

CASCADE

A "CASCADE" action propagates the delete or update operation on the parent key to each dependent child key. For onDelete() action, this means that each row in the child entity that was associated with the deleted parent row is also deleted. For an onUpdate() action, it means that the values stored in each dependent child key are modified to match the new parent key values.

我的說法為:Forign key 本身的資料做更動時(delete or update),使用該forign key的entity 資料也一併delete/update

 

NO_ACTION

When a parent key is modified or deleted from the database, no special action is taken. This means that SQLite will not make any effort to fix the constraint failure, instead, reject the change.

我的理解為:Forign key 本身的資料做更動時(delete or update),不做任何事情。

 

RESTRICT

The RESTRICT action means that the application is prohibited from deleting (for onDelete()) or modifying (for onUpdate()) a parent key when there exists one or more child keys mapped to it. The difference between the effect of a RESTRICT action and normal foreign key constraint enforcement is that the RESTRICT action processing happens as soon as the field is updated - not at the end of the current statement as it would with an immediate constraint, or at the end of the current transaction as it would with a deferred() constraint.

Even if the foreign key constraint it is attached to is deferred(), configuring a RESTRICT action causes SQLite to return an error immediately if a parent key with dependent child keys is deleted or modified.

這個我英文不好, 看不懂要幹嘛。 猜測是保護用,當有人使用該forign key時,其禁止本身做修改與刪除。

 

SET_DEFAULT

The "SET DEFAULT" actions are similar to SET_NULL, except that each of the child key columns is set to contain the columns default value instead of NULL.

我的理解為:Forign key 本身的資料做更動時(delete or update),使用該forign key的entity 資料設為預設值,而不是null

 

SET_NULL

If the configured action is "SET NULL", then when a parent key is deleted (for onDelete()) or modified (for onUpdate()), the child key columns of all rows in the child table that mapped to the parent key are set to contain NULL values.

我的理解為:Forign key 本身的資料做更動時(delete or update),使用該forign key的entity 資料清空為null

 

注意 

@Insert(onConflict = REPLACE)的處理流程是,delete舊資料,再insert新的資料。

若 primary key 用 auto generate 的話,key 會不同唷,這樣會導致Relation找不到正確的資料唷。

 

相關做法

https://gitlab.com/jc7003/roomsample/ 

tag: room_forign_key

 

 

 

arrow
arrow
    文章標籤
    android room foreginkey
    全站熱搜

    Owen Chen 發表在 痞客邦 留言(0) 人氣()