首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala反射与Squeryl

Scala反射与Squeryl
EN

Stack Overflow用户
提问于 2013-08-23 15:59:59
回答 1查看 208关注 0票数 1

我正在使用Scala、Scalatra和Squeryl进行我的第一个实质性项目,并且遇到了以下问题:我想为我的DAOs创建一个抽象基类,它提供了一个基本CRUD操作的简单实现(创建、读取、更新、删除),所以我需要一种方法,让这个抽象基类知道要引用哪个表。

使用Squeryl,您可以将数据类映射到扩展squeryl.Schema的单例对象中的实际表,而DAO通常是每个类的伴生对象。

我想出了以下使用类型标记的解决方案:

首先,摘录所有DAO将继承的基类(注意: DBRecord是Squeryl's KeyedEntity的一个子类):

代码语言:javascript
复制
abstract class CrudOps[S <: DBRecord](implicit tt: TypeTag[S]) {

  def create(item: S)= {
    inTransaction{
      val result = ATSchema.recordTable.insert(item)
    }
  }

接下来,在recordTable中使用ATSchema函数:

代码语言:javascript
复制
object ATSchema extends Schema {
  val users = table[User]
  def recordTable[T <: DBRecord](implicit tt: TypeTag[T]): Table[T] = tt.tpe match {
    case t if t =:= typeOf[User] => users.asInstanceOf[Table[T]]
    //...other table types go here
    case _ => throw new IllegalArgumentException("Unknown DBRecord type")
  }
}

现在,这是可行的,我有几个表和CrudOps抓住正确的一个,并做它的东西。但是有一点我还不理解(我对Scala还是很陌生的):为什么我需要将表recordTable()中的表放到TableT中呢?如果删除.asInstanceOf,则会得到类型不匹配,但用户的类型是TableUser.看来这应该是不必要的。而且,对于应该是一个小问题(也许我在滥用类型系统)来说,这是一个复杂的解决方案,并且将CrudOps耦合到模式(我想避免这种情况),所以我当然愿意接受那些比我有更多Scala和/或Squeryl经验的人的建议。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-06 12:51:11

这不是斯奎里尔的事。据我了解,问题是模式匹配测试是在类型擦除发生后在运行时进行的。Scala能够在TypeTag中保留类型信息并执行运行时检查,但它不能推断类型在编译时是正确的。如果你想尝试一下

代码语言:javascript
复制
case t: ClassTag[User] => users

它要求编译器执行静态检查,您将得到用户类型被删除的警告。您所做的方式应该有效,因为在您验证了类型之后执行强制转换应该很好,而且我认为没有更好的方法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18407145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档