我尝试创建这些,但无法理解如何保持它们之间的关系以及插入/获取保存的数据。
您可以通过两种方式执行此操作:
第一个示例(所有三个表@Embedded
) 存在 :-
class OrgWithLoginAndStyle {
/* Note use Query that
JOINS the Orgtable with the Login table
and JOINS the Orgtable with the Style table
*/
@Embedded
OrgTable orgTable;
@Embedded
LoginOptionsTable loginOptionsTable;
@Embedded
StyleTable styleTable;
}
利用这一点的 Dao 的一个例子是:-
@Query("SELECT * FROM OrgTable " +
"JOIN StyleTable ON StyleTable.styleId = OrgTable.stId " +
"JOIN LoginOptionsTable ON LoginOptionsTable.loginOpnId = OrgTable.loginOptionsId")
List<OrgWithLoginAndStyle> getOrganizationLoginAndStyle();
- 这是更灵活的查询方式,因为所有列都可用于 WHERE 子句等,但查询更复杂。
第二个的例子(与@Relation
LoginOptionsTable 和 StyleTable 的注释):-
class OrganizationWithLoginOptionsAndWithStyles {
@Embedded
OrgTable orgTable;
@Relation(entity = LoginOptionsTable.class,parentColumn = "loginOptionsId",entityColumn = "loginOpnId")
List<LoginOptionsTable> loginOptionsTables;
@Relation(entity = StyleTable.class,parentColumn = "stId",entityColumn = "styleId")
List<StyleTable> styleTables;
}
- 这也许更容易编码。然而,它的效率较低,因为样式和 LoginOptions 是为每个 OrgTable 独立检索的。因此,查询更简单,因为您只需要获取 OrgTable。 Room 负责构建相关对象的工作。查询仅限于 OrgTable 列上的 WHERE 等(如果您 JOINed 其他表,此类子句可能不会获得所需的结果(在您的情况下可能没问题,因为每个 OrgTable 对象只有 1 个 LoginOptions 和 1 个 Style))
利用这一点的 Dao 的一个例子是:-
@Transaction
@Query("SELECT * FROM OrgTable")
List<OrganizationWithLoginOptionsAndWithStyles> getOrganizationsLoginsAndStyles();
- 请注意,建议使用 @Transaction,因为(我相信)正在运行底层查询来获取 LoginOptionsTable 对象和 StyleTable 对象。
Note关于你的getOrganization
查询(见评论)
@Query("SELECT * FROM OrgTable")
//OrgTable getOrganization(); /* <<<<<<<<<< WRONG should be a List */
List<OrgTable> getOrganizations();
和你的insertOrg
@Insert
//void insertOrg(OrgTable org)
long insertOrg(OrgTable org); /* <<<<<<<<<< might as well allow the id of the inserted row to be obtained */
好的。现在我必须通过我的存储库将它们插入 Room 数据库,为此我面临很多困难。
我相信您的 OrgTable FK 定义应该如下:-
@Entity(foreignKeys = {@ForeignKey(entity = StyleTable.class, parentColumns =
"styleId", childColumns = "stId"),
@ForeignKey(entity = LoginOptionsTable.class, parentColumns =
"loginOpnId", childColumns = "loginOptionsId")
})
- 即 LoginOptions 子级和父级是错误的,并且父级应该是 loginOptionsId 而不是 loginOptionId (不是 Option 之后的 s)。
基础测试
使用上面的以下代码,除了使OrgDao班级 :-
@Dao
public interface OrgDAO {
@Query("SELECT * FROM OrgTable")
//OrgTable getOrganization(); /* <<<<<<<<<< WRONG should be a List */
List<OrgTable> getOrganizations();
@Query("SELECT * FROM OrgTable " +
"JOIN StyleTable ON StyleTable.styleId = OrgTable.stId " +
"JOIN LoginOptionsTable ON LoginOptionsTable.loginOpnId = OrgTable.loginOptionsId")
List<OrgWithLoginAndStyle> getOrganizationLoginAndStyle();
@Transaction
@Query("SELECT * FROM OrgTable")
List<OrganizationWithLoginOptionsAndWithStyles> getOrganizationsLoginsAndStyles();
@Insert
//void insertOrg(OrgTable org)
long insertOrg(OrgTable org); /* <<<<<<<<<< might as well allow the id of the inserted row to be obtained */
@Insert
long insertStyle(StyleTable styleTable);
@Insert
long insertLoginOptions(LoginOptionsTable loginOptionsTable);
}
并使用:-
@Database(entities = {OrgTable.class,StyleTable.class,LoginOptionsTable.class},version = 1)
抽象类 OrgLoginStyleDatabase 扩展 RoomDatabase {
抽象 OrgDAO getOrgDao();
}
并通过一个活动(请注意,您的一些代码已被注释掉,即实体的 @Parcelize 和 @Ignored Concstructors 的使用):-
public class MainActivity extends AppCompatActivity {
OrgLoginStyleDatabase db;
OrgDAO dao;
public static final String TAG = "OLSINFO";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = Room.databaseBuilder(this,OrgLoginStyleDatabase.class,"orgloginoptionsstyle.db")
.allowMainThreadQueries()
.build();
dao = db.getOrgDao();
StyleTable s1 = new StyleTable();
s1.bannerBackgroundColor = "X";
s1.bannerTextColor = "X";
s1.baseTextSize = 20;
s1.bodyBackgroundColor = "X";
s1.bodyTextColor = "X";
s1.buttonBackgroundColor = "X";
s1.buttonTextColor = "X";
s1.htmlWrapper = "X";
s1.navigationBackgroundColor = "X";
s1.navigationTextColor = "X";
s1.styleId = 100;
s1.topBarBackgroundColor = "X";
s1.topBarLabel = "X";
s1.topBarTextColor = "X";
long s1Id = dao.insertStyle(s1);
LoginOptionsTable l1 = new LoginOptionsTable();
l1.allowedEmailDomain = "Y";
l1.authorizationEndpointUri = "Y";
l1.clientId = "Y";
l1.clientSecret = "Y";
l1.description = "Y";
l1.loginOpnId = 1000;
l1.name = "Y";
l1.nonce = "Y";
l1.redirectUri = "Y";
l1.restrictedEmailDomain = "Y";
l1.state = "Y";
l1.title = "Y";
l1.url = "Y";
long l1Id = dao.insertLoginOptions(l1);
OrgTable o1 = new OrgTable();
o1.description = "Z";
o1.id = 10000;
o1.loginOptionsId = l1Id;
o1.stId = s1Id;
dao.insertOrg(o1);
List<OrgTable> orgTableList = dao.getOrganizations();
for(OrgTable o: orgTableList) {
logOrgTable(o,"FROM getOrganizations -> ");
}
List<OrganizationWithLoginOptionsAndWithStyles> organizationsLoginsAndStylesList = dao.getOrganizationsLoginsAndStyles();
for(OrganizationWithLoginOptionsAndWithStyles owloaws: organizationsLoginsAndStylesList) {
logOrgTable(owloaws.orgTable,"FROM (@Relations) getOrganizationsLoginsAndStyles -> ");
for(LoginOptionsTable lot: owloaws.loginOptionsTables) {
logLoginOptionsTable(lot,"\t");
}
for(StyleTable s: owloaws.styleTables) {
logStyleTable(s,"\t");
}
}
List<OrgWithLoginAndStyle> owlas = dao.getOrganizationLoginAndStyle();
for(OrgWithLoginAndStyle o: owlas) {
logOrgTable(o.orgTable,"FROM (@Embeddeds) getOrganizationLoginAndStyle -> ");
logLoginOptionsTable(o.loginOptionsTable,"\t");
logStyleTable(o.styleTable,"\t");
}
}
private void logOrgTable(OrgTable o,String preamble) {
Log.d(TAG,preamble + "OrgTable Description = " + o.description + " ID = " + o.id);
}
private void logStyleTable(StyleTable s, String preamble) {
Log.d(TAG,preamble + "StyleTable Description = " + s.topBarTextColor + " ID =" + s.styleId);
}
private void logLoginOptionsTable(LoginOptionsTable l, String preamble) {
Log.d(TAG,preamble + "LoginOptionsTable Description = " + l.description + " ID = " + l.loginOpnId);
}
}
Result
运行时(仅运行一次,因为已使用硬编码 ID),输出到日志的结果是:-
2021-04-12 21:51:50.981 D/OLSINFO: FROM getOrganizations -> OrgTable Description = Z ID = 10000
2021-04-12 21:51:50.987 D/OLSINFO: FROM (@Relations) getOrganizationsLoginsAndStyles -> OrgTable Description = Z ID = 10000
2021-04-12 21:51:50.987 D/OLSINFO: LoginOptionsTable Description = Y ID = 1000
2021-04-12 21:51:50.987 D/OLSINFO: StyleTable Description = X ID =100
2021-04-12 21:51:50.989 D/OLSINFO: FROM (@Embeddeds) getOrganizationLoginAndStyle -> OrgTable Description = Z ID = 10000
2021-04-12 21:51:50.989 D/OLSINFO: LoginOptionsTable Description = Y ID = 1000
2021-04-12 21:51:50.989 D/OLSINFO: StyleTable Description = X ID =100
- 所有三个对象均已成功插入,并且所有三个查询均按预期工作。