gpt4 book ai didi

android - 如何在 Android 中正确使用外键,使用 SQLite 和 OrmLite

转载 作者:IT王子 更新时间:2023-10-29 06:29:32 24 4
gpt4 key购买 nike

首先,我用这 2 个表创建了数据库: 地址和电话。

我已经使用 Ormlite 在 android 中实现了外键,以便从 Adresse 到 Telephones 建立 1 到 many 的连接。

电话代码:

@DatabaseTable(tableName = "TELEPHONES")
public class Telephone {
public static final String TABLE_NAME = "TELEPHONES";
public static final String ID_ADRESSE = "ID_ADRESSE";

@DatabaseField(generatedId = true)
private Integer _id;

@DatabaseField(canBeNull = false, foreign = true,columnName = ID_ADRESSE)
private Adresse adresse;
.
.
.
.
public Adresse getAdresse() {
return adresse;
}

public void setAdresse(Adresse adresse) {
this.adresse = adresse;
}
}

地址代码:

@DatabaseTable(tableName = "ADRESSE")
public class Adresse {

public static final String TABLE_NAME = "ADRESSE";
public static final String ID = "_id";

@DatabaseField(generatedId = true)
private Integer _id;

@ForeignCollectionField(eager = false)
private ForeignCollection<Telephone> telephones;
}

我还读到 SQLite 数据库实现了外键,但每次打开数据库时都必须启用它们,才能对其进行修改。所以我添加了这段代码:

.
.
.
public void openDataBase() {
// Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
if (!myDataBase.isReadOnly()) {
myDataBase.execSQL("PRAGMA foreign_keys=ON;");
} else {
System.out.println("database is open as read only");
}
}
.
.
.

问题是,通常如果我想删除一个有一个或多个电话的地址,外键约束不应该让我这样做,但没有任何反应。没有错误,没有警告,什么都没有。当我在数据库中查看我是否删除了地址时,我看到地址已删除,电话仍然存在,id_adresse 链接到我删除的那个。

我已经使用 Firefox 中的 SQLite 管理器打开了数据库,当我尝试做同样的事情时,发生了一个错误,告诉我,由于外键,不能这样做....

差点忘了:

Sqlite 中电话表的代码:

CREATE TABLE "TELEPHONES" 
("_id" INTEGER PRIMARY KEY NOT NULL,"ID_ADRESSE" INTEGER REFERENCES ADRESSE(_id))

所以我的最后一个问题是:

我做错了什么,因为在 Android 中我可以删除地址?

我想要的是正确实现外键,不先删除与地址相关的电话就不能删除地址。

更新: 我试过这样做:

public void openDataBase() {
// Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
if (!myDataBase.isReadOnly()) {
myDataBase.execSQL("PRAGMA foreign_keys=ON");
myDataBase.execSQL("DELETE FROM ADRESSE WHERE _id=8");
}
}

它确实删除了地址和相关电话。

那么为什么要使用 ormlite 命令:

    DeleteBuilder<Adresse, Integer> db = daoAdresse.deleteBuilder();
db.where().eq(Adresse.ID, 8);
daoAdresse.delete(db.prepare());

在交易中不起作用?

更新 2:

@Override
public void onOpen(SQLiteDatabase myDatabase){
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
if (!myDataBase.isReadOnly()) {
myDataBase.execSQL("PRAGMA foreign_keys=ON");
System.out.println("open database with pragma on from onOpen");
} else {
System.out.println("database is open as read only from onOpen");
}

}

我这样做了,我收到消息说使用了这种方法,而不是另一种方法,但只是删除了我的地址,没有电话。所以我真的不知道。肯定是哪里出了问题,我觉得跟DeleteBuilder有关系……

仍在寻找..

最佳答案

据我所知,支持外键限制,但您必须明确设置它。 This answer可能会帮助你。请注意,如评论中所述,它仅适用于 Android 2.2 及更高版本。

更新

您还没有定义更新/删除操作。在 Telephone 中,将您的列定义更新为以下内容:

@DatabaseField(canBeNull = false, foreign = true, columnDefinition = "integer references ADRESSE(_id) on delete cascade")
private Adresse adresse;

并重新创建您的数据库。注意“删除级联”;当删除 ADRESSE 中的一行时,应删除 TELEPHONES 中的所有相关条目。

关于android - 如何在 Android 中正确使用外键,使用 SQLite 和 OrmLite,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13493535/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com