Android解决xutils数据库kotlin添加List数组问题

文章讲述了在使用xutils数据库操作时遇到的不能直接存储KotlinList数据的问题,以及如何通过自定义转换器ColumnConverter和Gson来实现List数据的序列化和反序列化,从而成功存储和读取List数据的解决方案。
摘要由CSDN通过智能技术生成

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和用户名称查询方法,只不过我不想测试了,项目中基本上所有的方法都使用了,如果感兴趣的同学可以自行尝试其他方法,基本上和其他数据库的使用方法没有多大区别,不会有太大问题,遇到问题不要慌,仔细排查,找到原因后努力解决就是了.道险且长,仍需努力,不畏艰难,勇往直前,码完收工,关机睡觉.

20.项目源码地址如下:

https://gitee.com/jackning_admin/xutilsdemo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值