通過一個簡單的例子來學習Sqlite,學生選課系統,一開始的需求是學生可以選課,選課完成後可以查詢到已經選擇的課。
首先設計三個表,學生,課程,選課。學生表格儲存體學生的資訊,課程表儲存課程的資訊,選課表格儲存體學生已經選擇的課程。建表的語句可以通過SQLite Expert這個軟體來測試。
在Sqlite Expert中建立一個資料庫
切換到SQL標籤
分別執行如下語句
Students(id , name Subjects(id , name Subject_Select(id , student_id Students(id), subject_id Subjects(id), unique_check text unique not null)
成功建立了3個表,說明SQL語句沒有錯誤
接下來使用代碼來建立資料庫
= = context.openOrCreateDatabase("select.db", Context.MODE_PRIVATE, version = currentVersion = 1 (version >= 0 mDatabase.execSQL("VACUUM" "create table if not exists Students(id integer primary key, name text not null)""create table if not exists Subjects(id integer primary key, name text not null)""create table if not exists Subject_Select(id integer primary key, " + "student_id integer references Students(id), " + "subject_id integer references Subjects(id)," + "unique_check text unique not null)"
由於使用的單例,要重寫application:
TestApplication
在AndroidManifest.xml中添加application
代碼結構為:
運行程式,會在私人目錄建立資料庫
在TestSqlite加入插入student和subject的代碼
insertStudentInfo( (name == -1 (mInsertStudentInfoStatement == = mDatabase.compileStatement("insert or ignore into Students values (?,?)"12 insertSubjectInfo( (name == -1 (mInsertSubjectInfoStatement == = mDatabase.compileStatement("insert or ignore into Subjects values (?,?)"12
這兩個操作沒有使用execSQL而是使用的SQLiteStatement,這樣可以提高效率。
插入選課代碼為:
insertSubjectSelectInfo( student_id, (mInsertSubjectSelectStatement == ="insert or ignore into Subject_Select(student_id, subject_id, unique_check) values (?,?,?)"= student_id + "_" +123
Subject_Select表的主鍵id自動產生,student_id和subject_id添加了references進行約束,必須是Students和Subjects表中的資料。unique_check添加了unique約束,內容為使用student_id和subject_id拼成的一個字串,防止插入重複的資料
在MainActiviy中進行測試
MainActivity 1, "小明"2, "小白"1, "數學"2, "語文"3, "英語"4, "物理"5, "化學"1, 11, 31, 42, 22, 42, 5
通過學生的id查詢所選的課程名稱:
List<String> getSelectSubjectNameByStudentId(<String> list = ArrayList<String>= String[] { id + ""= mDatabase.rawQuery("select subjects.name from subjects,subject_select " + "where subject_select.student_id = ? " + "and subject_select.subject_id = subjects.id"0
使用的cursor中有一點要注意,在拼接SQL語句的時候,可以直接將參數拼到字串裡,例如:
Cursor cursor2 = mDatabase.rawQuery("select name from Students where id = " + id, );
也可以
Cursor cursor2 = mDatabase.rawQuery("select name from Students where id = ?", String[] { id + "" });
一般情況下,這兩種寫法效果是一樣的,但是第二種方法的優點是不用考慮逸出字元,像 \%$&/" 這樣的字串直接就可以使用,而第一種方法要考慮進行轉義,否則不能正常進行識別。
測試查詢的代碼:
List<String> list = TestSqlite.Instance().getSelectSubjectNameByStudentId(1
至此,一個簡單的資料庫就設計完成了,經過進一步的完善,軟體上線了,在開發2.0的時候,又有了一新的需求,要有課程的分數,這就需要在Subject_Select表添加一個新的欄位score。又要保留之前的資料,在1.0的基礎上進行升級,又要添加新的功能,這就需要對資料庫進行重構。
我們要做的就是
1)將Subject_Select重新命名為Subject_Select_Obsolete
2)按新的需求建立一個Subject_Select
3)將Subject_Select_Obsolete的資料複製到Subject_Select
4)刪除Subject_Select_Obsolete
SQL語句為
Subject_Select rename Subject_Select_Obsolete
Subject_Select(id , student_id Students(id), subject_id Subjects(id),unique_check , score )
Subject_Select (id,student_id,subject_id,unique_check) id,student_id,subject_id,unique_check Subject_Select_Obsolete
Subject_Select_Obsolete
首先要在代碼中進行判斷:
version = currentVersion = 2 (version >= 0 1 mDatabase.execSQL("VACUUM"
在上面的代碼中,如果資料庫版本為0,說明不存在就的資料庫,直接建立表,如果資料庫版本為1,說明有老版本的資料庫,要對資料庫進行升級。不管是升級還是全新的建立,資料庫的版本都設定為2。
資料庫升級的代碼為:
"alter table Subject_Select rename to Subject_Select_Obsolete""create table Subject_Select(id integer primary key, student_id integer references Students(id), subject_id integer references Subjects(id),unique_check text unique not null, score real)""insert into Subject_Select (id,student_id,subject_id,unique_check) select id,student_id,subject_id,unique_check from Subject_Select_Obsolete""drop table Subject_Select_Obsolete"