美文网首页
Anko-SQLite的使用

Anko-SQLite的使用

作者: 番茄tomato | 来源:发表于2020-07-07 16:14 被阅读0次

    Anko是Kotlin库,可以使Android应用程序的开发变得更快,更轻松。它使您的代码干净且易于阅读,并且使您无需理会Android SDK for Java的粗糙之处。

    Anko提供了许多扩展功能
    github地址:https://github.com/Kotlin/anko
    根据github上的内容引入到项目,这里贴出来的话以后肯定不是Anko最新版本了。

    Anko的功能非常丰富,本文主要使用其为了简化SQLite的使用提供的数据库管理的功能Anko-SQLite
    以下为使用方法,主要参考:https://github.com/Kotlin/anko/wiki/Anko-SQLite

    一 为你的项目创建数据库管理工具类

    class MyDatabaseOpenHelper private constructor(ctx: Context) :
        ManagedSQLiteOpenHelper(ctx, "MyDatabase", null, 1) {
        //初始化
        init {
            instance = this
        }
    
        //单例模式
        companion object {
            private var instance: MyDatabaseOpenHelper? = null
    
            @Synchronized
            fun getInstance(ctx: Context) = instance ?: MyDatabaseOpenHelper(ctx.applicationContext)
        }
    
        //创建数据库时 做一些事情 比如创建一些默认的表
        override fun onCreate(db: SQLiteDatabase) {
    
    
        }
    
        //数据库版本更新 版本发生改变时做一些事情 比如删除所有表
        override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
            // Here you can upgrade tables, as usual
            db.dropTable("User", true)
        }
    
        // Access property for Context
        val Context.database: MyDatabaseOpenHelper
            get() = MyDatabaseOpenHelper.getInstance(this)
    }
    

    代码讲解:

    1. MyDatabaseOpenHelper就是此项目的数据库管理工具类,它有一个构造参数Context,它继承于框架提供的ManagedSQLiteOpenHelperManagedSQLiteOpenHelper有四个构造参数分别是:context,数据库名称,数据库工厂(默认null就行),数据库版本号

    2.在 companion object中创建静态方法,使用单例模式调用此类

    3.在onCreate中,就是创建数据库了,文档中在这里创建了一个默认表,但是我是为了每个表单独创建了一个操作类,所以就没有在这里建表。各人有不同的封装思路,如果表很少的话,可以将数据库相关代码全部写在MyDatabaseOpenHelper

    4.其他代码暂时不管

    二 为你的每张表创建操作类

    比如我这里有一个扫码记录表
    包括三个字段:id | 扫描字符串 | 扫码时间戳
    我创建了一个类ScanRecordsDbProvider如下:

    //主要负责扫描历史记录的增删查
    class ScanRecordsDbProvider {
        //数据库操作
        private val database = MyDatabaseOpenHelper.getInstance(App.context)
    
        //初始化 调用createTable建表
        init {
            createTable()
        }
    
        //单例模式
        companion object {
            val instance: ScanRecordsDbProvider by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { ScanRecordsDbProvider() }
            //表名
            private const val TABLE_NAME = "ScanRecords"
            //表字段名(id省略了)
            private const val COLUMN_CONTENT = "content"
            private const val COLUMN_TIMESTAMP = "timestamp"
        }
    
    
        //建表
        private fun createTable() {
            database.use {
                //检查表是否存在 不存在则创建表
                createTable(
                    TABLE_NAME, true,
                    "id" to INTEGER + PRIMARY_KEY + UNIQUE,//主键 int型 唯一 递增
                    COLUMN_CONTENT to TEXT,
                    COLUMN_TIMESTAMP to TEXT
                )
            }
        }
    
    
        //增加数据
        fun insertData(data: ScanRecordEntity) {
            database.use {
                insert(TABLE_NAME, COLUMN_CONTENT to data.content, COLUMN_TIMESTAMP to data.timestamp)
            }
        }
    
    
        //查询所有数据
        fun queryAll(): ArrayList<ScanRecordEntity> {
            val list = ArrayList<ScanRecordEntity>()
            database.use {
                select(TABLE_NAME).exec {
                    while (moveToNext()) {
                        val content = getString(getColumnIndex(COLUMN_CONTENT))
                        val timestamp = getString(getColumnIndex(COLUMN_TIMESTAMP))
                        list.add(ScanRecordEntity(content, timestamp))
                    }
    
                }
    
            }
            //倒序
            list.reverse()
            return list
        }
    
        //清除所有数据
        fun clearAll() {
            database.use {
                delete(TABLE_NAME)
            }
        }
    
        //添加数据(多条)
        fun insertData(data: List<ScanRecordEntity>) {
    
        }
    
    
        //删除表
        fun dropTable() {
    
        }
    
    
    }
    

    代码解析:

    1. 成员变量database直接调用 MyDatabaseOpenHelper.getInstance(App.context)获得,这里App.context也就是application的context

    2. 还是单例模式,在初始化init自动建表。companion object 中完成单例模式并且给出表名和字段名(id省略了)

    3.在createTable()函数中创建表,使用database.use{ }直接调用createTable方法,建表时确定每个字段的类型,比如id是INTEGER,并且是主键,不重复(自动递增),扫码内容字符串是TEXT也就是String。时间戳本来是long但是框架没有提供,就使用TEXT 。其实在实际使用过程中前端的数据库都是比较简单的,框架为我们提供了五个表字段基本类型:NULL, INTEGER, REAL, TEXT ,BLOB
    但其实只用到INTEGER和TEXT就可以应付99%的情况了。

    4.insertData(data: ScanRecordEntity)添加单个数据,代码很简单

    5.queryAll()查询所有数据,注意数据查询出来后,要把每一行每一列的字段拿出来存到内存。

    三 调用表的操作类,进行数据库操作

    例如我这里在activity中添加数据和查询所有数据:

        private val scanRecordsProvider = ScanRecordsDbProvider.instance
    //添加数据
     scanRecordsProvider.insertData(ScanRecordEntity(result, timeUnit.getTimestampStr()))
    //查询数据
    mData.addAll(scanRecordsProvider.queryAll())
    

    不同的表根据不同的业务,有不同的操作方法,所以具体需要表的哪些操作,自己在表操作类中自定义

    到这里只是最简单的使用,比如更复杂的查询,多表联合查询这些,看文档慢慢扩展吧。
    最后还在再说一句,建议每张表对应一个操作类,或者多张业务需求的表对应一个操作类。这样以后数据库表比较多后,每个表的操作方法都封装好了,代码非常清楚。当然,如果是非常简单的就一张表,就写到数据库helper类中都可以,这样的封装方式是有一些多余了

    相关文章

      网友评论

          本文标题:Anko-SQLite的使用

          本文链接:https://www.haomeiwen.com/subject/ucgaqktx.html