热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AndroidKotlin语言学习第三课:自定义ContentProvider和SQlite学习增删改查

AndroidKotlin语言学习第三课:自定义ContentProvider和SQlite学习增删改查-一:创建主界面增删改查***@authorzhiqiangRuan*@

一:创建主界面增删改查

/**
 * @author zhiqiangRuan
 * @ClassName
 * @Date  2022/7/4
 */
class FiveActivity : BaseActivity(), View.OnClickListener {
    lateinit var addData: Button
    lateinit var deleteData: Button
    lateinit var queryData: Button
    lateinit var updataData: Button
    var bookId: String? = null
    override fun initView() {
        addData = findViewById


二:Xml文件




    

三:自定义的MyProvider

package com.cnstrong.leke.helloworld

import android.content.ContentProvider
import android.content.ContentValues
import android.content.UriMatcher
import android.net.Uri
import java.lang.RuntimeException

/**
 * @author zhiqiangRuan
 * @ClassName 自定义ContentProvider
 * @Date  2022/7/4
 */
class MyProvider : ContentProvider() {

    private val bookDir = 0
    private val bookItem = 1

    private val categoryDir = 2
    private val categoryItem = 3

    /**
     * 每一个ContentProvider定义唯一标识URI  URI*/
    private var dbHelper: MySqliteDataHelper? = null

    private val authority = "com.cnstrong.leke.helloworld.provider"

    /**UriMatcher本质上是一个文本过滤器,用在contentProvider中帮助我们过滤,分辨出查询者想要查询哪个数据表。*/
    private val uriMatcher by lazy {
        //常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
        val mathcher = UriMatcher(UriMatcher.NO_MATCH)
        //如果match()方法匹配content://com.cnstrong.leke.helloworld.provider/book路径,返回匹配码为1
        mathcher.addURI(authority, "book", bookDir)
        //如果match()方法匹配content://com.cnstrong.leke.helloworld.provider/book/通配符 路径,返回匹配码为2
        mathcher.addURI(authority, "book/#", bookItem)

        mathcher.addURI(authority, "category", categoryDir)
        mathcher.addURI(authority, "category/#", categoryItem)
        mathcher
    }

    /**创建数据*/
    /**
     * override fun onCreate(): Boolean {
    dbHelper = context?.let {
    MySqliteDataHelper(it, "BookStore.db", 1)
    return true
    }
    return false

    ------------------------------
    这里用到了Kotlin let操作符
    obj.let{} 或obj?.let{}
    第一种写法,如果确定obj不为null,可以使用,
    第二种写法相当于java的非空判断,当obj不为空时,才执行大括号内的代码段,相对java的空判断来说简洁一些,值得使用。
    //在函数体内使用it替代object对象去访问其公有的属性和方法
    } */
    override fun onCreate() = context?.let {
       // MySqliteDataHelper(it, "BookStore.db", 1)
//要记住这个问题,自己写代码太不严谨了
 dbHelper=MySqliteDataHelper(it, "BookStore.db", 1)
        true
    } ?: false


    /**查询数据*/

    override fun query(
        uri: Uri,
        projection: Array?,
        selection: String?,
        selectionArgs: Array?,
        sortOrder: String?
    ) = dbHelper?.let {
        //查询数据
        val db = it.writableDatabase
        val cursor = when (uriMatcher.match(uri)) {
            bookDir -> db.query("Book", projection, selection, selectionArgs, null, null, sortOrder)
            bookItem -> {
                val bookId = uri.pathSegments[1]
                db.query("Book", projection, "id=?", arrayOf(bookId), null, null, sortOrder)
            }
            categoryDir -> db.query(
                "Category",
                projection,
                selection,
                selectionArgs,
                null,
                null,
                sortOrder
            )
            categoryItem -> {
                val categoryId = uri.pathSegments[1]
                db.query("Category", projection, "id=?", arrayOf(categoryId), null, null, sortOrder)
            }
            else->null
        }
        cursor

    }

    /**
     * 得到数据类型*/

    override fun getType(uri: Uri) = when (uriMatcher.match(uri)) {
        bookDir -> "vnd.android.cursor.dir/vnd.com.cnstrong.leke.helloworld.provider.book"
        bookItem -> "vnd.android.cursor.item/vnd.com.cnstrong.leke.helloworld.provider.book"
        categoryDir -> "vnd.android.cursor.dir/vnd.com.cnstrong.leke.helloworld.provider.category"
        categoryItem -> "vnd.android.cursor.item/vnd.com.cnstrong.leke.helloworld.provider.category"
        else -> null
    }

    /**插入数据
     *
     *  override fun insert(uri: Uri, values: ContentValues?): Uri? {
    //获取到SQLiteDatabase 对象
    val db = dbHelper?.writableDatabase
    val uriReturn = when (uriMatcher.match(uri)) {
    bookDir, bookItem -> {
    val newBookId = db?.insert("Book", null, values)
    Uri.parse("content://$authority/book/$newBookId")
    }
    categoryDir, categoryItem -> {
    val newCategoryId = db?.insert("Category", null, values)
    Uri.parse("content://$authority/category/$newCategoryId")
    }
    else -> null
    }
    return uriReturn


    }*/

    override fun insert(uri: Uri, values: ContentValues?) = dbHelper?.let {
        //获取到SQLiteDatabase 对象
        val db = it.writableDatabase
        val uriReturn = when (uriMatcher.match(uri)) {
            bookDir, bookItem -> {
                val newBookId = db.insert("Book", null, values)
                Uri.parse("content://$authority/book/$newBookId")
            }
            categoryDir, categoryItem -> {
                val newCategoryId = db.insert("Category", null, values)
                Uri.parse("content://$authority/category/$newCategoryId")
            }
            else ->null
        }
        uriReturn


    }

    /**删除数据*/

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array?) =
        dbHelper?.let {
            //删除数据
            val db = it.writableDatabase
            val deleteRows = when (uriMatcher.match(uri)) {
                bookDir -> db.delete("Book", selection, selectionArgs)
                bookItem -> {
                    //筛选条件参数
                    val bookId = uri.pathSegments[1]
                    db.delete("Book", "id=?", arrayOf(bookId))
                }
                categoryDir -> db.delete("Category", selection, selectionArgs)
                categoryItem -> {
                    val categoryId = uri.pathSegments[1]
                    db.delete("Category", "id=?", arrayOf(categoryId))
                }
                else -> 0
            }
            deleteRows

        } ?: 0

    /**更新数据*/

    override fun update(
        uri: Uri,
        values: ContentValues?,
        selection: String?,
        selectionArgs: Array?
    ) = dbHelper?.let {
        val db = it.writableDatabase
        val updateRows = when (uriMatcher.match(uri)) {
            bookDir -> db.update("Book", values, selection, selectionArgs)
            bookItem -> {
                val bookId = uri.pathSegments[1]
                db.update("Book", values, "id=?", arrayOf(bookId))
            }
            categoryDir -> db.update("Category", values, selection, selectionArgs)
            categoryItem -> {
                val categoryId = uri.pathSegments[1]
                db.update("Category", values, "id=?", arrayOf(categoryId))
            }
            else -> 0
        }
        updateRows

    } ?: 0
}

四:MySqliteDataHelper 数据库创建的帮助类

package com.cnstrong.leke.helloworld

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.widget.Toast

/**
 * @author zhiqiangRuan
 * @ClassName
 * kotlin 构造函数 参数
 * val context: Context 上下文
 * name: String  数据库名,库名 xxx.db
 * version: Int 版本号,用来数据库升级的
 * @Date  2022/7/4
 */
class MySqliteDataHelper(val context: Context, name: String, version: Int) :
    SQLiteOpenHelper(context, name, null, version) {

    private val book = "create table Book( " +
            "id integer primary key autoincrement," +
            "author text," +
            "price real," +
            "pages integer," +
            "name text)"


    private val category = "create table Category( " +
            "id integer primary key autoincrement," +
            "category_name text," +
            "category_code integer)"


    /**使用SQliteDatabase创建数据表
     *
     * 1.这个方法,第一次打开数据库时候才会走
     * 2.在清除数据之后再一次运行-->打开数据库,这个方法会走
     * 3.没有清除数据,不会走这个方法
     * 4.数据库升级的时候这个方法不会走
     * */
    override fun onCreate(db: SQLiteDatabase?) {
        db?.execSQL(book)
        db?.execSQL(category)
        Toast.makeText(context, "create books success", Toast.LENGTH_SHORT).show()

    }


    /**
     * 1.第一次创建数据库的时候,这个方法不会走
     *
     *2.清除数据再次运行(相当于第一次创建)这个方法不会走
     *
     * 3.数据库已经存在,而且版本升高的时候,这个方法才会调用*/
    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        //根据版本号判断
        if (oldVersion <= 1) {
            db?.execSQL("alter table Book add column category_id")
        }
    }


    /**这个方法是数据库降级操作
     *
     * 1.新版本比旧版本低时候才会执行
     *
     * 2.如果不执行降级操作会抛出异常*/

    override fun onDowngrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        super.onDowngrade(db, oldVersion, newVersion)
    }
}

五:MyProvider的AndroidManifest配置




    
    
    
    

    
        
            
                

                
            
        
        
        

        

        
    

六:遇到的问题

不知道什么原因,有大神知道吗,需要指导一下


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • MySQL外键1对多问题的解决方法及实例
    本文介绍了解决MySQL外键1对多问题的方法,通过准备数据、创建表和设置外键关联等步骤,实现了用户分组和插入数据的功能。详细介绍了数据准备的过程和外键关联的设置,以及插入数据的示例。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • MySQL插入数据的四种方式及安全性分析
    本文介绍了MySQL插入数据的四种方式:插入完整的行、插入行的一部分、插入多行和插入查询结果,并对其安全性进行了分析。在插入行时,应注意字段的定义和赋值,以提高安全性。同时指出了使用insert语句的不安全性,应尽量避免使用。建议在表中定义相关字段,并根据定义的字段赋予相应的值,以增加插入操作的安全性。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
author-avatar
手机用户2502939965
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有