SQLite-迁移链接的数据,如何避免硬编码的主键

问题描述 投票:0回答:1

我正在为SQLite DB编写SQL迁移,并且已经链接了表,所以我必须先插入'root'表行,然后再插入'children'行,该ID将为'root'行使用ID。

[一种选择可能是对'root'行的主键进行硬编码,并在以后在所有相关行中重用它,但我不愿意冒'重复ID'错误的风险。

我知道SQLite中有一个'last_insert_rowid',我可以使用临时表为以下插入操作保存该值,但仍然可能缺少最佳的方法。

例如,我有表格:

  • 植物(id)
  • PlantDescription(id,language_id,plant_id,desctiption)
  • PlantLink(id,language_id,plant_id,链接)

而且我要插入以下内容:

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解决方案都应适用。

sql sqlite android-room
1个回答
0
投票

有了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);
© www.soinside.com 2019 - 2024. All rights reserved.