我认为您可能会因为您处理人际关系的方式而引起自己的焦虑。
考虑StateWithFacilities
您似乎是在说让学校的 id 等于该州的 schoolId 列。
虽然房地产应该来自 School 中存储适当 StateId 的列。
您似乎正在使用相反的方法。
例子
也许根据您似乎想要做的事情来考虑这个例子:(州、学校和地点已被赋予一个名称列,以使输出更容易理解)-
处于层次结构顶部的状态类(实体和表)。
@Entity
public class State {
@PrimaryKey
Long stateId;
String stateName;
// etc //
public State(){}
@Ignore
public State(String stateName){
this.stateName = stateName;
}
.... getters and setters
}
将属于一个州的学校班级(实体和表格)。
@Entity(
foreignKeys = {
@ForeignKey(entity = State.class,parentColumns = "stateId",childColumns = "stateIdMap"),
},
indices = {@Index("stateIdMap")}
)
public class School {
@PrimaryKey
Long schoolId;
Long stateIdMap;
String schoolName;
// etc
public School(){}
@Ignore
public School(String schoolName, long stateId) {
this.schoolName = schoolName;
this.stateIdMap = stateId;
}
.... getters and setters
}
- ForeignKeys 不是必需的,但可以帮助维护参照完整性。
- 同样, stateIdMap 列上的索引不是必需的,但如果定义了 ForeignKeys,如果索引不存在,Room 会发出警告。
属于学校的位置类(实体和表)(一个学校可以有许多位置)。
@Entity(
foreignKeys = {
@ForeignKey(entity = School.class,parentColumns = "schoolId",childColumns = "schoolIdMap")
},
indices = {@Index("schoolIdMap")}
)
public class Location {
@PrimaryKey
Long locationId;
Long schoolIdMap;
String locationName;
float x1;
float y1;
float x2;
float y2;
// etc
public Location(){}
@Ignore
public Location(String locationName,long schoolId, float x1, float y1, float x2, float y2) {
this.locationName = locationName;
this.schoolIdMap = schoolId;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
.... getters and setters
}
- 为了使演示更易于阅读,已为 Location 命名。
为了满足用它的孩子检索父母的需求,使用了以下 POJO:-
SchoolWithLocations
public class SchoolWithLocations {
@Embedded
School school;
@Relation(entity = Location.class,parentColumn = "schoolId",entityColumn = "schoolIdMap")
List<Location> locationList;
}
StateWithSchoolsWithLocations
public class StateWithSchoolsWithLocations {
@Embedded
State state;
@Relation(entity = School.class, parentColumn = "stateId",entityColumn = "stateIdMap")
List<SchoolWithLocations> schoolWithLocationsList;
}
A Dao AllDao与一些常见有用的 Dao 的:-
@Dao
interface AllDao {
@Insert
long insert(State state);
@Insert
long[] insert(State...states);
@Insert
long insert(Location location);
@Insert
long[] insert(Location...locations);
@Insert
long insert(School school);
@Insert
long[] insert(School...schools);
@Query("SELECT * FROM State")
List<State> getAllStates();
@Query("SELECT * FROM State WHERE stateId=:stateId")
State getStateById(long stateId);
@Query("SELECT * FROM Location")
List<Location> getAllLocations();
@Query("SELECT * FROM Location WHERE locationId=:locationId")
Location getLocationById(long locationId);
@Query("SELECT * FROM Location WHERE x1=:x1 AND y1=:y1 AND x2=:x2 AND y2=:y2")
Location getLocationByCoords(float x1,float y1,float x2,float y2);
@Query("SELECT * FROM School")
List<School> getAllSchools();
@Transaction
@Query("SELECT * FROM State")
List<StateWithSchoolsWithLocations> getStateWithSchoolsAndLocations();
@Transaction
@Query("SELECT * FROM State WHERE stateId=:stateId")
List<StateWithSchoolsWithLocations> getStateByIdWithSchoolsAndLocations(long stateId);
}
一个数据库类TheDatabase
@Database(entities = {State.class,Location.class,School.class},exportSchema = false,version = 1)
abstract class TheDatabase extends RoomDatabase {
abstract AllDao getAllDao();
private static volatile TheDatabase instance;
public static TheDatabase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(
context,
TheDatabase.class,
"state.db"
)
.allowMainThreadQueries()
.build();
}
return instance;
}
}
最后是演示活动(在主线程上运行):-
public class MainActivity extends AppCompatActivity {
TheDatabase db;
AllDao dao;
static final String TAG = "StateINFO";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Instantiate Database and get dao
db = TheDatabase.getInstance(this);
dao = db.getAllDao();
// Add 3 states
long s1Id = dao.insert(new State("State1"));
long s2Id = dao.insert(new State("State2"));
// Add 2 Schools (in State1)
long sc1 = dao.insert(new School("School1 in State1",s1Id));
long sc2 = dao.insert(new School("School2 in State1",s1Id));
// Add 4 Locations
long l1Id = dao.insert(new Location("Loc1",sc1,1f,1f,2f,2f));
long l2Id = dao.insert(new Location("Loc2",sc1,2f,2f,3f,3f));
long l3Id = dao.insert(new Location("Loc3",sc1,3f,3f,4f,4f));
long l4Id = dao.insert(new Location("Loc4",sc2,4f,4f,5f,5f));
// Get Everything via State
for (StateWithSchoolsWithLocations swswl: dao.getStateWithSchoolsAndLocations() ) {
Log.d(TAG,"State is " + swswl.state.stateName);
for (SchoolWithLocations s: swswl.schoolWithLocationsList) {
Log.d(TAG,"\tSchool is " + s.school.schoolName);
for (Location l: s.locationList) {
Log.d(TAG,"\t\tLocation is " + l.locationName + " XYvalues are X1=" + l.x1 + " Y1=" + l.y2 + " X2=" + l.x2 + " Y2=" + l.y2);
}
}
}
}
}
结果
可以看出,检索所有位置和 x1..Y2 值很容易。运行上述日志时,日志包括:-
2021-06-13 08:53:40.748 D/StateINFO: State is State1
2021-06-13 08:53:40.748 D/StateINFO: School is School1 in State1
2021-06-13 08:53:40.748 D/StateINFO: Location is Loc1 XYvalues are X1=1.0 Y1=2.0 X2=2.0 Y2=2.0
2021-06-13 08:53:40.748 D/StateINFO: Location is Loc2 XYvalues are X1=2.0 Y1=3.0 X2=3.0 Y2=3.0
2021-06-13 08:53:40.748 D/StateINFO: Location is Loc3 XYvalues are X1=3.0 Y1=4.0 X2=4.0 Y2=4.0
2021-06-13 08:53:40.748 D/StateINFO: School is School2 in State1
2021-06-13 08:53:40.748 D/StateINFO: Location is Loc4 XYvalues are X1=4.0 Y1=5.0 X2=5.0 Y2=5.0
2021-06-13 08:53:40.748 D/StateINFO: State is State2
我想要实现,而不是创建一个新的表/实体类,除非我没有其他选择。
以上内容是否可用于进行适当的更正以保留当前表格是您必须确定的。
额外的 HashMaps
添加到SchoolWithLocations POJO 的方法:-
public HashMap<String,Float> getLocationsAsHashMap() {
HashMap<String,Float> rv = new HashMap<>();
for (Location l: locationList) {
String basekey = this.getClass().getSimpleName() + (rv.size() + 1);
rv.put(basekey+"x1",l.x1);
rv.put(basekey+ "y1",l.y1);
rv.put(basekey+"x2",l.x2);
rv.put(basekey+"y2",l.y2);
}
return rv;
}
添加到学校的方法
public HashMap<String,Float> getLocationsAsHashMap(AllDao dao) {
HashMap<String,Float> rv = new HashMap<>();
for(Location l: dao.getLocationsBySchool(schoolId)) {
String basekey = this.getClass().getSimpleName() + (rv.size() + 1);
rv.put(basekey+"x1",l.x1);
rv.put(basekey+ "y1",l.y1);
rv.put(basekey+"x2",l.x2);
rv.put(basekey+"y2",l.y2);
}
return rv;
}
- 注意细微的差异。由于 School 对象不包含位置,因此需要从数据库中检索这些位置。因此,它需要一个 AllDao 的实例,因为它使用一个 dao 来获取位置。
全道
AllDao 中添加了以下内容,以方便获取适用于学校的位置:-
@Query("SELECT * FROM location WHERE schoolIdMap=:schoolId")
List<Location> getLocationsBySchool(long schoolId);
遍历检索到的StateWithSchoolsWithLocations列表的修正循环
// Get Everything via State
HashMap<String,Float> locations = new HashMap<>(); //<<<<< ADDED
HashMap<String,Float> locationsFromSchool = new HashMap<>(); //<<<<<ADDDED
for (StateWithSchoolsWithLocations swswl: dao.getStateWithSchoolsAndLocations() ) {
Log.d(TAG,"State is " + swswl.state.stateName);
for (SchoolWithLocations s: swswl.schoolWithLocationsList) {
Log.d(TAG,"\tSchool is " + s.school.schoolName);
for (Location l: s.locationList) {
Log.d(TAG,"\t\tLocation is " + l.locationName + " XYvalues are X1=" + l.x1 + " Y1=" + l.y2 + " X2=" + l.x2 + " Y2=" + l.y2);
}
/* ADDED get HashMap of Locations */
locations = s.getLocationsAsHashMap();
/* OR */
locationsFromSchool = s.school.getLocationsAsHashMap(dao);
Float value = 99.99999F; //<<<<< ADDED for setting a breakpoint
}
}
修订守则的结果
断点已添加到 LineFloat value = 99.99999F
并在调试模式下运行。
当断点第一次被击中(第一个 StateWithSchoolsAndWithLocations)时,调试窗口是:-

第二个断点:-
