Android使用SQLite Kotlin

2,315 阅读4分钟

关于Android原生数据库的使用

学习日记

SQLite数据库在android.database.sqlite软件包提供了使用所需的API,对于大量的重复结构化数据(例如:联系人,信息...),使用内置轻量数据库保存是绝佳的选择。

但是缺点也是很明显的,建议使用第三方数据库框架(Room,GreenDao,LitePal,Afinal...),增加效率,减少出错。本文章仅记录SQLite基础学习记录,个人理解。

新建一个空的Android空项目

编写初始界面,四个对应(增,删,查,改)的按钮,底部空白区域为RecycleView

XMK.png

创建用于储存联系人的数据实体类contact

data class contact(val id:Int,val name:String,val numder:String)

使用SQLiteOpenHelper类创建数据库

从实体类中我们可以看到id(唯一标识),name(联系人姓名),numder(联系人手机号),所以我们要根据以上字段创建数据库

创建数据库表的SQL语句

val sqlCreate = "create table contact(id integer primary key,name text,numder text)"

为了保证语句的正确性可以在MySQL中创建一次来保证

mysqltable.png

创建数据库以及表

class DBHelper(context: Context) : SQLiteOpenHelper(context,"contact",null,1) {
    
    val sqlCreate = "create table contact(id integer primary key,name text,numder text)"
    override fun onCreate(p0: SQLiteDatabase?) {
        //创建表格,传入建表sql语句
        p0?.execSQL(sqlCreate)
    }

    override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
        //进行数据库的更新
    }

}

SQLiteOpenHelper中的4个参数分别是,传入上下文,数据库名称,CursorFactory类型,数据库版本号

进行数据库的增删查改

使用viewBinding获取控件id

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.btnAdd.setOnClickListener { 
    
        }
    }
}

需要在build.gradle(Module) android标签中加入
buildFeatures{
    viewBinding = true
}

创建实例

var dbHelper: DBHelper? = null

实例化对象
    dbHelper = DBHelper(this)
    var db = openDB()
    
选择模式(写入和读取)
fun openDB(): SQLiteDatabase? {
    //获取SQLiteDatabase对象
    var db: SQLiteDatabase? = null
    try {
      db = dbHelper?.writableDatabase
    } catch (e: Exception) {
       db = dbHelper?.readableDatabase
    }
    return db
}

增加一条数据

binding.btnAdd.setOnClickListener {
    //增加一条数据
    val content = ContentValues().apply {
        put("name","小明")
        put("numder","13888888888")
    }
    db?.insert("contact",null,content)
}

读取数据

binding.btnQurey.setOnClickListener {
    dbData()
}

fun dbData(){
    //更新全部数据
    //需要先清理原来列表的数据
    contactList?.clear()
    var cursor = db?.query("contact",null,null,null,null,null,null)
    //cursor可以解释为指针,将指针移动到第一位,有就true,否则就false
    if(cursor!!.moveToFirst()){
        do{
            contactList?.add(contact(cursor.getInt(0),cursor.getString(1),cursor.getString(2)))
            //将指针移动至下一条数据
        }while (cursor.moveToNext())
    }
    //adapter是RecyleView的适配器
    adapter!!.notifyDataSetChanged()
}

删除一条数据

binding.btnRemove.setOnClickListener {
    //删除数据,ID查找删除
    db?.delete("contact","id=?", listOf("1").toTypedArray())
    //删除之后需要重新拿取数据
    dbData()
}

修改数据

binding.btnUpdata.setOnClickListener {
    //更新数据,ID查找更新
    //把需要更新的数据封装好
    val content = ContentValues().apply {
        put("name","小王")
        put("numder","10086")
    }
    //根据id查询,传入对应ID可以对数据进行修改
    db?.update("contact",content,"id=?",listOf("1").toTypedArray())
    dbData()
}

以上就是数据库增删查改的基本操作,一般来说,报错的大部分原因是因为,数据库字段、数据库名称、表名,实体类,代码中相应的变量名没有一一对应

RecycView在viewBinding中基本的使用方式

RecycleView Adapter

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.sqlitedemo.databinding.RvLayoutBinding

class RVAdapter(list: MutableList<contact>) : RecyclerView.Adapter<RVAdapter.V>(){
    var list : MutableList<contact> = list
    class V(itemView: RvLayoutBinding) : RecyclerView.ViewHolder(itemView.root){
        var mView = itemView
    }
    //RvLayoutBinding是对应RecycleView的布局
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): V {
        return V(RvLayoutBinding.inflate(LayoutInflater.from(parent.context),parent,false))
    }

    override fun onBindViewHolder(holder: V, position: Int) {
        var contact = list.get(position)
        holder.mView.tvId.setText(" ${contact.id}")
        holder.mView.tvName.setText(contact.name)
        holder.mView.tvNumder.setText(contact.numder)
    }

    override fun getItemCount(): Int {
        return list.size
    }
}

在MainActivity中使用

var dbHelper: DBHelper? = null
var adapter : RVAdapter? = null
var db:SQLiteDatabase? = null
var contactList: MutableList<contact>? = null

onCreate方法中
contactList = mutableListOf(contact(0,"联系人姓名","联系人号码"))
adapter = RVAdapter(contactList!!)
binding.rv.adapter = adapter
binding.rv.layoutManager = LinearLayoutManager(this)

创建数据库工具类,统一处理增删查改

DBUtil工具类

import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase

object DBUtil {
    var dbHelper: DBHelper? = null
    var db:SQLiteDatabase? = null
    fun openDB(context: Context) {
        //获取SQLiteDatabase对象
        dbHelper = DBHelper(context)
        var db: SQLiteDatabase?
        try {
            db = dbHelper?.writableDatabase
        } catch (e: Exception) {
            db = dbHelper?.readableDatabase
        }
        this.db = db
    }

    fun closeDB(){
        //关闭输出输入
        if (db!!.isOpen){
            db?.close()
        }
    }

    fun qurey(context: Context) : MutableList<contact>? {
        //更新全部数据
        openDB(context)
        var contactList: MutableList<contact>? = mutableListOf()
        var cursor = db?.query("contact",null,null,null,null,null,null)
        //cursor可以解释为指针,将指针移动到第一位,有就true,否则就false
        if(cursor!!.moveToFirst()){
            do{
                contactList?.add(contact(cursor.getInt(0),cursor.getString(1),cursor.getString(2)))
                //将指针移动至下一条数据
            }while (cursor.moveToNext())
        }
        return contactList
    }

    fun remove(id: Int?,context: Context){
        openDB(context)
        db?.delete("contact","id=?", listOf(id.toString()).toTypedArray())
    }

    fun updata(id:Int?,content:ContentValues,context: Context){
        //更新数据,ID查找更新
        openDB(context)
        db?.update("contact",content,"id=?",listOf(id.toString()).toTypedArray())
    }

    fun add(content:ContentValues,context: Context){
        //增加一条数据
        openDB(context)
        db?.insert("contact",null,content)
    }
}

MainActivity中使用

import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.sqlitedemo.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    var adapter : RVAdapter? = null
    var contactList: MutableList<contact>? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        DBUtil.openDB(this)
        contactList = mutableListOf(contact(0,"联系人姓名","联系人号码"))
        adapter = RVAdapter(contactList!!)
        binding.rv.adapter = adapter
        binding.rv.layoutManager = LinearLayoutManager(this)
        binding.btnAdd.setOnClickListener {
            //增加一条数据
            val content = ContentValues().apply {
                put("name","小明")
                put("numder","13888888888")
            }
            DBUtil.add(content,this)
            updataAdapter()
        }
        binding.btnQurey.setOnClickListener {
            updataAdapter()
        }
        binding.btnRemove.setOnClickListener {
            //删除数据,ID查找删除
            DBUtil.remove(1,this)
            //删除之后需要重新拿取数据
            updataAdapter()
        }
        binding.btnUpdata.setOnClickListener {
            //更新数据,ID查找更新
            val content = ContentValues().apply {
                put("name","小王")
                put("numder","10086")
            }
            DBUtil.updata(1,content,this)
            updataAdapter()
        }
    }
    fun updataAdapter(){
        contactList?.clear()
        contactList!!.addAll(DBUtil.qurey(this)!!)
        adapter!!.notifyDataSetChanged()
    }
}

SQLite的学习也到此结束了,项目中的使用就需要触类旁通