我正在创建一个需要两种类型用户的网站:学生和提供者。在传统的java设置中,我将创建一个用户类(或接口),然后创建两个继承自用户的类。这是scala中最好的课程,使用“extends”和“with”修饰符?如果这确实是最好的方式(我怀疑它是),那么在数据库中映射这个的最佳方法是什么?最好保留一个“类型”列,然后将其设置为一个或另一个?
第二个问题是如何使用视图。根据用户的类型,显示将是非常不同的,因此我认为将涉及一些严重的路由逻辑或至少在视图中内置到片段中的逻辑。
我想最重要的问题是:是否有一种“首选”方式可以做到这一点(比如铁轨中的食谱或其他类似的东西),或者我是不是自己出去了?
由于
答案 0 :(得分:8)
如果这确实是最好的方式(我怀疑它是),那么在数据库中映射这个的最佳方法是什么?最好保留一个“类型”列,然后将其设置为一个或另一个?
在给定方案的情况下,我认为没有明确的“最好的方法”来设计数据库结构。教科书答案为database normalization和DRY。
例如,一种方法是创建包含两种类型用户的User表,仅存储公共属性,并创建具有User表外键的Student表和Provider表以及专用属性(如果有)。这可能不是传统的关系数据库人所推荐的,但它更贴近OO继承模型。
像你所说的另一种方法是创建一个“UserType”字段并将这两种类型的用户存储到User表中。这很简单,但是你错过了利用关系数据库的引用完整性的机会。例如,如果您要创建仅针对Student的子表,例如Homework,如果学生和提供者都位于User表中,则不能简单地将外键设置为StudentID。
如果您正在使用对象关系映射框架,可能最简单的方法是将对象世界海峡中您想要的内容准确地映射到数据库中,该数据库将具有Student表和Provider表,并表达了通用性。两个作为Scala方面的特征。
我找到了Lift cheat sheet:
定义模型
提升O-R映射模型是基于具有字段的类来定义的。
class WikiEntry extends KeyedMapper[Long, WikiEntry] {
def getSingleton = WikiEntry // what's the "meta" object
def primaryKeyField = id
// the primary key
object id extends MappedLongIndex(this)
// the name of the entry
object name extends MappedString(this, 32) {
override def dbIndexed_? = true // indexed in the DB
}
object owner extends MappedLongForeignKey(this, User)
// the text of the entry
object entry extends MappedTextarea(this, 8192) {
override def textareaRows = 10
override def textareaCols = 50
}
}
大卫波拉克写道:
你正在寻找一些Scala魔法:
trait Posting[MyType <: Mapper[MyType]] { // Defines some common fields for posted user content
self: MyType =>
def primaryKeyField = id
object id extends MappedLongIndex(this)
object creator extends MappedLongForeignKey(this, User)
object createdAt extends MappedLong(this) {
override def defaultValue = System.currentTimeMillis
}
}
class FooPosting extends KeyedMapper[FooPosting] with Posting[MyType]