如果你是说没有
@Relation
与其没有关系,不如考虑以下因素:-
data class UserEvents(
@Embedded
val user: User,
@Embedded
val university: University,
@Embedded
val semester: Semester,
@Embedded
val course: Course
)
从下面的演示/示例中,我们将产生以下内容:-
2021-11-06 13:25:28.960 D/EVENTS_1: Event is English part1: Semester is Semester 1 2022, from 2022-01-17 to 2022-03-10:Univeristy is Cambridge:User is Jane
2021-11-06 13:25:28.960 D/EVENTS_1: Event is English part2: Semester is Semester 2 2022, from 2022-03-24 to 2022-06-14:Univeristy is Cambridge:User is Jane
2021-11-06 13:25:28.960 D/EVENTS_1: Event is English part 1: Semester is Semester 1, from 2022-01-15 to 2022-03-31:Univeristy is Oxford:User is Jane
2021-11-06 13:25:28.965 D/EVENTS_1: Event is Mathematcis part2: Semester is Semester 3 2022, from 2022-06-24 to 2022-09-15:Univeristy is Cambridge:User is Fred
2021-11-06 13:25:28.965 D/EVENTS_1: Event is Mathematcis part2: Semester is Semester 4 2022, from 2022-10-03 to 2022-12-15:Univeristy is Cambridge:User is Fred
-
注意Jane的UserEvents是在Jane登录时提取的,Fred的UserEvents是在Fred登录时提取的。
所以除了
用户事件
POJO有@EntityClass:-
使用者
:-
@Entity
data class User (
@PrimaryKey
val userId: Long? = null,
val userName: String,
val userPassword: String,
val userOtherData: String
)
大学
@Entity(
indices = [
Index(value = ["universityName"], unique = true)
]
)
data class University(
@PrimaryKey
val universityId: Long?=null,
val universityName: String,
val universityOtherData: String
)
学期
@Entity
data class Semester(
@PrimaryKey
val semesterId: Long?=null,
val semesterName: String,
val semesterStartDate: String,
val semesterEndDate: String,
val semesterUniversityMap: Long
)
课程
@Entity
data class Course(
@PrimaryKey
val courseId: Long?=null,
val courseName: String,
val courseSemesterMap: Long
)
用户课程地图
注意到提供的关系是多方面的,但这可以促进1-many。
@Entity(
primaryKeys = ["userCourseMapUserId","userCourseMapCourseId"],
indices = [
Index(value = ["userCourseMapCourseId"]
)
])
data class UserCourseMap(
val userCourseMapUserId: Long,
val userCourseMapCourseId: Long
)
上述设计并未将大学、学期或课程指定给特定用户。它们是共享的,例如,用户1添加Oxford uni,然后用户2尝试它不是重复的,但已经存在,等等。
只有用户注册的课程,因此学期,因此大学是特定于用户的。
所有这些类都需要一个单独的Dao还是一个UserDao
奥尔道
:-
@Dao
abstract class AllDao {
@Insert(onConflict = IGNORE)
abstract fun insert(user: User): Long
@Insert(onConflict = IGNORE)
abstract fun insert(university: University): Long
@Insert(onConflict = IGNORE)
abstract fun insert(semester: Semester): Long
@Insert(onConflict = IGNORE)
abstract fun insert(course: Course): Long
@Insert(onConflict = IGNORE)
abstract fun insert(userCourseMap: UserCourseMap): Long
@Query("SELECT universityId FROM University WHERE universityName=:universityName")
abstract fun getUniversityIdByName(universityName: String): Long
@Query("SELECT semesterId FROM semester WHERE semesterName=:semesterName AND semesterUniversityMap=:universityId")
abstract fun getSemesterByNameAndUniversityId(semesterName: String, universityId: Long): Long
@Query("SELECT courseId FROM course WHERE courseName=:courseName AND courseSemesterMap=:semesterId")
abstract fun getCourseByCourseNameAndSemesterId(courseName: String, semesterId: Long): Long
@Query("SELECT coalesce(max(userid),-1) FROM user WHERE userName=:userName AND userPassword =:userPassword")
abstract fun userLogin(userName: String, userPassword: String): Long
@Query("SELECT * FROM usercoursemap " +
"JOIN User on userCourseMapUserId = userId " +
"JOIN course on userCourseMapCourseId = courseId " +
"JOIN semester ON courseSemesterMap = semesterId " +
"JOIN university ON semesterUniversityMap = universityId " +
"WHERE userId=:userId")
abstract fun getUserEvents(userId: Long): List<UserEvents>
}
如何将用户数据彼此分离?
见上图
用户课程地图
还有
getUserEvents
刀
-
如果对以上内容感到满意,我建议考虑定义外键约束,以加强引用完整性,但为了简洁和降低理解的复杂性,我省略了它们。
所以用一个非常典型的@数据库
数据库
:-
@Database(entities = [
User::class,University::class,Semester::class,Course::class,UserCourseMap::class,
version = 1)
@TypeConverters(DateTimeConverter::class)
abstract class TheDatabase: RoomDatabase() {
abstract fun getAllDao(): AllDao
companion object {
@Volatile
private var instance: TheDatabase? = null
fun getInstance(context: Context): TheDatabase {
if (instance == null) {
instance = Room.databaseBuilder(context,TheDatabase::class.java,"thedatabase.db")
.allowMainThreadQueries()
.build()
}
return instance as TheDatabase
}
}
}
-
一个例外是为了简洁
.allowMainThreadQueries
已被利用。
最后,在一个演示中(产生了上面的输出)将其全部放在一起
主要活动
:-
class MainActivity : AppCompatActivity() {
lateinit var db: TheDatabase
lateinit var dao: AllDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = TheDatabase.getInstance(this)
dao = db.getAllDao()
var currentUserId: Long = -1 /* no user not logged in */
/* Add a couple of users */
dao.insert(User(userName = "Fred",userPassword = "passwordforfred", userOtherData = "blah"))
dao.insert(User(userName = "Jane", userPassword = "passwordforjane", userOtherData = "blah"))
/* add some universities, semesters and courses all 3 are globally accessible */
val yaleid = dao.insert(University(universityName = "Yale", universityOtherData = "blah"))
val cambridgeid = dao.insert(University(universityName = "Cambridge", universityOtherData = "blah"))
val semester1yale = dao.insert(Semester(semesterName = "Semester 1 2022", semesterStartDate = "2022-01-23", semesterEndDate = "2022-04-07", semesterUniversityMap = yaleid))
val semester2yale = dao.insert(Semester(semesterName = "Semester 2 2022", semesterStartDate = "2022-04-17", semesterEndDate = "2022-07-01", semesterUniversityMap = yaleid))
val semester3yale = dao.insert(Semester(semesterName = "Semester 3 2022", semesterStartDate = "2022-07-28", semesterEndDate = "2022-10-01", semesterUniversityMap = yaleid))
val semester4yale = dao.insert(Semester(semesterName = "Semester 4 2022", semesterStartDate = "2022-10-25", semesterEndDate = "2022-12-18", semesterUniversityMap = yaleid))
val semester1camb = dao.insert(Semester(semesterName = "Semester 1 2022", semesterStartDate = "2022-01-17", semesterEndDate = "2022-03-10", semesterUniversityMap = cambridgeid))
val semester2camb = dao.insert(Semester(semesterName = "Semester 2 2022", semesterStartDate = "2022-03-24", semesterEndDate = "2022-06-14", semesterUniversityMap = cambridgeid))
val semester3camb = dao.insert(Semester(semesterName = "Semester 3 2022", semesterStartDate = "2022-06-24", semesterEndDate = "2022-09-15", semesterUniversityMap = cambridgeid))
val semester4camb = dao.insert(Semester(semesterName = "Semester 4 2022", semesterStartDate = "2022-10-03", semesterEndDate = "2022-12-15", semesterUniversityMap = cambridgeid))
val coursecambengp1 = dao.insert(Course(courseName = "English part1",courseSemesterMap = semester1camb))
val coursecambengp2 = dao.insert(Course(courseName = "English part2",courseSemesterMap = semester2camb))
val coursecambengp3 = dao.insert(Course(courseName = "English part2",courseSemesterMap = semester3camb))
val coursecambengp4 = dao.insert(Course(courseName = "English part2",courseSemesterMap = semester4camb))
val coursecambmthp1 = dao.insert(Course(courseName = "Mathematics part1",courseSemesterMap = semester1camb))
val coursecambmthp2 = dao.insert(Course(courseName = "Mathematics part2",courseSemesterMap = semester2camb))
val coursecambmthp3 = dao.insert(Course(courseName = "Mathematcis part2",courseSemesterMap = semester3camb))
val coursecambmthp4 = dao.insert(Course(courseName = "Mathematcis part2",courseSemesterMap = semester4camb))
/* Logon in eventually to Jane, after 2 failed login attempts */
currentUserId = dao.userLogin("Not a known user","obviously not a valid password")
if (currentUserId < 1) {
/* try again */
currentUserId = dao.userLogin("Fred","wrongpassword")
if (currentUserId < 1) {
currentUserId = dao.userLogin("Jane","passwordforjane")
}
}
if (currentUserId > 0) {
/* all in one add of English part 1 - semster 1 at Oxford (i.e. bar the user all are added in one go) */
dao.insert(
UserCourseMap(
userCourseMapUserId = currentUserId,
userCourseMapCourseId =
dao.insert(
Course(
courseName = "English part 1",
courseSemesterMap = dao.insert(
Semester(
semesterName = "Semester 1",
semesterStartDate = "2022-01-15",
semesterEndDate = "2022-03-31",
semesterUniversityMap = dao.insert(
University(
universityName = "Oxford",
universityOtherData = "blah"
)
)
)
)
)
)
)
)
/* add event (mapping course to user and this implicitly adding semester and uni) to pre-existing */
dao.insert(UserCourseMap(userCourseMapUserId = currentUserId,userCourseMapCourseId = coursecambengp1))
dao.insert(UserCourseMap(userCourseMapCourseId = currentUserId,userCourseMapUserId = coursecambengp2))
}
/* get the events for Jane */
for(ue: UserEvents in dao.getUserEvents(currentUserId)) {
Log.d("EVENTS_1",
"Event is ${ue.course.courseName}: " +
"Semester is ${ue.semester.semesterName}, from ${ue.semester.semesterStartDate} to ${ue.semester.semesterEndDate}:" +
"Univeristy is ${ue.university.universityName}:" +
"User is ${ue.user.userName}")
}
/* SWITCH TO USER FRED */
currentUserId = dao.userLogin("Fred","passwordforfred")
if (currentUserId > 0) {
dao.insert(UserCourseMap(userCourseMapUserId = currentUserId,userCourseMapCourseId = coursecambmthp3))
dao.insert(UserCourseMap(userCourseMapUserId = currentUserId,userCourseMapCourseId = coursecambmthp4))
}
/* Get the events for Fred */
for(ue: UserEvents in dao.getUserEvents(currentUserId)) {
Log.d("EVENTS_1",
"Event is ${ue.course.courseName}: " +
"Semester is ${ue.semester.semesterName}, from ${ue.semester.semesterStartDate} to ${ue.semester.semesterEndDate}:" +
"Univeristy is ${ue.university.universityName}:" +
"User is ${ue.user.userName}")
}
}
}