什么是SQLite数据库
SQLite数据库是适合在移动设备上使用的轻量型关系型数据库,速度快,占用空间小.与SharedPreferences适合存储少量简单类型数据相反,SQLite数据库适合存储大量复杂类型的数据.
安卓原生提供了操作数据库的API接口,但是操作较为繁杂,于是涌现了大量第三方的开源操作库,如GreenDAO、Realm等.但Google最新推出Jetpack全家桶,自带Room数据库操作库,使用上方便快捷,同时可以和Jetpack中的其他库结合,高效完成开发.
基础样例
1. 采用安卓原生方式操作数据库
a. 效果图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XwhRNhnT-1598402428745)(https://upload-images.jianshu.io/upload_images/6169789-0121b82ea983be9e.gif?imageMogr2/auto-orient/strip)]
b. 使用方法
1). 添加数据库辅助操作类
/**
* 数据库辅助操作类
*/
class DbHelper
(context: Context?, databaseName: String, version: Int) : SQLiteOpenHelper(
context, databaseName, null, version
) {
//创建用户表的sql语句,表名:user_table,包含主键_id,用户名字段:user_name。
private var createUserTableSql =
("CREATE TABLE user_table(_id INTEGER PRIMARY KEY, user_name text)")
/**
* 创建数据库表
*/
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(createUserTableSql)
}
/**
* 数据库升级
*/
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
val sql = "DROP TABLE IF EXISTS user_table"
db.execSQL(sql)
onCreate(db)
}
/**
* 插入数据
*/
fun insert(tableName: String, cv: ContentValues) = writableDatabase.insert(tableName, null, cv)
/**
* 删除指定数据
*/
fun delete(tableName: String, id: Int): Int {
val where = "_id = ?"
val whereValue = arrayOf(id.toString())
return writableDatabase.delete(tableName, where, whereValue)
}
/**
* 删除所有数据
*/
fun deleteAll(tableName: String) = writableDatabase.delete(tableName, null, null)
/**
* 更新数据
*/
fun update(
tableName: String, values: ContentValues, whereClause: String?, whereArgs: Array<String>?
) = writableDatabase.update(tableName, values, whereClause, whereArgs)
/**
* 查询数据,返回一个指定数据集合的游标
*/
fun query(tableName: String): Cursor {
return readableDatabase.query(tableName, null, null, null, null, null, null)
}
}
2). Activity中进行调用
- Activity代码
class MainActivity : AppCompatActivity() {
private lateinit var dbHelper: DbHelper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
dbHelper = DbHelper(this, "user_database", 1)
addDataBtn.setOnClickListener { addUser() }
updateDataBtn.setOnClickListener { updateUser() }
delDataBtn.setOnClickListener { delUser() }
queryDataBtn.setOnClickListener { queryUser() }
}
/**
* 新增数据
*/
private fun addUser() {
val values = ContentValues().apply {
put("user_name", "张三")
}
dbHelper.insert("user_table", values)
}
/**
* 更新数据
*/
private fun updateUser() {
val values = ContentValues().apply {
put("user_name", "李四")
}
dbHelper.update("user_table", values, null, null)
}
/**
* 删除数据
*/
private fun delUser() {
dbHelper.deleteAll("user_table")
}
/**
* 查询数据
*/
private fun queryUser() {
val cursor = dbHelper.query("user_table")
if (cursor.moveToFirst()) {
do {
val id = cursor.getInt(cursor.getColumnIndex("_id"))
val name = cursor.getString(cursor.getColumnIndex("user_name"))
Log.d("MainActivity", "用户:${id}_$name")
} while (cursor.moveToNext())
} else {
Log.d("MainActivity", "数据库是空的!")
}
cursor.close()
}
}
- Activity对应布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="@+id/addDataBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="新增数据" />
<Button
android:id="@+id/updateDataBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="更新数据" />
<Button
android:id="@+id/delDataBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除数据" />
<Button
android:id="@+id/queryDataBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询数据" />
</LinearLayout>
2. 采用Room操作数据库
a. 效果图:
b. 使用方法
1). 在app模块的build.gradle文件中增加依赖:
//集成room进行SQLite数据库操作
implementation "androidx.room:room-runtime:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
//集成协程coroutines进行异步操作
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0"
2). 定义数据类:
/**
* 测试用的用户数据类,包含自动生成值的主键id字段,用户名字段。
*/
@Entity(tableName = "user_table")
class User(
@PrimaryKey(autoGenerate = true) var id: Long = 0,
@ColumnInfo(name = "user_name") var name: String = ""
)
3). 定义数据库表操作类
/**
* 用户数据库表操作类
*/
@Dao
public interface UserDao {
//新增数据
@Insert
long[] add(User... users);
@Update
void update(User... users);
//删除所有数据
@Query("DELETE FROM USER_TABLE")
void deleteAll();
//查询出所有数据
@Query("SELECT * FROM USER_TABLE")
List<User> query();
}
4). 创建数据库类
/**
* 数据库类,用于创建数据库及对所有数据库表进行操作。
* 所有的数据库表类都放在entities里,通过逗号分隔;
* version表示当前的数据库版本号,如果应用发布后,又对数据库结构做了修改,则需要变更版本号(一般加1即可)
*/
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
//所有数据库表操作类都放在这里
abstract val userDao: UserDao
companion object {
//自定义数据库文件名,只要在应用内不存在多个同名的数据库文件即可。
private const val DATABASE_NAME = "user_database"
@Volatile
private var instance: AppDatabase? = null
@Synchronized
fun getInstance(context: Context) =
instance
?: buildDatabase(context)
.also { instance = it }
private fun buildDatabase(context: Context) =
Room.databaseBuilder(context, AppDatabase::class.java,
DATABASE_NAME
).build()
}
}
5). Activity中进行调用
- Activity代码
class MainActivity : AppCompatActivity() {
//记录最后一次新增的用户id,用于标识待更新的用户
private var lastAddedUserId: Long = 0
private lateinit var userDao: UserDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
userDao = AppDatabase.getInstance(this).userDao
addDataBtn.setOnClickListener { addUser() }
updateDataBtn.setOnClickListener { updateUser() }
delDataBtn.setOnClickListener { delUser() }
queryDataBtn.setOnClickListener { queryUser() }
}
private fun addUser() {
GlobalScope.async {
var result = userDao.add(User(name = "张三"))
lastAddedUserId = result[0]
}
}
private fun updateUser() {
val user = User(id = lastAddedUserId, name = "李四")
GlobalScope.async {
userDao.update(user)
}
}
private fun delUser() {
GlobalScope.async {
userDao.deleteAll()
}
}
private fun queryUser() {
GlobalScope.async {
val dataList = userDao.query()
if (dataList.isNotEmpty()) {
dataList.forEach { Log.d("MainActivity", "用户:${it.id}_${it.name}") }
} else {
Log.d("MainActivity", "数据库是空的!")
}
}
}
}
- Activity对应布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="@+id/addDataBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="新增数据" />
<Button
android:id="@+id/updateDataBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="更新数据" />
<Button
android:id="@+id/delDataBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除数据" />
<Button
android:id="@+id/queryDataBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询数据" />
</LinearLayout>
完整源代码