加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

数据库 – 在Scala-Slick中键入外键的投影

发布时间:2020-12-12 07:05:23 所属栏目:MsSql教程 来源:网络整理
导读:我正在使用 Scala,而且是Play and Slick的新手.我开始阻止一个简单的数据库结构,我不确定处理外键和投影的正确方法.在页面底部的示例中,它目前无法编译,因为无法直接提取ForeignKey,因此将查询结果提升到我的类型(这基本上是sans方法和其他构造函数)的正确方
我正在使用 Scala,而且是Play and Slick的新手.我开始阻止一个简单的数据库结构,我不确定处理外键和投影的正确方法.在页面底部的示例中,它目前无法编译,因为无法直接提取ForeignKey,因此将查询结果提升到我的类型(这基本上是sans方法和其他构造函数)的正确方法是什么:
case class UserCompanyPermission(pk: UUID,company: Company,user: User,accessLevel: CompanyPermissionLevel)

要么我想有型投影返回UserCompanyPermission,否则有办法来包装都进入和流出的DAO方法,以便从外面我只是通过我的斯卡拉几种类型,基本上我想确保我的生意逻辑完全与状态分离,以便更容易测试,因此能够将所有表特定限制在此存储包中.是他们的包装方式,还是我在DAO对象中编写的每个方法都需要自己进行转换?

trait CompaniesComponent { this: UsersComponent =>
  val Companies: Companies
  val UserCompanyPermissions: UserCompanyPermissions

  implicit val companyPermissionLevelTypeMapper = MappedTypeMapper.base[CompanyPermissionLevel.Value,Int](
    { level => level.id },{ id => CompanyPermissionLevel(id) }
  )

  class Companies extends Table[Company]("Company") {
    def pk = column[UUID]("pk",O.PrimaryKey)
    def subdomain = column[String]("subdomain",O.NotNull)
    def name = column[String]("name",O.NotNull)

    def * = pk ~ subdomain ~ name <> (Company.apply _,Company.unapply _)
  }


  class UserCompanyPermissions extends Table[UserCompanyPermission]("UserCompanyPermission") {

    def pk = column[UUID]("pk",O.PrimaryKey)
    def company_pk = column[UUID]("company_pk",O.NotNull)
    def user_pk = column[UUID]("user_pk",O.NotNull)
    def accessLevel = column[CompanyPermissionLevel.Value]("access_level",O.NotNull)

    def company = foreignKey("company_pk",company_pk,Companies)(_.pk)
    def user = foreignKey("user_pk",user_pk,Users)(_.pk)

    def * = pk ~ company ~ user ~ accessLevel <> (UserCompanyPermission.apply _,UserCompanyPermission.unapply _)
  }

}


object Companies extends DAO {
  def insert(company: Company)(implicit session: Session) {
    Companies.insert(company)
  }
}

object UserCompanyPermissions extends DAO {
  def insert(perm: UserCompanyPermission)(implicit session: Session) {
    UserCompanyPermissions.insert(perm)
  }
}

解决方法

使用Slick的推荐方法是永远不会嵌套包含行值的case类.它们应该只包含实际的列,而不是任何相关的对象,因为它会硬编码它们必须加载在一起(除非你在引擎盖下做一些神奇的延迟加载,这使得使用和实现复杂).相反,您编写查询,使用元组将您现在需要的特定数据的值关联起来.
// FYI
case class UserCompanyPermission( pk: UUID,company_pk: UUID,user_pk: UUID,accessLevel: CompanyPermissionLevel.Value )

// associating data in an ad-hoc,not hard-coded way
for( ucp <- Query(UserCompanyPermissions).filter(_.accessLevel === LevelOne);
     c <- ucp.company;
     u <- ucp.user
) yield (u,c)

在这里我们加载u和c,因为我们这样说.我们本可以只加载u或c或c和ucp等等.它在我们的行类中没有硬编码.

在架构方面,您可以在Scala Days 2013演讲和Scala Exchange 2013演讲中找到帮助. http://slick.typesafe.com/docs/

作为一个侧节点,我建议使用case对象的密封特征而不是Enumerationfor CompanyPermissionLevel.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读