加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-12 19:00:51 所属栏目:百科 来源:网络整理
导读:首先,我用这两个表创建了数据库: ?Adresse和电话. 我使用Ormlite在android中实现了外键,以便从Adresse到电话进行1对多的连接. TELEPHONES的代码: @DatabaseTable(tableName = "TELEPHONES")public class Telephone { public static final String TABLE_NAM
首先,我用这两个表创建了数据库:
?Adresse和电话.

我使用Ormlite在android中实现了外键,以便从Adresse到电话进行1对多的连接.

TELEPHONES的代码:

@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;
    }  
}

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 Manager打开数据库,当我尝试做同样的事情时,发生错误告诉我,由于外键而无法做到这一点….

差点忘了:

Sqlite中的表Telephone的代码:

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

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

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

我想要的是正确实现外键,不能删除该地址而不删除与该地址相关的电话.

更新:
??我试过这样做:

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

它确实删除了adresse以及相关的电话.

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

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

在tranzaction里面没有用?

更新2:

@Override
    public void onOpen(SQLiteDatabase myDatabase){
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath,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及更高版本.

UPDATE

您尚未定义操作如何更新/删除.在“电话”中,将列定义更新为以下内容:

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读