创建数据库
需要 创建数据库 类 “MyHelper”
class MyHelper(
private val mContext: Context? = null,
private val dbname: String = "mydb",
private val version: Int = 1
) : SQLiteOpenHelper(mContext, dbname, null, version) {
/*
* 需要变量sql确定表的格式
* 需要 execSQL()执行创建表的动作
* */
override fun onCreate(p0: SQLiteDatabase?) {
// 创建数据库表
val sql: String =
"CREATE TABLE PRODUCTS (_id INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, DESCRIPTION TEXT, PRICE READ)"
// 执行创建表的动作
p0?.execSQL(sql)
}
/*
*
* */
override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
TODO("Not yet implemented")
}
}
- 创建数据库需要继承SQLiteOpenHelper()类型,需要四个参数进行初始化
- (四个参数:mContext:上下文,dbname: 数据库名称,version:数据库版本,factory:null)
- 需要实现两个方法onCreate()和onUpgrade()方法
在需要创建数据库时调用
var myHelper: MyHelper = MyHelper(mContext = this)
val sqlLiteDatabase: SQLiteDatabase = myHelper.readableDatabase
这时数据库就创建完成了
插入数据
创建仓库后插入数据
需要”ContentValues()”类型
需要”SQLiteDatabase的insert()”方法
在”自定义数据库中”中添加方法
private fun instertData(
name: String,
description: String,
price: Double,
database: SQLiteDatabase
) {
// ContentValues() 类型负责存放键值的数据.你只需要记住它是往数据库中存放数据的.
val values: ContentValues = ContentValues()
values.put("NAME", name)
values.put("DESCRIPTION", description)
values.put("PRICE", price)
// 向当前数据库(database)插入数据(values)
database.insert("PRODUCTS", null, values)
}
在外部要插入数据设置类型为 “public”即可。
插入数据在外部调用方法
// insert
instertData("Jam", "Fruit Jam", 300.1, p0!!)
instertData("Yli", "Te Jam", 305.13, p0!!)
instertData("Tom Li", "Zhou Jam", 210.7, p0!!)
读取数据
需要”MyHelper”自定义数据库类的实例
需要”MyHelper.readableDatabase”方法读取数据库方法返回一个可对数据库读写的对象.
需要”sqlLiteDatabase.rawQuery()”方法获得(数据库表)每行的集合(Cursor类型).
// 实例话自定义的数据类
var myHelper: MyHelper = MyHelper(mContext = this)
// 创建数据库
val sqlLiteDatabase: SQLiteDatabase = myHelper.readableDatabase
val cursor: Cursor =
sqlLiteDatabase.rawQuery("SELECT NAME, PRICE FROM PRODUCTS", arrayOf<String>())
if (cursor != null)
cursor.moveToFirst()
val builder: StringBuilder = StringBuilder()
do {
val name: String = cursor.getString(0)
val price: Double = cursor.getDouble(1)
builder.append("NAME - " + name + "PRICE - " + price)
} while (cursor.moveToNext())
// 这是在界面上刷新了读取的数据
text_view.setText(builder.toString())
按照条件查询指定数据
val cursor: Cursor =
sqlLiteDatabase.rawQuery("SELECT NAME, PRICE FROM PRODUCTS WHERE NAME = ?", arrayOf<String>("Tom Li"))
查询 列 “NAME,PRICE” 来自表 “PRODUCTS” 根据条件 “NAME = ?”
查询完成
什么是Cursor类型
引用:Android中的Cursor到底是什么?如何理解Cursor的方法都在做什么事情?
Cursor是每行的集合
表中共有多行数据.
假如:获得通过”select”语句”gender”获得符合这列的男性那么得到的是 “张三,赵六”这两行数据.也就是说 “Cursor”类型存放了两行数据。
如何获得Cursor类型
通过数据库对象的方法获得。👇
SQLiteDataBase db;
Cursor cursor = db.query(各种参数);
这些就是每一行的集合
索引在Cursor中是什么
在Cursor中索引指的就是表中的列
返回了”PRICE”列在表中的索引(位置)。
关于为何要使用 “moveToFirst()” 方法
利用反证法,不使用”moveToFirst()”方法,获得游标后,直接输出当前的”position”值
“position”的值会直接输出 “-1”,也就是说当我们不适用”moveToFirst()”方法时它会在坐标”position”(0)的上边。
所以我们应该使用方法”moveToFirst()”使”position”为”0”。
源码分析 使用”moveToNext()”方法是如何得知遍历完成的?
先说明 调用”moveToNext()”方法最总会调用”moveToPosition()”方法
👆界面在被初始化时,指当前页面的对象。这时源码中的”mPos=-1”会被在一个空参数构造方法里初始化。
仅理解的话: “moveToFirst()”调用的是”moveToPostion(0)”,”moveToNext()” 调用的是”moveToNext(mPos+1)”,所以说当首次调用的他们两个的结果是一样的。
ps:个人理解:在使用”cursor.moveToFirst()”先进行判断可以更有效的避免空指针异常j
更新数据
需要修改数据库返回的类型为可写入类型
// 创建数据库
val sqlLiteDatabase: SQLiteDatabase = myHelper.writableDatabase
需要 “ContentValues()” 类型存放更新的值
//更新数据
val values: ContentValues = ContentValues()
values.put("PRICE", 280)
// 参数1:表示更新的表.参数2:表示更新的数据.参数3:表示条件(表示通过那个条件更新值) 参数4:条件的值
sqlLiteDatabase.update("PRODUCTS", values, "_id = ?", arrayOf<String>("1"))
“280”价格更新了
多条件更新
更新表 “PRODUCTS“ 的值 “values“,根据 “NAME“为”Tom Li“ 和”DESCRIPTION“ 为 “Zhou Jam“ 的行中的数据.
sqlLiteDatabase.update("PRODUCTS", values, "NAME = ? AND DESCRIPTION = ?", arrayOf<String>("Tom Li","Zhou Jam"))
删除数据
在获得数据库的可写入类型后。 调用 “delete()”方法。
// 根据条件删除一行数据
// 参数1:要删除的表名字,参数2:选择删除的条件(根据这个条件删除),参数3:条件的值
sqlLiteDatabase.delete("PRODUCTS", "_id=?", arrayOf<String>("1"))
删除成功了.