Android中使用kotlin进行xutils数据库版本升级
前言
最近的项目是一个很老的项目,数据库采用的是xutils中的数据库,之前的业务没有关于版本变更和数据库修改的业务,这次新需求数据库需要新加一张表,之前的表也需要修改字段,涉及到数据库版本的升级,升级无非是根据数据库版本进行数据库表的变更添加新字段,不扯没用的,直接上代码。
1.添加依赖:
implementation 'org.xutils:xutils:3.8.12'
2.xutils初始化:
open class MyApp : Application() {
private lateinit var dbManager: DbManager
override fun onCreate() {
super.onCreate()
instance = this
initXUtils()
}
private fun initXUtils() {
x.Ext.init(this)//xutils初始化
x.Ext.setDebug(true)//是否开启日志
}
companion object {
lateinit var instance: MyApp
}
}
3.数据库管理类:
package com.example.xutilsdemo.db
import com.blankj.utilcode.util.LogUtils
import com.example.xutilsdemo.app.MyApp
import com.example.xutilsdemo.utils.FireGsonUtil
import org.xutils.DbManager
import org.xutils.common.util.KeyValue
import org.xutils.db.sqlite.WhereBuilder
import org.xutils.ex.DbException
import java.io.ByteArrayOutputStream
import java.io.PrintStream
/**
*@author: njb
*@date: 2023/5/24 23:04
*@desc:
*/
class UserInfoDBManager {
private val TAG = "UserInfoDbManager"
companion object {
private lateinit var mDbManager: DbManager
val instance by lazy (LazyThreadSafetyMode.SYNCHRONIZED){ UserInfoDBManager() }
}
fun initDB(){
mDbManager = MyApp.instance.getLocalDbManager()
}
/**
* 保存用户信息
*
* @param UserInfoDataBaseBean 传入用户信息
*/
open fun saveUserInfo(UserInfoDataBaseBean: UserInfoDataBaseBean) {
try {
LogUtils.i(TAG, "=====saveUserInfo: ${FireGsonUtil.objectToJson(UserInfoDataBaseBean)}")
mDbManager.saveOrUpdate(UserInfoDataBaseBean)
} catch (e: DbException) {
e.printStackTrace()
LogUtils.e(TAG, "====saveUserInfo: 出错!! " + getExceptionInfo(e))
}
}
/**
* 通过name删除用户信息
*
* @param name return 删除条数 -1则异常
*/
fun deleteByDeviceName(name: String?): Int {
return try {
mDbManager.delete(
UserInfoDataBaseBean::class.java,
WhereBuilder.b().and("name", "=", name)
)
} catch (e: DbException) {
e.printStackTrace()
LogUtils.e(TAG, "deleteByName: " + getExceptionInfo(e))
-1
}
}
/**
* 通过id删除用户
*
* @param id
* @return 删除条数 -1则异常
*/
fun deleteByUserId(id: Int): Int {
return try {
mDbManager.delete(
UserInfoDataBaseBean::class.java,
WhereBuilder.b().and("id", "=", id)
)
} catch (e: DbException) {
e.printStackTrace()
LogUtils.e(TAG, "deleteByRunName: " + getExceptionInfo(e))
-1
}
}
/**
* 删除所有设备-删除表
*/
fun deleteAllUsers() {
try {
mDbManager.dropTable(UserInfoDataBaseBean::class.java)
} catch (e: DbException) {
e.printStackTrace()
LogUtils.e(TAG, "deleteAllUsers: " + getExceptionInfo(e))
}
}
/**
* 更新用户信息状态
*
* @param name
* @return 修改多少条数
*/
fun updateByName(name: String?, vararg kv: KeyValue?): Int {
return try {
mDbManager.update(
UserInfoDataBaseBean::class.java,
WhereBuilder.b().and("name", "=", name),
*kv
)
} catch (e: Exception) {
e.printStackTrace()
LogUtils.e(TAG, "updateByName: " + getExceptionInfo(e))
-1
}
}
/**
* ApplianceId更新用户状态
*
* @param id
* @return 修改多少条数
*/
fun updateById(id: String?, vararg kv: KeyValue?): Int {
return try {
mDbManager.update(
UserInfoDataBaseBean::class.java,
WhereBuilder.b().and("id", "=", id),
*kv
)
} catch (e: Exception) {
e.printStackTrace()
LogUtils.e(TAG, "updateById: " + getExceptionInfo(e))
-1
}
}
/**
* 更状态
*
* @param UserInfoDataBaseBean 传入结构体更新数据库
*/
fun updateUserInfo(UserInfoDataBaseBean: UserInfoDataBaseBean?) {
try {
mDbManager.replace(UserInfoDataBaseBean)
} catch (e: DbException) {
e.printStackTrace()
LogUtils.e(TAG, "updateUserInfo: " + getExceptionInfo(e))
}
}
/**
* 获取所有用户
*
* @return List<UserInfoDataBaseBean>
**/
fun getAllUserInfo(): List<UserInfoDataBaseBean?>? {
return try {
mDbManager.findAll(
UserInfoDataBaseBean::class.java
)
} catch (e: DbException) {
e.printStackTrace()
LogUtils.e(TAG, "getAllUserInfo: " + getExceptionInfo(e))
null
}
}
/**
* 根据用户名称查找用户
*
* @param name
* @return UserInfoDataBaseBean
*/
fun queryUserInfoByName(name: String?): UserInfoDataBaseBean? {
return try {
mDbManager.selector(UserInfoDataBaseBean::class.java).where("name", "=", name)
.findFirst()
} catch (e: DbException) {
e.printStackTrace()
LogUtils.e(TAG, "queryUserInfoByName: " + getExceptionInfo(e))
null
}
}
/**
* 根据Id查找用户信息
*
* @param id
* @return UserInfoDataBaseBean
*/
fun queryDeviceByApplianceId(id: String?): UserInfoDataBaseBean? {
return try {
mDbManager.selector(UserInfoDataBaseBean::class.java).where("id", "=", id)
.findFirst()
} catch (e: DbException) {
e.printStackTrace()
LogUtils.e(TAG, "queryDeviceByApplianceId: " + getExceptionInfo(e))
null
}
}
fun getExceptionInfo(e: Exception): String {
val baos = ByteArrayOutputStream()
e.printStackTrace(PrintStream(baos))
return baos.toString()
}
}
4.用户信息数据库:
package com.example.xutilsdemo.db
import org.xutils.db.annotation.Column
import org.xutils.db.annotation.Table
/**
*@author: njb
*@date: 2023/5/24 23:02
*@desc:
*/
@Table(name = "userinfo")
open class UserInfoDataBaseBean(
@Column(name = "id", isId = true, property = "UNIQUE")
var id: String? = "",
@Column(name = "name")
var name: String? = "",
@Column(name = "age")
var age: String? = "",
@Column(name = "account")
var account:String ?= "",
@Column(name = "size")
var size:String ? = ""
):java.io.Serializable
5.获取数据库配置信息:
private lateinit var dbManager: DbManager
/**
* 获取数据库配置信息
*
* @return 配置信息对象
*/
open fun getLocalDbManager(): DbManager {
val dbConfig = DaoConfig()
.setDbName("userinfo.db")
.setDbVersion(1)
.setDbOpenListener { db: DbManager -> db.database.enableWriteAheadLogging() } //监听数据库打开
.setDbUpgradeListener { db: DbManager, oldVersion: Int, newVersion: Int -> //监听数据库更新
//todo:数据库升级需要做的一些操作
try {
} catch (e: DbException) {
e.printStackTrace()
}
}.setTableCreateListener { db: DbManager?, table: TableEntity<*>? -> }
dbManager = x.getDb(dbConfig)
return dbManager
}
6.添加用户信息:
fun add(view: View) {
UserInfoDBManager.instance.initDB()
userInfo.id = "1"
userInfo.name = "张帅"
userInfo.age = "18"
userInfo.account = "4"
userInfo.size = "100"
try {
UserInfoDBManager.instance.saveUserInfo(userInfo)
}catch (e:Exception){
e.printStackTrace()
}
}
7.主界面布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="add"
android:text="增加"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="delete"
android:text="删除"
app:layout_constraintTop_toBottomOf="@+id/add" />
<Button
android:id="@+id/update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="update"
android:text="修改"
app:layout_constraintTop_toBottomOf="@+id/delete" />
<Button
android:id="@+id/query"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="query"
android:text="条件查询"
app:layout_constraintTop_toBottomOf="@+id/update" />
<Button
android:id="@+id/query_all"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="query_all"
android:text="查询全部"
app:layout_constraintTop_toBottomOf="@+id/query" />
</androidx.constraintlayout.widget.ConstraintLayout>
8.打印添加后的用户信息:
9.效果截图:
10.数据库升级:
private DbUpgradeListener dbUpgradeListener; //升级监听事件
数据库默认版本为1;添加了一个头像字段后,版本修改为2,
xutils中数据库版本的回调为:setDbUpgradeListener,
升级为的步骤为:
- 判断版本
- 添加相应的列名
- 查找数据库中的数据
- 保存并更新数据库数据
/**
* 获取数据库配置信息
*
* @return 配置信息对象
*/
open fun getLocalDbManager(): DbManager {
val dbConfig = DaoConfig()
.setDbName("userinfo.db")
.setDbVersion(2)
.setDbOpenListener { db: DbManager -> db.database.enableWriteAheadLogging() } //监听数据库打开
.setDbUpgradeListener { db: DbManager, oldVersion: Int, newVersion: Int -> //监听数据库更新
//todo:数据库升级需要做的一些操作
try {
if (newVersion > oldVersion) {
db.addColumn(UserInfoDataBaseBean::class.java, "avatar")
val userList: List<UserInfoDataBaseBean> =
db.findAll(UserInfoDataBaseBean::class.java)
db.saveOrUpdate(userList)
LogUtils.d("--数据库版本升级成功--", FireGsonUtil.listToJson(userList))
}
} catch (e: DbException) {
e.printStackTrace()
}
}.setTableCreateListener { db: DbManager?, table: TableEntity<*>? -> }
dbManager = x.getDb(dbConfig)
return dbManager
}
11.完整代码如下:
package com.example.xutilsdemo
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.blankj.utilcode.util.ToastUtils
import com.example.xutilsdemo.db.UserInfoDBManager
import com.example.xutilsdemo.db.UserInfoDataBaseBean
import com.example.xutilsdemo.utils.FireGsonUtil
class MainActivity : AppCompatActivity() {
val userInfo: UserInfoDataBaseBean by lazy { UserInfoDataBaseBean() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun add(view: View) {
UserInfoDBManager.instance.initDB()
userInfo.id = "1"
userInfo.name = "张帅"
userInfo.age = "18"
userInfo.account = "4"
userInfo.size = "100"
userInfo.avatar = ""
try {
UserInfoDBManager.instance.saveUserInfo(userInfo)
ToastUtils.showShort("添加数据成功" + FireGsonUtil.objectToJson(userInfo))
} catch (e: Exception) {
e.printStackTrace()
}
}
fun delete(view: View) {}
fun update(view: View) {}
fun query(view: View) {}
fun query_all(view: View) {}
}
12.总结:
本文全程采用koltin语法,因为最近项目基本上都是kotlin,数据库升级很简单,大家可以随便添加一个字段进行升级尝试.具体的实现根据自己的业务进行调整,但是不建议使用xutils,毕竟现在LitePal、Room、DataStore使用也非常方便简单,大家可以根据自己喜欢选择数据库.
13.代码源码地址如下:
https://gitee.com/jackning_admin/xutilsdemo