上次说到持久化技术有三种——文件存储、SharePreference、数据库存储,今天就来学习数据库存储
实际上Android内置了SQLite数据库,是一款轻量级的关系型数据库,运行速度非常快。
可以借助SQLiteOpenHelper,但是它是一个抽象类,需要自己写一个类继承。
class MyDatabaseHelper(val context: Context,name:String,version:Int):SQLiteOpenHelper(context,name,null,version) {
private val createCategory = "create table Category ("+
"id integer primary key autoincrement,"+
"category_name text,"+
"category_code integer)"
override fun onCreate(db: SQLiteDatabase?) {
db?.execSQL(createBook)
Toast.makeText(context,"Create succeeded",Toast.LENGTH_SHORT).show()
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
}
}
SQLiteOpenHelper接收四个参数,第一个是Context类,第二个数据库名,第三个一般传入null,其作用是允许我们在查询数据时返回一个自定义的Cursor。
需要重写两个函数,一个是onCreate,第二个是onUpgrade,如其名字一样实现其功能。
在创建数据库时,需要有建表语句。
create table Book(
id integer primary key autoincrement,
author text,
price real,
pages integer,
name text)
}
将建表语句定义成一个字符串常量,然后在onCreate中调用db的execSQL方法去执行这条语句。
这样就创建成功!
在MainActivity还需要修改以下代码
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val dbHelper = MyDatabaseHelper(this,"BookStore.db",1)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.createDatabase.setOnClickListener {
dbHelper.writableDatabase
}
}
}
主要功能是提供一个按钮去实现手动创建数据库,即调用dbHelper的writableDatabase()方法。
MyDatabaseHelper中还有一个重写方法onUpgrade就是用来升级数据库的。
如果我们要向数据库中添加一张Category表用于记录图书分类
建表语句如下:
create table Category(
id integer primary key autoincrement,
category_name text,
category_code integer)
将其添加到MyDatabaseHelper
class MyDatabaseHelper(val context: Context,name:String,version:Int):SQLiteOpenHelper(context,name,null,version) {
private val createCategory = "create table Category ("+
"id integer primary key autoincrement,"+
"category_name text,"+
"category_code integer)"
private val createBook = "create table Book("+
" id integer primary key autoincrement,"+
"author text,"+
"price real,"+
"pages integer,"+
"name text)"
override fun onCreate(db: SQLiteDatabase?) {
db?.execSQL(createBook)
db?.execSQL(creatCategory)
Toast.makeText(context,"Create succeeded",Toast.LENGTH_SHORT).show()
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
db?.execSQL("drop table if exists Book")
db?.execSQL("drop table if exists Category")
onCreate(db)
}
}
当存在Book表或者Category时,就删除这两张表,然后再创建,就可以调用onCreate。
调用onUpgrade的方法同样很简单,只需要将之前的版本号改写成2即可。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val dbHelper = MyDatabaseHelper(this,"BookStore.db",2)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.createDatabase.setOnClickListener {
dbHelper.writableDatabase
}
}
}
DatabaseHelper提供了insert方法来方便插入数据。
insert有三个参数。第一个是插入的表名,第二个用于在未指定数据的情况下给某些可为空的列自动赋值null,一般填null。第三个是一个ContentValues类型的对象,提供了put用于插入数据。
binding.addData.setOnClickListener {
val db = dbHelper.writableDatabase
val values1 = ContentValues().apply {
put("name","The Da Vinci Code")
put("author", "Dan Brown")
put("pages",454)
put("price",16.96)
}
db.insert("Book",null,values1)
val values2 = ContentValues().apply {
put("name","The lost Symbol")
put("author","Dan Brown")
put("pages",510)
put("price",19.95)
}
db.insert("Book",null,values2)
}
update()接收四个参数,第一个参数和insert方法一样,第二个参数是ContentValues对象,第三四个参数则是制定修改的范围。
binding.updateData.setOnClickListener {
val db = dbHelper.writableDatabase
val values = ContentValues();
values.put("price",10.99)
db.update("Book",values,"name = ?", arrayOf("The Da Vinci Code"))
}
第三个参数“name = ?”是name = ?的行,?是一个占位符,是什么内容呢?后面给出答案,name = “The DaVinci Code”。
delete()参数接收三个参数,第一个仍然是表名,第二个三个则是指定某一行或者几行,默认就会删除所有。
binding.deleteData.setOnClickListener {
val db = dbHelper.writableDatabase
db.delete("Book","pages > ?", arrayOf("500"))
}
query()提供查询数据的功能,一共有七个参数。
第一个参数就是表名,后面六个是用来指定数据的,需要了解的话去看文档。
binding.queryData.setOnClickListener {
val db = dbHelper.writableDatabase
val cursor = db.query("Book",null,null,null,null,null,null) //查询全部
if (cursor.moveToFirst())
{
do {
val name = cursor.getString(cursor.getColumnIndex("name"))
val author = cursor.getString(cursor.getColumnIndex("author"))
val pages = cursor.getString(cursor.getColumnIndex("pages"))
val price = cursor.getString(cursor.getColumnIndex("price"))
Log.d("MainActivity","book name is $name")
Log.d("MainActivity","book author is $author")
Log.d("MainActivity","book pages is $pages")
Log.d("MainActivity","book price is $price")
}while (cursor.moveToNext())
}
cursor.close()
}
看起来很多,实际上逻辑很简单,首先定义Cursor查询全部数据。
调用它的moveFirst,也就是指针移动到第一行,开始循环,打印出来即可。
最后别忘了用close关闭Cursor