在Kotlin中为Room的@Entity数据类配置@ForeignKey与主键
How to Configure Room @Entity, Primary Key, and Foreign Key for Your Kotlin Data Class
Got it, let's walk through how to properly set up Room's annotations for your Foo data class—including primary keys, foreign keys, and keeping your Parcelable setup intact.
1. Basic @Entity Annotation Setup
First, add the @Entity annotation to your class. In Kotlin, we use square brackets [] for arrays (like the foreignKeys parameter) instead of curly braces, which is a key difference from Java-style Room code.
2. Primary Key Configuration
You have two options for defining a primary key:
- Single-field primary key: Add
@PrimaryKeydirectly to the field you want to use as the unique identifier. If you need an auto-incrementing numeric key, addautoGenerate = trueto the annotation. - Composite primary key: Define multiple fields as the primary key using the
primaryKeysproperty in@Entity(useful if no single field is unique on its own).
3. Foreign Key Configuration
To add a foreign key, you'll need to:
- Add a field to
Foothat maps to the primary key of the parent entity (e.g.,userIdfor aUserentity). - Define the
ForeignKeyinside theforeignKeysarray of@Entity, specifying the parent entity, matching parent/child columns, and delete/update behavior.
Full Example Code
Here's a complete implementation that ties it all together. Let's assume we're using stringOne as the primary key and adding a foreign key to a User entity:
import androidx.room.Entity import androidx.room.ForeignKey import androidx.room.PrimaryKey @Parcel(Parcel.Serialization.BEAN) @Entity( foreignKeys = [ ForeignKey( entity = User::class, parentColumns = ["id"], // Must match the primary key field name in your User entity childColumns = ["userId"], // The field in Foo that links to User's id onDelete = ForeignKey.CASCADE // Adjust behavior as needed (e.g., SET_NULL, RESTRICT) ) ] ) data class Foo @ParcelConstructor constructor( @PrimaryKey val stringOne: String, // Single-field primary key var stringTwo: String, var stringThree: String, var userId: Long // New field to hold the foreign key reference to User ) : BaseFoo() { // If Room runs into instantiation issues (rare with modern Room/Kotlin), add a no-arg constructor: // constructor() : this("", "", "", 0L) } // Ensure your parent User entity is properly annotated too: @Entity data class User( @PrimaryKey(autoGenerate = true) val id: Long = 0, val username: String )
Key Notes
- Foreign Key Matching: The
userIdfield inFoomust match the data type ofUser's primary key (e.g.,LongifUser.idis aLong). - Parcelable Compatibility: Your existing
@ParcelConstructorsetup should work seamlessly with Room. If you encounter issues, adding a no-arg constructor (like the commented one above) can resolve instantiation problems. - Composite Primary Key Example: If you need a composite key, replace the field-level
@PrimaryKeywith:@Entity( primaryKeys = ["stringOne", "stringTwo"], foreignKeys = [...] )
内容的提问来源于stack exchange,提问作者Chisko
相关产品推荐
相关产品推荐

