我相信您可以使用包含所有字段的 POJO(或者可能是合适的实体,如果存在的话)并使用包含 UNION 的 getAll@Query。当然,更好的方法或许是重新考虑设计。
以下是一个父类 (BaseObject) 的示例,从其中继承了 2 个对象,名称为 ChildType1 和 ChildType2。
在此示例中,ChildType2 具有 2 个附加字段,其中一个 ChildType1 具有唯一的附加字段。因此 ChildType2 适合保存 ChildType1 的所有字段。
但是,要正确提取 ChildType1,它必须模仿 ChildType2 的附加字段>。这可以通过 Dao Alldao 中 getAll() 方法中的 SQL 轻松完成。
以下是使用的代码:-
BaseObject,两个 ChildType 继承自:-
class BaseObject {
@ColumnInfo(name = BaseColumns._ID)
Long id;
String name;
long createdTimestamp = System.currentTimeMillis() / 1000;
int type;
}
ChildType1 :-
@Entity(primaryKeys = {BaseColumns._ID})
class ChildType1 extends BaseObject {
public static final int TYPE = 1;
String ct1;
}
- 正如将看到的,id 列 (_id) 已被继承,后来它不会导致任何问题。
ChildType2 :-
@Entity(primaryKeys = {BaseColumns._ID})
class ChildType2 extends BaseObject {
public static final int TYPE = 2;
String ct1;
String ct2;
}
AllDao,所有的道都被编码了:-
@Dao
interface AllDao {
@Insert
long insert(ChildType1 childType1);
@Insert
long insert(ChildType2 childType2);
@Query("SELECT *, 'n/a' AS ct2 FROM ChildType1 UNION SELECT * FROM childtype2")
List<ChildType2> getAll();
}
- 查询正在使用最初 childtype1 表的 UNION 填充缺少的 ct2 字段,值为 n/a 和 childtype2 表。请注意,id 可能会被重复,因此要使用 id,您必须确定相应的类型 (例如,ct2 = n/a 那么它可能是 ChildType1(因此我会建议字符串类型的指示符)不能模棱两可))。
@Database TheDatabase :-
@Database(entities = {ChildType1.class,ChildType2.class},version = 1)
abstract class TheDatabase extends RoomDatabase {
abstract AllDao getAllDao();
private volatile static TheDatabase instance;
public static TheDatabase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(
context,
TheDatabase.class,
"thedatabase.db"
)
.allowMainThreadQueries()
.build();
instance.getOpenHelper().getWritableDatabase();
}
return instance;
}
}
最后是一个 Activity,MainActivity 将它们放在一起进行演示:-
public class MainActivity extends AppCompatActivity {
TheDatabase db;
AllDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = TheDatabase.getInstance(this);
dao = db.getAllDao();
ChildType1 c1_1 = new ChildType1();
c1_1.name = "CT1 001";
c1_1.ct1 = "This is a CT1 for CT1 001";
c1_1.type = ChildType1.TYPE;
dao.insert(c1_1);
ChildType2 c2_1 = new ChildType2();
c2_1.name = "CT2 002";
c2_1.ct1 = "This is CT1 for CT2 002";
c2_1.ct2 = "This is CT2 for CT2 002";
dao.insert(c2_1);
for(ChildType2 c: dao.getAll()) {
Log.d("" +
"TYPEINFO",
"Name = " + c.name +
"\n\t Created = " + c.createdTimestamp +
"\n\t ID = " + c.id +
"\n\t type = " + c.type +
"\n\t CT1 = " + c.ct1 +
"\n\t CT2 = " + c.ct2
);
}
}
}
结果
运行时日志包含:-
D/TYPEINFO: Name = CT1 001
Created = 1626589554
ID = 1
type = 1
CT1 = This is a CT1 for CT1 001
CT2 = n/a
D/TYPEINFO: Name = CT2 002
Created = 1626589554
ID = 1
type = 0
CT1 = This is CT1 for CT2 002
CT2 = This is CT2 for CT2 002
即两种类型的孩子都被提取到一个可以包含所有字段的对象列表中。