SQLite數據庫是一款輕型的數據庫,在很多嵌入式產品中使用。它占用的資源非常低,只需要幾百K內存就足夠了。
對windows/linux/unix等多種操作系統提供支持。目前SQLite3是最新的版本。
android系統集成了SQLite數據庫。
我們也可以使用一些工具對SQLite數據庫進行可視化的操作。比如: SQLite Expert Personal 是一款免費的工具。
可以到 http://www.sqliteexpert.com/ 下載使用。
對于SQLite計劃采用一個例子實現對數據庫的一些操作,包含:創建數據庫和數據表;新增記錄;查詢記錄;修改記錄;刪除記錄。還要能復制數據庫以便在其他設備上使用 SQLite Expert 查看。
先構建一個界面。包含6個按鈕和一個顯示結果的TextView。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.cofox.functions.SQLite.SQLiteActivity">
<Button
android:id="@+id/btnCreateSQLiteDatabaseTable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="創建SQLite數據庫和數據表"
android:textAllCaps="false" />
<Button
android:id="@+id/btnSQLiteInsert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="新增記錄" />
<Button
android:id="@+id/btnSQLiteSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查詢記錄" />
<Button
android:id="@+id/btnSQLiteUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="修改記錄" />
<Button
android:id="@+id/btnSQLiteDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="刪除記錄" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="130dp">
<TextView
android:id="@+id/ttvwQueryResult"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="QueryResult" />
</ScrollView>
<Button
android:id="@+id/btnSQLiteDbCopy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="復制數據庫" />
</LinearLayout>
創建SQLite數據庫和數據表
首先在onCreate內添加一個數據庫文件的路徑,讓整個APP來使用。
/**數據庫文件的路徑*/
val fileName = filesDir.toString() + "/cofoxTest.db"
之所以使用/***/這種注釋方式,是因為這樣可讓調用fileName的地方,鼠標懸浮的時候可以看到注釋內容文字。
//創建數據庫和數據表
btnCreateSQLiteDatabaseTable.setOnClickListener {
/**創建數據表的SQL語句*/
val createTableSQL = "CREATE TABLE [cofoxArticle] (" +
"[id] INTEGER PRIMARY KEY AUTOINCREMENT," +
"[title] VARCHAR(50)," +
"[author] VARCHAR(100)," +
"[content] TEXT," +
"[date] DATE," +
"[status] VARCHAR(20)" +
")"
val file = File(fileName)
if (file.exists()){
//如果文件存在就刪除舊文件
file.delete()
}
/**數據庫對象*/
val database = SQLiteDatabase.openOrCreateDatabase(fileName, null)
//建立數據庫數據表
database.execSQL(createTableSQL)
database.close()
Toast.makeText(this, "數據庫"+fileName, Toast.LENGTH_LONG).show()
}
這里創建數據庫的時候是強制創建,如果發現有舊的數據庫,就先刪除舊數據庫,然后再創建。表結構是有一個自增的id字段,為Int型。建立成功后會彈出一個提示框。寫入數據
寫入數據采用了2種寫入的寫法,并且又使用循環做了3次重復寫入。這樣我們點次按鈕,就可以在數據庫中增加5條內容略有差別的記錄了。最細微的差別就是寫入時間date了。
//寫入數據
btnSQLiteInsert.setOnClickListener {
val database = SQLiteDatabase.openOrCreateDatabase(fileName, null)
//第一種方式
val contentValues = ContentValues()
contentValues.put("title", "金龍翼")
contentValues.put("author", "厚土火焰山")
contentValues.put("content", "go和kotlin的技術公司,企業IT系統移動化解決方案。")
contentValues.put("date", getNow())
contentValues.put("status", "edit")
database.insert("cofoxArticle", null, contentValues)
//第二種方式
val insertSQL = "insert into cofoxArticle(title, author, content, date, status) values(?,?,?,?,?)"
database.execSQL(insertSQL, arrayOf("我的公司","Smith","是專業的軟件網絡公司,為企業提供IT技術支撐。", getNow(), "publish"))
//重復添加3條
for (i in 1..3){
val insertSQL = "insert into cofoxArticle(title, author, content, date, status) values(?,?,?,?,?)"
database.execSQL(insertSQL, arrayOf("我的公司","金龍翼","是專業的軟件網絡公司,為企業提供IT技術支撐。", getNow(), "publish"))
}
database.close()
Toast.makeText(this, "寫入數據完成", Toast.LENGTH_LONG).show()
}
這里的時間用到了一個getNow()函數,是用來獲取當前時間的。
/**
* Cofox 日期函數
* created at 2017/12/19 0:06
* 功能描述:返回當前日期,格式:2017-12-19 12:13:55.917
* file:cofoxFuction.kt
*
*
* 修改歷史:
* 2017/12/19:新建
*
*/
fun getNow(): String {
if (android.os.Build.VERSION.SDK_INT >= 24) {
return SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(Date())
} else {
var tms = Calendar.getInstance()
return tms.get(Calendar.YEAR).toString() + "-" + tms.get(Calendar.MONTH+1).toString() + "-" + tms.get(Calendar.DAY_OF_MONTH).toString() + " " + tms.get(Calendar.HOUR_OF_DAY).toString() + ":" + tms.get(Calendar.MINUTE).toString() + ":" + tms.get(Calendar.SECOND).toString() + "." + tms.get(Calendar.MILLISECOND).toString()
}
}
寫入完成,這個時候如何查看結果呢?可以使用數據庫復制出來的辦法。那么先來完成數據庫復制的功能吧。
復制數據庫
//數據庫復制
btnSQLiteDbCopy.setOnClickListener {
copyDb()
}
copyDb()是把存儲在私密文件夾下的數據庫保存到內置SD卡的路徑。這樣就可以很容易的復制到其他地方,不用對手機獲取root權限了。
fun copyDb() {
val fos = FileOutputStream("/sdcard/cofoxTest.db")
val fileName = filesDir.toString() + "/cofoxTest.db"
//獲取執行assets/image.png的inputStream對象
val inputStream = FileInputStream(fileName)
//定義寫入數據時的緩存,每次寫入100字節
val b = byteArrayOf(100)
var count = 0
//循環寫入文件數據
while (true) {
count = inputStream.read(b)
if (count < 0) {
break
}
fos.write(b, 0, count)
}
fos.close()
inputStream.close()
Toast.makeText(this, "數據庫復制保存成功", Toast.LENGTH_LONG).show()
}
查詢記錄
在手機上獲取數據庫的內容,并且顯示出來。我們把數據顯示到TextView控件上。
也來用多種方式實現吧。
先是把title為“我的公司”的記錄找出來,但是只顯示title和author兩個字段。
再用第二種方法,直接寫SQL語句的,把所有記錄都查出來并顯示所有字段。
如果要顯示多條記錄,就需要用到循環,并且使用 moveToNext() 方法,直到 isAfterLast 為止。
//查詢記錄
btnSQLiteSearch.setOnClickListener {
val database = SQLiteDatabase.openOrCreateDatabase(fileName, null)
var queryResult = ""
//使用 query 方法查詢cofoxArticle數據表中的記錄
val cursorl = database.query("cofoxArticle", arrayOf("title", "author"), "title=?", arrayOf("我的公司"), "", "", "")
try {
cursorl.moveToFirst()
queryResult += cursorl.getString(0) + " -> " + cursorl.getString(1) + "\r\n"
} catch (e: Exception) {
}
val querySQL = "select * from cofoxArticle"
val cursor2 = database.rawQuery(querySQL, null)
try {
cursor2.moveToFirst()
while (!cursor2.isAfterLast){
queryResult += cursor2.getString(0) + " -> " +cursor2.getString(1) + " -> " +cursor2.getString(2) + " -> " +cursor2.getString(3) + " -> " +cursor2.getString(4) + " -> " +cursor2.getString(5) + "\r\n"
cursor2.moveToNext()
}
} catch (e: Exception) {
}
ttvwQueryResult.setText(queryResult)
database.close()
}
修改記錄
對數據庫中現有的記錄進行修改是很常用的操作。依然采用參數方式和SQL方式,用2種方法分別實現一次。
//修改記錄
btnSQLiteUpdate.setOnClickListener {
val database = SQLiteDatabase.openOrCreateDatabase(fileName, null)
//第一種方式
val contentValues = ContentValues()
contentValues.put("content", "專注為企業提供IT支撐服務的科技型公司。")
database.update("cofoxArticle", contentValues, "author=?", arrayOf("金龍翼"))
//第二種那個方式
val updateSQL = "update cofoxArticle set content='是內部最強大的質量保障' where author=?"
database.execSQL(updateSQL, arrayOf("Smith"))
database.close()
Toast.makeText(this, "修改完成", Toast.LENGTH_LONG).show()
}
以author為條件,對應修改content內容。
刪除記錄
根據條件可以刪除所有滿足條件的記錄。
這里采用了三種方式。用參數全匹配、SQL語句條件等于、SQL語句條件范圍
//刪除數據
btnSQLiteDelete.setOnClickListener {
val database = SQLiteDatabase.openOrCreateDatabase(fileName, null)
database.delete("cofoxArticle", "author=?", arrayOf("金龍翼"))
val deleteSQL = "delete from cofoxArticle where author=?"
database.execSQL(deleteSQL, arrayOf("Smith"))
//id大于2的都刪掉
val deleteSQLThan2 = "delete from cofoxArticle where id>?"
database.execSQL(deleteSQLThan2, arrayOf("2"))
database.close()
Toast.makeText(this, "刪除成功", Toast.LENGTH_LONG).show()
}
利用以上的內容,可以讓APP在初次運行的時候,根據數據庫是否存在判斷是否需要創建。并且也可以根據用戶的選擇,對數據庫進行初始化。如果有必要,還可以讓用戶主動的保存自己的數據。