我正在为SQLite DB编写SQL迁移,并且已经链接了表,所以我必须先插入'root'表行,然后再插入'children'行,该ID将为'root'行使用ID。
[一种选择可能是对'root'行的主键进行硬编码,并在以后在所有相关行中重用它,但我不愿意冒'重复ID'错误的风险。
我知道SQLite中有一个'last_insert_rowid',我可以使用临时表为以下插入操作保存该值,但仍然可能缺少最佳的方法。
例如,我有表格:
而且我要插入以下内容:
INSERT INTO Plant VALUES (123);
INSERT INTO PlantDescription VALUES (1, 1, 123, 'some description');
INSERT INTO PlantLink VALUES (1, 1, 123, 'http://eng-link.com');
这里要插入PlantDescription和PlantLink,我需要知道先前插入的Plant的主要ID。
我正在寻找实现这一目标的最佳实践。我正在开发Android应用程序并使用Android Room,但问题可能更笼统,任何SQLite解决方案都应适用。
有了Android Room,插入时便会获得ID,而无需担心,因为底层方法会返回ID(只要它是RowID的别名)。
对于您的情况,您可能会遇到以下问题:-
实体(表):-
Plant.java
@Entity
public class Plant {
@PrimaryKey
Long id;
}
PlantDescription.java
@Entity(
foreignKeys = {
@ForeignKey(
entity = Plant.class,
parentColumns = "id",
childColumns = "plant_id",
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
},
indices = {@Index(value = {"plant_id"})}
)
public class PlantDescription {
@PrimaryKey
Long id;
Long language_Id;
Long plant_id;
String description;
}
PlantLink.java
@Entity(
foreignKeys = {
@ForeignKey(
entity = Plant.class,
parentColumns = "id",
childColumns = "plant_id",
onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.CASCADE
)
},
indices = {@Index(value = {"plant_id"})}
)
public class PlantLink {
@PrimaryKey
Long id;
Long language_id;
Long plant_id;
String link;
}
Dao的(在此示例中为AllDao.Java)
@Dao
public interface AllDao {
@Insert
long insertPlant(Plant plant);
@Insert
long insertPlantDescription(PlantDescription plantDescription);
@Insert
long insertPlantLink(PlantLink plantLink);
}
使用@Database,Mydatabase.java
@Database(version = 1,entities = {Plant.class,PlantLink.class,PlantDescription.class})
public abstract class MyDatabase extends RoomDatabase {
abstract AllDao allDao();
}
然后下面的示例演示了如何在不对工厂的ID进行硬编码的情况下插入结果数据的方法:-
myDatabase = Room.databaseBuilder(this,MyDatabase.class,"mydb")
.allowMainThreadQueries()
.build();
// Insert a plant getting it's id
long plant1 = myDatabase.allDao().insertPlant(new Plant());
// Insert a PlantDescription using the plant id as per the inserted plant
PlantDescription pd = new PlantDescription();
pd.description = "some description";
pd.language_Id = 1L;
pd.plant_id = plant1;
long plantdescription1 = myDatabase.allDao().insertPlantDescription(pd);
pd.id = plantdescription1;
// Insert a PlantLink using the plant id as per the inserted plant
PlantLink pl = new PlantLink();
pl.language_id = 1L;
pl.link = "http://eng-link.com";
pl.plant_id = plant1;
pl.id = myDatabase.allDao().insertPlantLink(pl);