Android ROOM 涉及多个对象相关联问题

高级用法-多表查询

ROOM 中不允许类中存在对象的直接引用。主要原因:在客户端查询数据库时会严重影响其性能,会严重阻塞UI线程。具体可以查询下Google官方解释。

针对这样的情况,提出了@Embedded注解 将引用的对象属性全部加载当前表中;也提出@TypeConverter , @TypeConverters注解来将复杂类型转化为ROOM支持的数据类型;也提供了@ForeignKey满足表之间关联查询;@Query 也支持直接填写多表联合查询SQL语句;还提供了@Relation 来解决一对多等查询。

(1)@Embedded使用方法

//定义Book
public class Book {

    @NonNull
    public String name;

    public String publicAddress;

    @Override
    public String toString(){
        return "(name: " + name + ", publicAddress: " + publicAddress + ")";
    }
}

//修改Student表
@Entity(tableName = "student_table", foreignKeys = {@ForeignKey(entity = ClassInfo.class, parentColumns = {"class_num"},
        childColumns = {"class_num"})})
public class StudentInfo {
    @ColumnInfo(name = "student_num")
    @PrimaryKey
    public int studentNumber;

    @NonNull
    @ColumnInfo(name = "student_name")
    public String studentName;

    @ColumnInfo(name = "class_num")
    public int classNumber;

    @ColumnInfo(name = "student_sex")
    @SEX
    public String sex;

    @Embedded(prefix = "book_")
    public Book book;





    @Override
    public String toString(){
        return "(student_number: " + studentNumber + ", student_name: " + studentName + ", student_sex: "
                + sex + ", class_num: " + classNumber + ", book: "+ (book == null ? "null" : book.toString()) + ")";
    }


    @StringDef({SEX_FEMALE, SEX_MALE})
    public @interface SEX{

    }
    public final static String SEX_MALE = "男";
    public final static String SEX_FEMALE = "女";
}


@Database(entities = {StudentInfo.class, ClassInfo.class}, version = 3, exportSchema = true)
public abstract class SchoolDatabase extends RoomDatabase {
    public abstract StudentDAO studentDAO();
}

//升级处理
public class DataBaseUtils {

    private static volatile SchoolDatabase schoolDatabase;

    public static SchoolDatabase getSchoolDatabase(Context context){
        if(schoolDatabase == null){
            synchronized (SchoolDatabase.class){
                schoolDatabase = Room.databaseBuilder(context, SchoolDatabase.class, "school_db")
                        .addMigrations(new Migration(1, 2) {
                            @Override
                            public void migrate(@NonNull SupportSQLiteDatabase database) {
                                String sql = "ALTER TABLE student_table ADD student_sex TEXT";
                                database.execSQL(sql);
                            }
                        }, new Migration(2, 3) {
                            @Override
                            public void migrate(@NonNull SupportSQLiteDatabase database) {
                                String sql_name = "ALTER TABLE student_table ADD book_name TEXT";
                                String sql_public = "ALTER TABLE student_table ADD book_publicAddress TEXT";
                                database.execSQL(sql_name);
                                database.execSQL(sql_public);
                            }
                        })
                        .build();
            }
        }
        return schoolDatabase;
    }
」

(2)@TypeConveter @TypeConveters使用方法,将复杂类型转为ROOM支持的类型

//定义类型转换规则
public class TypeConverterUtils {

    @TypeConverter
    public String dateToTimestamp(Date date){
        if(date != null)return date.toString();
        return null;
    }

    @TypeConverter
    public Date fromTimeStamp(String timeStamp){
        if(timeStamp == null)return null;
        return new Date(timeStamp);
    }

}

//修改表
@Entity(tableName = "student_table", foreignKeys = {@ForeignKey(entity = ClassInfo.class, parentColumns = {"class_num"},
        childColumns = {"class_num"})})
public class StudentInfo {
    @ColumnInfo(name = "student_num")
    @PrimaryKey
    public int studentNumber;

    @NonNull
    @ColumnInfo(name = "student_name")
    public String studentName;

    @ColumnInfo(name = "class_num")
    public int classNumber;

    @ColumnInfo(name = "student_sex")
    @SEX
    public String sex;

    @Embedded(prefix = "book_")
    public Book book;


    @ColumnInfo(name = "birthDay")
    public Date date;

    @Override
    public String toString(){
        return "(student_number: " + studentNumber + ", student_name: " + studentName + ", birthDay: " + (date == null ? "unknown" : date.toString()) +", student_sex: "
                + sex + ", class_num: " + classNumber +", book: "+ (book == null ? "null" : book.toString()) + ")";
    }


    @StringDef({SEX_FEMALE, SEX_MALE})
    public @interface SEX{

    }
    public final static String SEX_MALE = "男";
    public final static String SEX_FEMALE = "女";
}

//修改数据库,添加转换规则
@TypeConverters(value = {TypeConverterUtils.class})
@Database(entities = {StudentInfo.class, ClassInfo.class}, version = 4, exportSchema = true)
public abstract class SchoolDatabase extends RoomDatabase {
    public abstract StudentDAO studentDAO();
}

public class DataBaseUtils {

    private static volatile SchoolDatabase schoolDatabase;

    public static SchoolDatabase getSchoolDatabase(Context context){
        if(schoolDatabase == null){
            synchronized (SchoolDatabase.class){
                schoolDatabase = Room.databaseBuilder(context, SchoolDatabase.class, "school_db")
                        .addMigrations(new Migration(1, 2) {
                            @Override
                            public void migrate(@NonNull SupportSQLiteDatabase database) {
                                String sql = "ALTER TABLE student_table ADD student_sex TEXT";
                                database.execSQL(sql);
                            }
                        }, new Migration(2, 3) {
                            @Override
                            public void migrate(@NonNull SupportSQLiteDatabase database) {
                                String sql_name = "ALTER TABLE student_table ADD book_name TEXT";
                                String sql_public = "ALTER TABLE student_table ADD book_publicAddress TEXT";
                                database.execSQL(sql_name);
                                database.execSQL(sql_public);
                            }
                        }, new Migration(3, 4) {
                            @Override
                            public void migrate(@NonNull SupportSQLiteDatabase database) {
                                String sql = "ALTER TABLE student_table ADD birthDay TEXT";
                                database.execSQL(sql);
                            }
                        })
                        .build();
            }
        }
        return schoolDatabase;
    }
}

(3) foreignKey 建立之间关联, quey 进行多表查询

(4)@Relation 是room 指定的一对多,多对多的解决方案。

//一对多,即一个class : n个学生
public class ClassAndStudent {
    @ColumnInfo(name = "class_num")
    public int classNumber;
    @ColumnInfo(name = "class_name")
    public String className;
    @Relation(parentColumn = "class_num", entityColumn = "class_num")
    List<StudentInfo> studentInfos;
}

//访问接口
 @Query("SELECT * FROM class_table")
 public abstract List<ClassAndStudent> getAll();

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值