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>
界面
首先在 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 在初次运行的时候,根据数据库是否存在判断是否需要创建。并且也可以根据用户的选择,对数据库进行初始化。如果有必要,还可以让用户主动的保存自己的数据。
来源: http://www.jianshu.com/p/b87c85c9d9f5