Android开发Kotlin编程Kotlin

59. (android开发)SQLite数据库操作

2018-01-06  本文已影响85人  厚土火焱

SQLite数据库是一款轻型的数据库,在很多嵌入式产品中使用。它占用的资源非常低,只需要几百K内存就足够了。
对windows/linux/unix等多种操作系统提供支持。目前SQLite3是最新的版本。
android系统集成了SQLite数据库。
我们也可以使用一些工具对SQLite数据库进行可视化的操作。比如: SQLite Expert Personal 是一款免费的工具。

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

上一篇 下一篇

猜你喜欢

热点阅读