2014-04-28 3 views
6

저는 COMMON CRUD 및 다른 종류의 작업에 일반적인 특성을 구현하는 방법을 살펴 보았습니다. thisthis을보고 지정된 메서드가 잘 작동하고 있습니다. 내가 처음 링크를 따라, 지금까지 시도 무엇Slick 2.0 일반 CRUD 작업

object CampaignModel { 
    val campaigns = TableQuery[Campaign] 

    def insert(campaign: CampaignRow)(implicit s: Session) = { 
    campaigns.insert(campaign) 
    } 
} 

했다 : 내가하고 싶은 무엇

가 삽입을위한 일반적인 방법이다, 내 수업은 순간 (비 일반적인 구현)에서 다음과 같습니다 이 (일반적인 구현) : 나는 insert 방법을 검사 할 때

trait PostgresGeneric[T <: Table[A], A] { 
    val tableReference = TableQuery[T] 

    def insertGeneric(row: ? What type goes here ?)(implicit s: Session) = tableReference.insert(row) 

} 

T#TableElementType해야 올바른 유형처럼 보이지만 내 지식은 아주 기본이고 나는이 유형의 주위에 내 머리를 정리 할 수없는, 나는 T 시도 A이고 컴파일러는 classtype이 특성에 부합하지 않는다고 말합니다.

import scala.slick.driver.PostgresDriver 
import scala.slick.driver.PostgresDriver.simple._ 
import path.to.RichTable 

trait PostgresGeneric[T <: RichTable[A], A] { 

    val tableReference: TableQuery[T] 

    def insert(row: T#TableElementType)(implicit s: Session) = 
    tableReference.insert(row) 

    def insertAndGetId(row: T#TableElementType)(implicit s: Session) = 
    (tableReference returning tableReference.map(_.id)) += row 

    def deleteById(id: Long)(implicit s: Session): Boolean = 
    tableReference.filter(_.id === id).delete == 1 

    def updateById(id: Long, row: T#TableElementType)(implicit s: Session): Boolean = 
    tableReference.filter(_.id === id).update(row) == 1 

    def selectById(id: Long)(implicit s: Session): Option[T#TableElementType] = 
    tableReference.filter(_.id === id).firstOption 

    def existsById(id: Long)(implicit s: Session): Boolean = { 
    (for { 
     row <- tableReference 
     if row.id === id 
    } yield row).firstOption.isDefined 
    } 
} 

RichTable이 추상 클래스는 다음과 같습니다

다른 정보를 정기적으로는, 테이블이 나는 그것이 작동하도록 관리하는 매끄러운 테이블 생성 도구

case class CampaignRow(id: Long, name: Option[String]) 

/** Table description of table campaign. Objects of this class serve as prototypes for rows in queries. */ 
class Campaign(tag: Tag) extends Table[CampaignRow](tag, "campaign") { 
    def * = (id, name) <>(CampaignRow.tupled, CampaignRow.unapply) 

    /** Maps whole row to an option. Useful for outer joins. */ 
    def ? = (id.?, name).shaped.<>({ 
    r => import r._; _1.map(_ => CampaignRow.tupled((_1.get, _2))) 
    }, (_: Any) => throw new Exception("Inserting into ? projection not supported.")) 

    /** Database column id AutoInc, PrimaryKey */ 
    val id: Column[Long] = column[Long]("id", O.AutoInc, O.PrimaryKey) 
    /** Database column name */ 
    val name: Column[Option[String]] = column[Option[String]]("name") 
} 

답변

11

생성됩니다, 이건 내 일반적인 특성이다 id 필드를 사용하면 상한 제한 조건을 사용하여 T#TableElementType의 id 필드를 얻는 것이 유용합니다 (자세한 내용은 this 참조).

import scala.slick.driver.PostgresDriver.simple._ 
import scala.slick.jdbc.{GetResult => GR} 

abstract class RichTable[T](tag: Tag, name: String) extends Table[T](tag, name) { 
    val id: Column[Long] = column[Long]("id", O.PrimaryKey, O.AutoInc) 
} 
그리고 캠페인 테이블은 이제 다음과 같습니다

object CampaignModel extends PostgresGeneric[Campaign, CampaignRow] { 

    override val tableReference: PostgresDriver.simple.TableQuery[Tables.Campaign] = 
    TableQuery[Campaign] 

    def insertCampaign(row: CampaignRow) = { 
    insert(CampaignRow(0, "test")) 
    } 
} 
:
import scala.slick.driver.PostgresDriver.simple._ 
import scala.slick.jdbc.{GetResult => GR} 
import scala.slick.lifted.TableQuery 

case class CampaignRow(id: Long, name: Option[String]) 

class Campaign(tag: Tag) extends RichTable[CampaignRow](tag, "campaign") { 
    def * = (id, name) <>(CampaignRow.tupled, CampaignRow.unapply) 

    def ? = (id.?, name).shaped.<>({ 
    r => import r._; _1.map(_ => CampaignRow.tupled((_1.get, _2))) 
    }, (_: Any) => throw new Exception("Inserting into ? projection not supported.")) 

    override val id: Column[Long] = column[Long]("id", O.AutoInc, O.PrimaryKey) 
    val name: Column[Option[String]] = column[Option[String]]("name") 
} 

일반 특성을 구현하는 모델은 다음과 같습니다