如何将数据插入多对多关系表并检索最后一个 ID 在该方法接受两个参数的情况下?
How to Insert data to Many to many relationship tables and retrieving last id In cases where the method accepts two parameters?
当输入只有一个参数时,Room return 插入的 id
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertWithDrinks(item: DrinkFavourite): Long
当方法看起来像这样时,我如何检索 ID
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertWithDrinks(item: DrinkFavourite, List<Drink>)
或者更确切地说,你如何处理多对多关系插入?我有这样的关系和交叉引用 table
data class DrinkFavouritesWithDrinks(
@Embedded
val item: DrinkFavourite,
@Relation(
parentColumn = "item_id",
entityColumn = "drink_id",
associateBy = Junction(DrinkFavouriteAndDrinksCrossRef::class)
)
val drinks: List<Drink> = emptyList()
)
我的交叉引用
@Entity(
primaryKeys = ["item_id", "drink_id"]
)
data class DrinkFavouriteAndDrinksCrossRef(
@ColumnInfo(name = "item_id")
val itemId: Long,
@ColumnInfo(name = "drink_id")
val drinkId: Int
)
How can i retrieve the ID when method looks like this
当您插入多行时,您会在 Array<Long>
中获得结果 ID
但是,对于基本交叉 reference/mapping table,您很少会使用 rowid 列(即返回值)。
rowid 即使该列是隐式定义的,也会返回。也就是说,除了很少使用的 WITHOUT ROWID tables 之外,所有 tables 都有一个名为 rowid 的隐藏列。
- 当您使用
INTEGER PRIMARY KEY
定义列时,该列是rowid列的别名。在房间 @PrimaryKey 中,对于 Long 或 Int,有或没有 autoGenerate = true/false
(没有 = false)等于 INTEGER PRIMARY KEY
或者如果 autoGenerate = true
等于 INTEGER PRIMARY KEY AUTOINCREMENT
.
How do you handle many-to-many relationship Insert?
这是一个基于可用代码并创建了其他代码的示例。
所以除了你的 DrinkFavouriteAndDrinksCrossRef 实体。
DrinkFavourite 和 Item 的实体是
@Entity
data class DrinkFavourite(
@PrimaryKey
val drink_id: Int? = null,
val drink_name: String = ""
)
@Entity
数据class饮料(
@PrimaryKey var itemId : 长?,
变种项目名称:字符串
)
The Dao AllDao 是:-
@Dao
interface AllDao {
@Insert
fun insertDrinkFavourite(drinkFavourite: DrinkFavourite) :Long
@Insert
fun insertManyDrinkFavourite(drinkFavourites: List<DrinkFavourite>) :Array<Long>
@Insert
fun insertItem(drink: Drink) :Long
@Insert
fun insertManyItems(drinks: List<Drink>) :Array<Long>
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insertDrinkFavouriteAndDrinksCrossRef(drinkFavouriteAndDrinksCrossRef: DrinkFavouriteAndDrinksCrossRef) :Long
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insertManyDrinkFavouriteAndDrinksCrossRef(drinkFavouriteAndDrinksCrossRefs: List<DrinkFavouriteAndDrinksCrossRef>) :Array<Long>
}
- 这适合为 3 个实体中的每一个插入一个 Entity/row 和多个 Entity/row。
下面利用道中定义的3多插入插入3Drink
、4DrinkFavourite
再插入12DrinkFavouriteAndDrinksCrossRef
(3Drink
* 4 DrinkFavorite
) 排列,即所有可能的排列,可以根据插入的 id 进行交叉引用。
class MainActivity : AppCompatActivity() {
lateinit var database: Database
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
database = Room.databaseBuilder(this, Database::class.java, "drinksdb")
.allowMainThreadQueries()
.build()
//val firsItemtid = database.allDao().insertItem( Item(0,"X"))
val manyItemIds = database.allDao().insertManyItems(
listOf(
Drink(null,"A"),
Drink(null,"B"),
Drink(null,"C")
)
)
val manyDrinkFavouriteIds = database.allDao().insertManyDrinkFavourite(
listOf(
DrinkFavourite(null,"DrinkA"),
DrinkFavourite(null,"DrinkB"),
DrinkFavourite(null,"DrinkC"),
DrinkFavourite(null,"DrinkD")
)
)
var xrefcombos = ArrayList<DrinkFavouriteAndDrinksCrossRef>()
for(itemId: Long in manyItemIds) {
for (dfId: Long in manyDrinkFavouriteIds) {
xrefcombos.add( DrinkFavouriteAndDrinksCrossRef(itemId,dfId.toInt()))
}
}
val drinkFavouriteAndDrinksCrossRefIdList = database.allDao().insertManyDrinkFavouriteAndDrinksCrossRef(xrefcombos)
for (dfadcrId in drinkFavouriteAndDrinksCrossRefIdList) {
Log.d("DRKFAVDRNKXREF","Id = " + dfadcrId)
}
}
}
输出为:-
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 1
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 2
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 3
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 4
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 5
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 6
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 7
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 8
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 9
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 10
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 11
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 12
即添加了 12 个排列。
除了根据插入的 Entity/Object 进行插入之外,我不相信您可以有效地使用 @Insert
进行其他操作。要根据其他值进行更复杂的插入,您可以使用 @Query
和 suitable SQL.
额外
关于 :-
data class DrinkFavouritesWithDrinks(
@Embedded
val item: DrinkFavourite,
@Relation(
parentColumn = "item_id",
entityColumn = "drink_id",
associateBy = Junction(DrinkFavouriteAndDrinksCrossRef::class)
)
我认为这应该是:-
data class DrinkFavouriteWithDrinks (
@Embedded
val drinkFavourite: DrinkFavourite,
@Relation(
entity = Drink::class,
entityColumn = "itemId",
parentColumn = "drink_id",
associateBy = Junction(
DrinkFavouriteAndDrinksCrossRef::class,entityColumn = "item_id",parentColumn = "drink_id"))
val drinks: List<Drink> = emptyList()
)
- 您可以获得每个 DrinkFavourite 的所有饮料,因此单数而不是复数是一个更好的名称。
- 关联需要知道要关联的列。
你可以有一个 Dao 方法,例如:-
@Query("SELECT * FROM drinkfavourite")
fun getAllDrinkFavouritesWithDrinks() :List<DrinkFavouriteWithDrinks>
将以下内容添加到上面的 MainActivity 中:-
val drinkFavouriteWithDrinksList = database.allDao().getAllDrinkFavouritesWithDrinks()
var sb = StringBuilder()
for (dfwd: DrinkFavouriteWithDrinks in drinkFavouriteWithDrinksList) {
sb.clear().append("DrinkFavourite = ").append(dfwd.drinkFavourite)
for (d: Drink in dfwd.drinks) {
sb.append("\n\tDrink = ").append(d.itemName)
}
Log.d("DRINKFAVINFO", sb.toString())
}
结果:-
2020-01-17 11:39:52.762 D/DRINKFAVINFO: DrinkFavourite = DrinkFavourite(drink_id=1, drinkFavouriteName=DrinkA)
Drink = A
Drink = B
Drink = C
2020-01-17 11:39:52.763 D/DRINKFAVINFO: DrinkFavourite = DrinkFavourite(drink_id=2, drinkFavouriteName=DrinkB)
Drink = A
Drink = B
Drink = C
2020-01-17 11:39:52.763 D/DRINKFAVINFO: DrinkFavourite = DrinkFavourite(drink_id=3, drinkFavouriteName=DrinkC)
Drink = A
Drink = B
Drink = C
2020-01-17 11:39:52.763 D/DRINKFAVINFO: DrinkFavourite = DrinkFavourite(drink_id=4, drinkFavouriteName=DrinkD)
Drink = A
Drink = B
Drink = C
- 不是最好的例子,因为每个 DrinkFavourite 都有这三种饮料
当输入只有一个参数时,Room return 插入的 id
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertWithDrinks(item: DrinkFavourite): Long
当方法看起来像这样时,我如何检索 ID
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertWithDrinks(item: DrinkFavourite, List<Drink>)
或者更确切地说,你如何处理多对多关系插入?我有这样的关系和交叉引用 table
data class DrinkFavouritesWithDrinks(
@Embedded
val item: DrinkFavourite,
@Relation(
parentColumn = "item_id",
entityColumn = "drink_id",
associateBy = Junction(DrinkFavouriteAndDrinksCrossRef::class)
)
val drinks: List<Drink> = emptyList()
)
我的交叉引用
@Entity(
primaryKeys = ["item_id", "drink_id"]
)
data class DrinkFavouriteAndDrinksCrossRef(
@ColumnInfo(name = "item_id")
val itemId: Long,
@ColumnInfo(name = "drink_id")
val drinkId: Int
)
How can i retrieve the ID when method looks like this
当您插入多行时,您会在 Array<Long>
但是,对于基本交叉 reference/mapping table,您很少会使用 rowid 列(即返回值)。
rowid 即使该列是隐式定义的,也会返回。也就是说,除了很少使用的 WITHOUT ROWID tables 之外,所有 tables 都有一个名为 rowid 的隐藏列。
- 当您使用
INTEGER PRIMARY KEY
定义列时,该列是rowid列的别名。在房间 @PrimaryKey 中,对于 Long 或 Int,有或没有autoGenerate = true/false
(没有 = false)等于INTEGER PRIMARY KEY
或者如果autoGenerate = true
等于INTEGER PRIMARY KEY AUTOINCREMENT
.
- 当您使用
How do you handle many-to-many relationship Insert?
这是一个基于可用代码并创建了其他代码的示例。
所以除了你的 DrinkFavouriteAndDrinksCrossRef 实体。
DrinkFavourite 和 Item 的实体是
@Entity
data class DrinkFavourite(
@PrimaryKey
val drink_id: Int? = null,
val drink_name: String = ""
)
@Entity
数据class饮料( @PrimaryKey var itemId : 长?, 变种项目名称:字符串 )
The Dao AllDao 是:-
@Dao
interface AllDao {
@Insert
fun insertDrinkFavourite(drinkFavourite: DrinkFavourite) :Long
@Insert
fun insertManyDrinkFavourite(drinkFavourites: List<DrinkFavourite>) :Array<Long>
@Insert
fun insertItem(drink: Drink) :Long
@Insert
fun insertManyItems(drinks: List<Drink>) :Array<Long>
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insertDrinkFavouriteAndDrinksCrossRef(drinkFavouriteAndDrinksCrossRef: DrinkFavouriteAndDrinksCrossRef) :Long
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insertManyDrinkFavouriteAndDrinksCrossRef(drinkFavouriteAndDrinksCrossRefs: List<DrinkFavouriteAndDrinksCrossRef>) :Array<Long>
}
- 这适合为 3 个实体中的每一个插入一个 Entity/row 和多个 Entity/row。
下面利用道中定义的3多插入插入3Drink
、4DrinkFavourite
再插入12DrinkFavouriteAndDrinksCrossRef
(3Drink
* 4 DrinkFavorite
) 排列,即所有可能的排列,可以根据插入的 id 进行交叉引用。
class MainActivity : AppCompatActivity() {
lateinit var database: Database
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
database = Room.databaseBuilder(this, Database::class.java, "drinksdb")
.allowMainThreadQueries()
.build()
//val firsItemtid = database.allDao().insertItem( Item(0,"X"))
val manyItemIds = database.allDao().insertManyItems(
listOf(
Drink(null,"A"),
Drink(null,"B"),
Drink(null,"C")
)
)
val manyDrinkFavouriteIds = database.allDao().insertManyDrinkFavourite(
listOf(
DrinkFavourite(null,"DrinkA"),
DrinkFavourite(null,"DrinkB"),
DrinkFavourite(null,"DrinkC"),
DrinkFavourite(null,"DrinkD")
)
)
var xrefcombos = ArrayList<DrinkFavouriteAndDrinksCrossRef>()
for(itemId: Long in manyItemIds) {
for (dfId: Long in manyDrinkFavouriteIds) {
xrefcombos.add( DrinkFavouriteAndDrinksCrossRef(itemId,dfId.toInt()))
}
}
val drinkFavouriteAndDrinksCrossRefIdList = database.allDao().insertManyDrinkFavouriteAndDrinksCrossRef(xrefcombos)
for (dfadcrId in drinkFavouriteAndDrinksCrossRefIdList) {
Log.d("DRKFAVDRNKXREF","Id = " + dfadcrId)
}
}
}
输出为:-
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 1
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 2
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 3
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 4
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 5
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 6
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 7
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 8
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 9
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 10
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 11
2020-01-17 07:46:40.621 D/DRKFAVDRNKXREF: Id = 12
即添加了 12 个排列。
除了根据插入的 Entity/Object 进行插入之外,我不相信您可以有效地使用 @Insert
进行其他操作。要根据其他值进行更复杂的插入,您可以使用 @Query
和 suitable SQL.
额外
关于 :-
data class DrinkFavouritesWithDrinks(
@Embedded
val item: DrinkFavourite,
@Relation(
parentColumn = "item_id",
entityColumn = "drink_id",
associateBy = Junction(DrinkFavouriteAndDrinksCrossRef::class)
)
我认为这应该是:-
data class DrinkFavouriteWithDrinks (
@Embedded
val drinkFavourite: DrinkFavourite,
@Relation(
entity = Drink::class,
entityColumn = "itemId",
parentColumn = "drink_id",
associateBy = Junction(
DrinkFavouriteAndDrinksCrossRef::class,entityColumn = "item_id",parentColumn = "drink_id"))
val drinks: List<Drink> = emptyList()
)
- 您可以获得每个 DrinkFavourite 的所有饮料,因此单数而不是复数是一个更好的名称。
- 关联需要知道要关联的列。
你可以有一个 Dao 方法,例如:-
@Query("SELECT * FROM drinkfavourite")
fun getAllDrinkFavouritesWithDrinks() :List<DrinkFavouriteWithDrinks>
将以下内容添加到上面的 MainActivity 中:-
val drinkFavouriteWithDrinksList = database.allDao().getAllDrinkFavouritesWithDrinks()
var sb = StringBuilder()
for (dfwd: DrinkFavouriteWithDrinks in drinkFavouriteWithDrinksList) {
sb.clear().append("DrinkFavourite = ").append(dfwd.drinkFavourite)
for (d: Drink in dfwd.drinks) {
sb.append("\n\tDrink = ").append(d.itemName)
}
Log.d("DRINKFAVINFO", sb.toString())
}
结果:-
2020-01-17 11:39:52.762 D/DRINKFAVINFO: DrinkFavourite = DrinkFavourite(drink_id=1, drinkFavouriteName=DrinkA) Drink = A Drink = B Drink = C 2020-01-17 11:39:52.763 D/DRINKFAVINFO: DrinkFavourite = DrinkFavourite(drink_id=2, drinkFavouriteName=DrinkB) Drink = A Drink = B Drink = C 2020-01-17 11:39:52.763 D/DRINKFAVINFO: DrinkFavourite = DrinkFavourite(drink_id=3, drinkFavouriteName=DrinkC) Drink = A Drink = B Drink = C 2020-01-17 11:39:52.763 D/DRINKFAVINFO: DrinkFavourite = DrinkFavourite(drink_id=4, drinkFavouriteName=DrinkD) Drink = A Drink = B Drink = C
- 不是最好的例子,因为每个 DrinkFavourite 都有这三种饮料