使用 Room 引用复杂数据

本文介绍如何在Room数据库中使用类型转换器处理复杂数据类型,如Date,并解释为何Room不支持实体间对象引用,以及如何通过创建POJO和编写联接查询来解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用 Room 引用复杂数据
Room 提供了在基元类型和盒装类型之间进行转换的功能,但不允许实体之间进行对象引用。本文档介绍了如何使用类型转换器,以及 Room 为何不支持对象引用。

使用类型转换器
有时,您的应用需要使用自定义数据类型,其中包含您想要存储到单个数据库列中的值。要为自定义类型添加此类支持,您需要提供一个 TypeConverter,它可以在自定义类与 Room 可以保留的已知类型之间来回转换。

例如,如果我们想保留 Date 的实例,则可以编写以下 TypeConverter,将等效的 Unix 时间戳存储在数据库中:

 class Converters {
     @TypeConverter
     fun fromTimestamp(value: Long?): Date? {
         return value?.let { Date(it) }
     }

     @TypeConverter
     fun dateToTimestamp(date: Date?): Long? {
         return date?.time?.toLong()
     }
 }

前面的示例定义了 2 个函数,一个用于将 Date 对象转换为 Long 对象,另一个用于执行从 Long 到 Date 的反向转换。由于 Room 已知道如何保留 Long 对象,因此可以使用此转换器来保存 Date 类型的值。

接着,将 @TypeConverters 注释添加到 AppDatabase 类中,以便 Room 可以使用您为该 AppDatabase 中的每个实体和 DAO 定义的转换器:

AppDatabase

@Database(entities = arrayOf(User::class), version = 1)
	@TypeConverters(Converters::class)
	abstract class AppDatabase : RoomDatabase() {
	    abstract fun userDao(): UserDao
 }

通过使用这些转换器,您就可以在其他查询中使用自定义类型,就像使用基元类型一样,如以下代码段所示:

User
    @Entity
    data class User(private val birthday: Date?)
    

UserDao
    @Dao
    interface UserDao {
        @Query("SELECT * FROM user WHERE birthday BETWEEN :from AND :to")
        fun findUsersBornBetweenDates(from: Date, to: Date): List<User>
    }

您还可以将 @TypeConverters 限制为不同的范围,包括个别实体、DAO 和 DAO 方法。如需了解详情,请参阅有关 @TypeConverters 注释的参考文档。

了解 Room 为何不允许对象引用
要点:Room 不允许实体类之间进行对象引用。因此,您必须明确请求您的应用所需的数据。

映射从数据库到相应对象模型之间的关系是一种常见做法,极其适用于服务器端。即使程序在访问字段时加载字段,服务器仍然可以正常工作。

但在客户端,这种延迟加载是不可行的,因为它通常发生在界面线程上,并且在界面线程上查询磁盘上的信息会导致严重的性能问题。界面线程通常需要大约 16 毫秒来计算和绘制 Activity 的更新后的布局,因此,即使查询只用了 5 毫秒,您的应用仍然可能会用尽剩余的时间来绘制框架,从而导致明显的显示故障。如果有一个并行运行的单独事务,或者设备正在运行其他磁盘密集型任务,则查询可能需要更多时间才能完成。不过,如果您不使用延迟加载,则应用会抓取一些不必要的数据,从而导致内存消耗问题。

对象关系型映射通常将决定权留给开发者,以便他们可以针对自己的应用用例执行最合适的操作。开发者通常会决定在应用和界面之间共享模型。不过,这种解决方案并不能很好地扩展,因为界面会不断发生变化,共享模型会出现开发者难以预测和调试的问题。

例如,假设界面加载了 Book 对象的列表,其中每本图书都有一个 Author 对象。您最初可能设计让查询使用延迟加载,从而让 Book 实例检索作者。对 author 字段的第一次检索会查询数据库。一段时间后,您发现还需要在应用的界面中显示作者姓名。您可以轻松访问此名称,如以下代码段所示:

authorNameTextView.text = book.author.name

不过,这种看似无害的更改会导致在主线程上查询 Author 表。

如果您事先查询作者信息,则在您不再需要这些数据时,就会很难更改数据加载方式。例如,如果应用的界面不再需要显示 Author 信息,则应用会有效地加载不再显示的数据,从而浪费宝贵的内存空间。如果 Author 类引用其他表(例如 Books),则应用的效率会进一步下降。

要使用 Room 同时引用多个实体,请改为创建包含每个实体的 POJO,然后编写用于联接相应表的查询。这种结构合理的模型结合 Room 强大的查询验证功能,可让您的应用在加载数据时消耗较少的资源,从而改善应用的性能和用户体验。

### Data Room 数据可视化的方法与工具 Data Room 是指一种集中存储和管理敏感数据的空间,通常用于商业交易、法律事务或其他需要高度保密性的场景。为了更好地理解和利用这些数据数据可视化成为不可或缺的一部分。 #### 常见的数据可视化方法 1. **热力图 (Heatmap)** 热力图是一种通过颜色强度展示数值大小的图表形式,在显示空间分布或时间序列上的变化非常有效。例如,在引用中提到的某次会议中的人员移动轨迹监控[^4],可以使用热力图来直观呈现不同区域内的人流量密度。 2. **交互式仪表盘 (Interactive Dashboards)** 交互式仪表盘允许用户动态筛选、过滤以及探索多维数据集。这种类型的可视化特别适合复杂的企业级应用环境下的 data room 场景。Tableau 提供了一种经济实惠的选择方案,尤其针对预算有限的小型企业[^2]。 3. **网络图 (Network Graphs)** 当涉及关系型数据时,比如公司之间的合作关系或者文档间的引用链接,网络图能够清晰表达节点间的关系结构及其权重属性。 4. **地理信息系统(GIS)地图** 如果 data room 中包含了地理位置信息,则 GIS 技术可以帮助创建基于位置的服务(LBS),从而更深入地洞察区域性趋势。例如房地产市场的分析可能需要用到此类技术来展现房源分布情况[^3]。 #### 推荐使用数据可视化工具/平台 以下是几个适用于构建高效 data room 的主流数据可视化软件: - **Power BI**: Microsoft 开发的强大BI工具,支持连接多种数据库源并生成精美的报告页面。 - **Tableau Public/Desktop Server**: 被广泛应用于商业智能领域的产品线之一;它不仅具备强大的图形渲染能力还提供免费版本(Tableau Public). - **QlikView/Qliksense**: 另一款专注于自助式数据分析体验的应用程序家族成员, 它们强调快速响应查询请求的同时保持较高的灵活性. - **D3.js**: 对于开发者而言,D3是一个灵活而功能全面的JavaScript库,可用于制作定制化程度很高的web端视觉效果. ```javascript // 使用 D3.js 创建简单柱状图的例子 var svg = d3.select("body").append("svg") .attr("width", 500) .attr("height", 300); var dataset = [5, 10, 15, 20]; svg.selectAll("rect") .data(dataset) .enter() .append("rect") .attr("x", function(d,i){return i * 70;}) .attr("y", function(d){return 300 - d*10;}) .attr("width", 65) .attr("height",function(d){return d*10;}); ``` 以上代码片段展示了如何借助 JavaScript 库 D3 来绘制基本条形图。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值