Android解决xutils数据库kotlin添加List数组问题
前言:
上一篇我们讲解了xutils中数据库版本升级的使用和问题,这篇博客讲解xutils中数据库添加list数据的问题,这个库真的是很强大,但是数据库的使用真不友好,添加一个list数组的数据居然报错,我的天,没办法,老项目选择了这个库就必须找到解决方法,要是你不想使用此库,可以换一个数据库,比如Room、DataStore、LitePal都是目前不错的选择,我是时间成本不允许,还是不折腾了,后期我会抽时间把这个古老的破旧代码给彻底换掉,要不然不熟悉这个库的人遇到这些坑会折磨死,问题不难,就是要熟悉这个库,能立马定位出问题,拿出解决方法.不扯了,直接上代码.
1.添加devices数组:
@Table(name = "userinfo")
open class UserInfoDataBaseBean:Serializable{
@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 ? = ""
@Column(name = "avatar")
var avatar:String ?= ""
@Column(name = "devices")
lateinit var devices:MutableList<DevicesInfoBean>
}
private val userInfo: UserInfoDataBaseBean by lazy { UserInfoDataBaseBean() }
private lateinit var devicesList: MutableList<DevicesInfoBean>
private var devicesInfoBean = DevicesInfoBean()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
UserInfoDBManager.instance.initDB()
initData()
}
private fun initData() {
devicesList = ArrayList()
devicesInfoBean.deviceName = "客厅空调"
devicesInfoBean.deviceType = "AIC"
devicesInfoBean.status = "on"
devicesInfoBean.address = "01"
devicesInfoBean.values = "10"
devicesList.add(devicesInfoBean)
// userInfo = UserInfoDataBaseBean("1","张帅","18","4","100","", devicesList!!)
}
}
2.打印日志如下:
新增设备信息列表:
查询所有信息:
这样操作会导致一个问题,用户信息是查出来了,但是用户信息对象里的devices集合是空的,我还洋洋得意的以为一切正常,然而小伙子你还是太年轻!!!
打开数据库表查看数据库信息:发现devices为null,没有保存进去,这是什么鬼?数据库居然不支持list数组?还能不能愉快的玩耍了???
3.查找原因:
原因是xutils数据库源码中支持的数据类型只有4种:
所以要使用自定义转换器来转换自定义的数据类型。
4.解决方法:
自定义转换器来转换自定义的数据类型,xutils内置了一些转换器:ColumnConverter
5.自定义转换器:
xUtils提供了一个转换器的接口ColumnConverter,因些我们只要实现这一接口即可
/**
*@author: njb
*@date: 2023/5/27 18:41
*@desc:
*/
class ListDevicesConverter :ColumnConverter<ListDevices<DevicesInfoBean>>{
override fun getFieldValue(
cursor: Cursor,
index: Int
): ListDevices<DevicesInfoBean>? {
return if(cursor.isNull(index)){
null
}else {
val s = cursor.getString(index)
val gson = Gson()
gson.fromJson(
s,
object : TypeToken<ListDevices<DevicesInfoBean>>() {}.type
)
}
}
override fun getColumnDbType(): ColumnDbType {
return ColumnDbType.TEXT
}
override fun fieldValue2DbValue(fieldValue: ListDevices<DevicesInfoBean>?): Any {
val gson = Gson()
return gson.toJson(fieldValue)
}
}
6.自定义列表数据转换器:
/**
*@author: njb
*@date: 2023/5/27 18:42
*@desc:
*/
class ListDevices <DevicesInfoBean>: ArrayList<DevicesInfoBean>() {
}
7.注册转换器:
private fun initXUtils() {
x.Ext.init(this)
x.Ext.setDebug(true)
ColumnConverterFactory.registerColumnConverter(ListDevices::class.java, ListDevicesConverter())
}
8.具体使用:
@Table(name = "userinfo")
open class UserInfoDataBaseBean:Serializable{
@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 ? = ""
@Column(name = "avatar")
var avatar:String ?= ""
@Column(name = "devices")
lateinit var devices:ListDevices<DevicesInfoBean>
}
9.测试新增数据:
private val userInfo: UserInfoDataBaseBean by lazy { UserInfoDataBaseBean() }
private lateinit var devicesList: ListDevices<DevicesInfoBean>
private var devicesInfoBean = DevicesInfoBean()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
UserInfoDBManager.instance.initDB()
initData()
}
private fun initData() {
devicesList = ListDevices()
devicesInfoBean.deviceName = "客厅空调"
devicesInfoBean.deviceType = "AIC"
devicesInfoBean.status = "on"
devicesInfoBean.address = "01"
devicesInfoBean.values = "10"
devicesList.add(devicesInfoBean)
// userInfo = UserInfoDataBaseBean("1","张帅","18","4","100","", devicesList!!)
}
fun add(view: View) {
try {
userInfo.let {
it.id = "1"
it.name = "张帅"
it.age = "18"
it.account = "4"
it.size = "100"
it.avatar = ""
it.devices = devicesList
UserInfoDBManager.instance.saveUserInfo(it)
ToastUtils.showShort("添加数据成功" + FireGsonUtil.objectToJson(it))
}
} catch (e: Exception) {
e.printStackTrace()
}
}
10.打印修改后的测试结果:
这次发现打印出来的结果都有了,而且数据很正常,很nice有木有~~~~
11.查看数据库表新数据:
查询单个信息和所有用户信息都有设备列表数据,可以发现完美解决添加list数组问题,对象和其他自定义数据类型都是一样的用法,这里就不重复讲解了,大家可自行体验.
12.数据修改:
修改数据库中的数据:
fun update(view: View) {
try {
devicesList.clear()
devicesInfoBean.deviceName = "卧室空调"
devicesInfoBean.deviceType = "AIC"
devicesInfoBean.status = "off"
devicesInfoBean.address = "02"
devicesInfoBean.values = "06"
devicesList.add(devicesInfoBean)
userInfo.run {
this.id = "22"
this.name = "李四"
this.size = "15"
this.account = "12345"
this.age = "18"
this.avatar = ""
this.devices = devicesList!!
UserInfoDBManager.instance.updateUserInfo(userInfo)
LogUtils.d("=更新用户信息===" + FireGsonUtil.objectToJson(userInfo))
}
} catch (e: Exception) {
e.printStackTrace()
}
}
13.数据查询:
调用数据库查询方法查询单个数据信息:
fun query(view: View) {
try {
try {
val userInfo: UserInfoDataBaseBean? =
UserInfoDBManager.instance.queryUserInfoByName("张帅")
LogUtils.d("=查询用户信息===" + FireGsonUtil.objectToJson(userInfo))
} catch (e: Exception) {
e.printStackTrace()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
14.查询所有数据:
调用数据库中查询所有数据方法查找所有数据:
fun queryAll(view: View) {
try {
val userList: List<UserInfoDataBaseBean>? = UserInfoDBManager.instance.getAllUserInfo()
LogUtils.d("=查询所有用户信息===" + FireGsonUtil.listToJson(userList))
} catch (e: Exception) {
e.printStackTrace()
}
}
15.删除数据:
调用数据库中的删除方法删除数据库的数据
fun delete(view: View) {
try {
UserInfoDBManager.instance.deleteAllUsers()
LogUtils.d("=删除后的用户信息===" + UserInfoDBManager.instance.getAllUserInfo())
} catch (e: Exception) {
e.printStackTrace()
}
}
16.完整测试代码如下:
package com.example.xutilsdemo
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.example.xutilsdemo.db.DevicesInfoBean
import com.example.xutilsdemo.db.ListDevices
import com.example.xutilsdemo.db.UserInfoDBManager
import com.example.xutilsdemo.db.UserInfoDataBaseBean
import com.example.xutilsdemo.utils.FireGsonUtil
class MainActivity : AppCompatActivity() {
private val userInfo: UserInfoDataBaseBean by lazy { UserInfoDataBaseBean() }
private lateinit var devicesList: ListDevices<DevicesInfoBean>
private val devicesInfoBean by lazy { DevicesInfoBean() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
UserInfoDBManager.instance.initDB()
initData()
}
private fun initData() {
devicesList = ListDevices()
// userInfo = UserInfoDataBaseBean("1","张帅","18","4","100","", devicesList!!)
}
fun add(view: View) {
try {
devicesInfoBean.deviceName = "客厅空调"
devicesInfoBean.deviceType = "AIC"
devicesInfoBean.status = "on"
devicesInfoBean.address = "01"
devicesInfoBean.values = "10"
devicesList.add(devicesInfoBean)
userInfo.let {
it.id = "1"
it.name = "张帅"
it.age = "18"
it.account = "4"
it.size = "100"
it.avatar = ""
it.devices = devicesList
UserInfoDBManager.instance.saveUserInfo(it)
ToastUtils.showShort("添加数据成功" + FireGsonUtil.objectToJson(it))
}
} catch (e: Exception) {
e.printStackTrace()
}
}
fun delete(view: View) {
try {
UserInfoDBManager.instance.deleteAllUsers()
LogUtils.d("=删除后的用户信息===" + UserInfoDBManager.instance.getAllUserInfo())
} catch (e: Exception) {
e.printStackTrace()
}
}
fun update(view: View) {
try {
devicesList.clear()
devicesInfoBean.deviceName = "卧室空调"
devicesInfoBean.deviceType = "AIC"
devicesInfoBean.status = "off"
devicesInfoBean.address = "02"
devicesInfoBean.values = "06"
devicesList.add(devicesInfoBean)
userInfo.run {
this.id = "22"
this.name = "李四"
this.size = "15"
this.account = "12345"
this.age = "18"
this.avatar = ""
this.devices = devicesList!!
UserInfoDBManager.instance.updateUserInfo(userInfo)
LogUtils.d("=更新用户信息===" + FireGsonUtil.objectToJson(userInfo))
}
} catch (e: Exception) {
e.printStackTrace()
}
}
fun query(view: View) {
try {
try {
val userInfo: UserInfoDataBaseBean? =
UserInfoDBManager.instance.queryUserInfoByName("张帅")
LogUtils.d("=查询用户信息===" + FireGsonUtil.objectToJson(userInfo))
} catch (e: Exception) {
e.printStackTrace()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
fun queryAll(view: View) {
try {
val userList: List<UserInfoDataBaseBean>? = UserInfoDBManager.instance.getAllUserInfo()
LogUtils.d("=查询所有用户信息===" + FireGsonUtil.listToJson(userList))
} catch (e: Exception) {
e.printStackTrace()
}
}
}
17.完整布局代码:
<?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="queryAll"
android:text="查询全部数据"
app:layout_constraintTop_toBottomOf="@+id/query" />
</androidx.constraintlayout.widget.ConstraintLayout>
18.效果预览图:
19.总结:
以上就是今天的全部内容,从数据库增、删、改、查到数据库添加新数据类型,自定义数据转换器等等,可以说很全面了,基本上涵盖了大部分用法,里面还有根据id和用户名称查询方法,只不过我不想测试了,项目中基本上所有的方法都使用了,如果感兴趣的同学可以自行尝试其他方法,基本上和其他数据库的使用方法没有多大区别,不会有太大问题,遇到问题不要慌,仔细排查,找到原因后努力解决就是了.道险且长,仍需努力,不畏艰难,勇往直前,码完收工,关机睡觉.