59. (android开发)SQLite数据库操作
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在初次运行的时候,根据数据库是否存在判断是否需要创建。并且也可以根据用户的选择,对数据库进行初始化。如果有必要,还可以让用户主动的保存自己的数据。