如何使用SQLite数据库将数据库表和列连接在一起

时间:2012-10-03 07:40:51

标签: android sqlite foreign-keys primary-key

我正在开发Android应用程序。它涉及SQLite数据库。我在一个数据库中创建了5个表,并创建了5个DBAdapter。

我在这些表中有主键(好友列表,标题,事件,喜欢和不喜欢)和4个表中的外键(标题,事件,喜欢和不喜欢)。这些表是在SQLite数据库中创建的。

哦,我编写了一个DBAdapter来创建5个表,需要将表连接在一起,主要和&外键在一起。而其他4个DBAdapter适用于5个表中的每一个。我只是发布代码,你可能会得到我说的和我需要的东西。

AnniversaryDBAdapter - 创建了5个表。

public class AnniversaryDBAdapter
{

    private static final String DATABASE_NAME = "Tables";
    private static final int DATABASE_VERSION = 2;

    private static final String CREATE_TABLE_TITLE = "create table titles(title_id integer primary key autoincrement, title text not null, image text not null);";
    private static final String CREATE_TABLE_BUDDIESLIST = "create table buddiesList(name_id integer primary key autoincrement, name text not null);";
    private static final String CREATE_TABLE_LIKES = "create table likes(likes_id integer primary key autoincrement,like text not null, name_id integer not null, FOREIGN KEY(name_id) REFERENCES buddiesList(name_id));";
    private static final String CREATE_TABLE_DISLIKES = "create table dislikes(dlike_id integer primary key autoincrement, dislike text not null, name_id integer not null, FOREIGN KEY(name_id) REFERENCES buddiesList(name_id));";
    private static final String CREATE_TABLE_EVENTS = "create table event(event_id integer primary key autoincrement, title_id integer not null, location text not null, starttime text not null, endtime text not null, desc text not null, date text not null, name_id integer not null, FOREIGN KEY(title_id) REFERENCES titles(title_id));";

    private final Context context;
    private static final String TAG = "DBAdapter";

    private DatabaseHelper DBHelper;
    protected SQLiteDatabase db;

    private static String DB_PATH = "/data/data/main.page/Tables/";


    public AnniversaryDBAdapter(Context aContext)
    {
        this.context = aContext;
        DBHelper = new DatabaseHelper(context);
    }




private static class DatabaseHelper extends SQLiteOpenHelper
{

    DatabaseHelper(Context context)
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db)
    {
        /*try
        {
            database.execSQL(CREATE_TABLE_BUDDIESLIST);
            database.execSQL(CREATE_TABLE_LIKES);
            database.execSQL(CREATE_TABLE_EVENTS);
            database.execSQL(CREATE_TABLE_TITLE);
            database.execSQL(CREATE_TABLE_DISLIKES);
        }catch(SQLException e)
        {
            e.printStackTrace();
        }*/

        db.execSQL(CREATE_TABLE_BUDDIESLIST);
        db.execSQL(CREATE_TABLE_LIKES);
        db.execSQL(CREATE_TABLE_EVENTS);
        db.execSQL(CREATE_TABLE_TITLE);
        db.execSQL(CREATE_TABLE_DISLIKES);
/*      database.execSQL("CREATE TRIGGER fk_budevent_nameid" +
                "BEFORE INSERT" +
                "ON events FOR EACH ROW BEGIN" +
                "SELECT CASE WHEN((SELECT name_id FROM buddiesList WHERE name_id = new.name_id) IS NULL)" +
                "THEN RAISE(ABORT, 'Foreign Key Violation')END;" +
                "END;");
        */


    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
        Log.w(TAG, "Upgrading database from version "+oldVersion+" to "+newVersion+", which will destroy all old data");

        onCreate(db);

    }

}


public AnniversaryDBAdapter open() throws SQLException
{
    db = this.DBHelper.getWritableDatabase();
/*  if(!db.isReadOnly())
    {
        db.execSQL("PRAGMA foreign_keys = ON;");
    }*/
    return this;
}

public void close()
{
    DBHelper.close();
}
/*
public long insertEvent(String title,String location,String starttime,String endtime,String desc,String date, String name)
{
   ContentValues cValues = new ContentValues();



   cValues.put(KEY_TITLE, title);
   cValues.put(KEY_LOCATION, location);
   cValues.put(KEY_START, starttime);
   cValues.put(KEY_END, endtime);
   cValues.put(KEY_DESC, desc);
   cValues.put(KEY_ALARM, alarm);
   cValues.put(KEY_DATE, date);
   cValues.put(KEY_NAME, name);


   return db.insert(CREATE_TABLE_EVENTS, null, cValues);

}

public boolean deleteEvent(long rowId)
{
    return db.delete(CREATE_TABLE_EVENTS, KEY_ROWID + "=" + rowId, null) > 0;
}

public Cursor getAllEvents()
{
    return db.query(CREATE_TABLE_EVENTS, new String[] {KEY_ROWID, KEY_TITLE, KEY_LOCATION, KEY_START, KEY_END, KEY_DESC, KEY_DATE, KEY_NAME}, null, null, null, null, null);

}

public Cursor getEvent(long rowId) throws SQLException
{
    Cursor c = db.query(true,CREATE_TABLE_EVENTS, new String[] {KEY_ROWID, KEY_TITLE, KEY_LOCATION, KEY_START, KEY_END, KEY_DESC, KEY_DATE, KEY_NAME}, KEY_ROWID + "=" + rowId, null, null, null, null, null);
    if(c != null)
    {
        c.moveToFirst();
    }
    return c;
}
*/
}

正如你在AnniversaryDBAdapter中看到的那样,在buddiesList表中,name_id是链接到event,likes和dislikes表的主键。事件中的name_id,喜欢和不喜欢的表是从buddiesList表中检索的外键。但是,当我在事件页面中键入事件详细信息并将它们保存到事件表中时,表中的name_id应该是从buddiesList表中检索的数字,而是存储为名称而不是id。喜欢和不喜欢也是如此。

另外,如果取消注释if(!db.isReadOnly()) { db.execSQL("PRAGMA foreign_keys = ON;"); },我无法打开信息,事件&短信页面,我得到了强制关闭消息。

BuddyDBAdapter - buddiesList表

public class BuddyDBAdapter extends AnniversaryDBAdapter
{
    public static final String KEY_ROWID = "name_id";
    public static final String KEY_NAME = "name";
    private static final String TAG = "DBAdapter";
    private static final String CREATE_TABLE_BUDDIESLIST = "buddiesList";

    //private SQLiteDatabase db;

    public BuddyDBAdapter(Context aContext)
    {
        super(aContext);
    }

    public long insertNames(String name)
    {
        ContentValues buddyValues = new ContentValues();
        buddyValues.put(KEY_NAME, name);
        return db.insert(CREATE_TABLE_BUDDIESLIST, null, buddyValues);
    }

    public boolean deleteNames(long rowId)
    {
        return db.delete(CREATE_TABLE_BUDDIESLIST, KEY_ROWID + "=" + rowId, null) > 0;
    }

    public Cursor getAllNames()
    {

           return db.query(CREATE_TABLE_BUDDIESLIST, new String[] { KEY_ROWID, KEY_NAME }, null, null, null, null, null);


    }

    public Cursor getNames(long rowId) throws SQLException
    {
        Cursor c = db.query(true, CREATE_TABLE_BUDDIESLIST, new String[] { KEY_ROWID, KEY_NAME }, KEY_ROWID + "=" + rowId, null, null, null, null, null);
        if(c != null)
        {
            c.moveToFirst();
        }
        return c;
    }
}

BuddyDBAdapter中的代码类似于CalendarAdapter(事件表),LikesDBAdapter(喜欢表格)和DislikesDBAdapter(不喜欢表格),除了表格和列名称

我的问题是,我不确定如何将表连接在一起。并且,如何在SQLite数据库中启用外键。

即使我输入类似

    private static final String CREATE_TABLE_TITLE = "create table titles(title_id integer primary key autoincrement, title text not null, image text not null);";
    private static final String CREATE_TABLE_BUDDIESLIST = "create table buddiesList(name_id integer primary key autoincrement, name text not null);";
    private static final String CREATE_TABLE_LIKES = "create table likes(likes_id integer primary key autoincrement,like text not null, name_id integer not null, FOREIGN KEY(name_id) REFERENCES buddiesList(name_id));";
    private static final String CREATE_TABLE_DISLIKES = "create table dislikes(dlike_id integer primary key autoincrement, dislike text not null, name_id integer not null FOREIGN KEY(name_id) REFERENCES buddiesList(name_id));";
    private static final String CREATE_TABLE_EVENTS = "create table event(event_id integer primary key autoincrement, title_id integer not null, location text not null, starttime text not null, endtime text not null, desc text not null, date text not null, name_id integer not null, FOREIGN KEY(name_id) REFERENCES buddiesList(name_id), FOREIGN KEY(title_id) REFERENCES titles(title_id));";


if(!db.isReadOnly())
    {
        db.execSQL("PRAGMA foreign_keys = ON;");
    }

我仍然有力量关闭错误。

另外,我不确定如何将来自buddiesList表的name_id连接到事件,喜欢&不喜欢桌子。同样,将titles表中的title_id连接到事件表中的title_id。

任何人都可以帮我解决这个问题吗?我们将非常感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:0)

你缺少一些指数;见Required and Suggested Database Indexes

更改数据时,请确保其始终有效,例如,在其子项之前插入父项,并删除其父项之前的所有子项。