복붙노트

[SCALA] 슬릭 2.0 일반 CRUD 작업

SCALA

슬릭 2.0 일반 CRUD 작업

나는 공유지 CRUD 및 운영의 다른 종류의 일반적인 특성을 구현하는 방법에 주위를 찾고 있었어요, 나는이이 쳐다 보면서 지정 방법은 잘 작동하고 있습니다.

내가하고 싶은 것은 삽입을위한 일반적인 방법이다, 순간 (비 일반적인 구현)에서이 같은 내 클래스 외모 :

object CampaignModel {
  val campaigns = TableQuery[Campaign]

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

지금까지 시도 무엇 첫 번째 링크를,이 (일반적인 구현)했다 :

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가 일치하지 않는 것을 말한다 형질 하나입니다.

다른 정보를 정기적으로이 테이블은 매끄러운 테이블 생성 도구를 사용하여 생성됩니다

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")
}

해결법

  1. ==============================

    1.나는 그것이 작동하도록 관리, 이쪽은 내 일반적인 특성이다 :

    나는 그것이 작동하도록 관리, 이쪽은 내 일반적인 특성이다 :

    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는 id 필드와 추상 클래스이고,이, 상한 제약과 T # TableElementType (자세한 정보를 원하시면,이 참조)의 id 필드를 얻기 위해 유용합니다 :

    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)
    }
    

    그리고 캠페인 테이블은 이제 다음과 같습니다 :

    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")
    }
    

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

     object CampaignModel extends PostgresGeneric[Campaign, CampaignRow] {
    
       override val tableReference: PostgresDriver.simple.TableQuery[Tables.Campaign] = 
         TableQuery[Campaign]
    
       def insertCampaign(row: CampaignRow) = {
         insert(CampaignRow(0, "test"))
       }
     }
    
  2. from https://stackoverflow.com/questions/23345303/slick-2-0-generic-crud-operations by cc-by-sa and MIT license