Android 官方数据库Room --- 复杂数据

源文档链接

复杂数据

Room提供了基本类型到包装类型的转换,但是不允许实体类型之间的引用。这里解释如何使用类型转换,并且Room为何不允许

使用类型转换

有时,可能需要将自定义对象存在单独一列中。为了实现这个需求,需要添加TypeConverter,来讲自定义对象转成Room可处理的类型

例如:想要保存Date类型的对象,可以这样写

  1. 编写converter

    public class Converters {
        @TypeConverter
        public static Date fromTimestamp(Long value) {
            return value == null ? null : new Date(value);
        }
    
        @TypeConverter
        public static Long dateToTimestamp(Date date) {
            return date == null ? null : date.getTime();
        }
    }

    示例中定义了两个方法,一个将Date转换成Long,另一个将Long转换成Date,因为Room已经知道如何处理Long对象,它可以使用这个converter用于Date类型处理。

  2. 注册converter

    使用@TypeConverter注解将Converter注册到AppDatabase中,Room会使用在每个AppDatabase中定义的DAO和entity中使用

    AppDatabase.java

    @Database(entities = {User.class}, version = 1)
    @TypeConverters({Converters.class})
    public abstract class AppDatabase extends RoomDatabase {
        public abstract UserDao userDao();
    }

    User.java

    @Entity
    public class User {
        ...
        private Date birthday;
    }

    UserDao.java

    @Dao
    public interface UserDao {
        ...
        @Query("SELECT * FROM user WHERE birthday BETWEEN :from AND :to")
        List findUsersBornBetweenDates(Date from, Date to);
    }   

    可以指定每个converter的作用域,如某个实体,DAO,DAO方法等,详情

为什么Room不允许

关键点:Room不允许实体中对象引用。相反,你必须明确app需要什么样的数据

在服务端中,数据库到实体的关系映射很常见,并且工作的很好。即使在运行时程序加载字段。

然而,在客户端,这种类型的懒加载是不可行的,因为通常发生在UI线程,查询磁盘发生在UI线程时,会发生重大的性能问题。UI线程具有16ms计算和绘制Activity界面,即使查询花费了5ms,可能会影响界面的绘制,导致视图的卡顿。如果还有其他并行的事务或者设备进行磁盘敏感的任务时,查询时间会更长。如果不使用懒加载,会导致取出无用的数据,加大内存负担

对象关系映射通常会将这个问题留给开发人员,以便针对应用选择合适的策略。开发者通常会在应用程序和应用界面中共享数据。然而,这种解决方案并不能很好地扩展,因为随着UI的变化,共享模型会产生一些难以让开发人员预测和调试的问题。

例如,考虑UI中加载了很多的Book对象,每个Book对象中Author对象。可能你的初始设计是懒加载,使用Book对象的getAuthor()方法来获取author对象。第一次调用getAuthor()时查询数据库。一段时间后,需要在界面上展示author名字。你可以添加方法轻松实现,如下:

authorNameTextView.setText(user.getAuthor().getName());

但是,这会导致在UI线程对Author表查询

如果提前查询author信息,在不需要数据的时候,很难决定如何加载数据。例如,如果程序界面需要展示author信息,在不使用数据时,会浪费应用的内存空间。如果Author引用另一张表(如Book),那么应用程序的效率会进一步降低

引用多个实体,不如使用POJO的方式,只获取部分属性,编写链接响应表的查询即可。这种结构良好的模型与Room健壮的查询验证功能相结合,可让您的应用在加载数据时消耗更少的资源,从而改善应用的性能和用户体验

你可能感兴趣的:(android)