콘텐츠로 이동

2023 03 15

2023-03-15

Scala Slick

  • 참고: https://www.youtube.com/watch?v=Uwqf_8nwYN4&list=PLmtsMNDRU0BxIFCdPgm77Dx5Ll9SQ76pR
  • 1. Setup and CRUD Operations - *는 테이블 <-> Case Class 어떻게 할 것인지
    object Connection {
      val db = Database.forConfig("postgres")
    }
    
    case class Movie(id: Long, name: String, releaseDate: LocalDate, lengthInMin: Int)
    
    object SlickTables {
      import slick.jdbc.PostgresProfile.api._
    
      class MovieTable(tag: Tag) extends Table[Movie](tag, Some("movies"), "Movie") {
        def id = column[Long]("movie_id", O.PrimaryKey, O.AutoInc)
        def name = column[String]("name")
        def releaseDate = column[LocalDate]("release_date")
        def lengthInMin = column[Int]("length_in_min")
    
        // * Mapping function to the case class
        // tupled : Tuple => Case Class
        // unapply: Case Class => Tuple
        override def * = (id, name, releaseDate, lengthInMin) <> (Movie.tupled, Movie.unapply)
      }
    
      lazy val movieTable = TableQuery[MovieTable]
    }
    
    object PrivateExecutionContext {
      val executor = Executors.newFixedThreadPool(4)
      implicit val ec: ExecutionContext = ExecutionContext.fromExecutorService(executor)
    }
    
    object Main {
      import slick.jdbc.PostgresProfile.api._
      import PrivateExecutionContext._
    
      val showshankRedemption = Movie(1L, "The Shawshank Redemption", LocalDate.of(1994, 9, 23), 162)
      val theMatrix = Movie(2L, "The Matrix", LocalDate.of(1999, 3, 11), 134)
    
      def demoInsertMovie(): Unit = {
        val queryDescription = SlickTables.movieTable += theMatrix
        val futureId: Future[Int] = Connection.db.run(queryDescription)
    
        futureId.onComplete {
          case Success(newMovieId) => println(s"Query was successful, new id is $newMovieId")
          case Failure(ex) => println(s"Query Failed : ${ex}")
        }
        Thread.sleep(10000)
      }
    
      def demoReadAllMovies(): Unit = {
        // select * from movie
        val resultFuture: Future[Seq[Movie]] = Connection.db.run(SlickTables.movieTable.result)
        resultFuture.onComplete {
          case Success(movies) => println(s"Fetched: ${movies.mkString(",")}")
          case Failure(ex) => println(s"Fetching failed: ${ex}")
        }
        Thread.sleep(10000)
      }
    
      def demoReadSomeMovies(): Unit = {
        // select * from movie where name like %Matrix%
        val resultFuture: Future[Seq[Movie]] = Connection.db.run(
          SlickTables.movieTable.filter(_name.like("%Matrix%")).result
        )
        resultFuture.onComplete {
          case Success(movies) => println(s"Fetched: ${movies.mkString(",")}")
          case Failure(ex) => println(s"Fetching failed: ${ex}")
        }
        Thread.sleep(10000)
      }
    
      def demoUpdate(): Unit = {
        val queryDescriptor = SlickTables.movieTable.filter(_.id === 1L).update(showshankRedemption.copy(lengthInMin = 150))
        val futureId: Future[Int] = Connection.db.run(queryDescriptor)
    
        futureId.onComplete {
          case Success(newMovieId) => println(s"Query was successful, new id is $newMovieId")
          case Failure(ex) => println(s"Query Failed : ${ex}")
        }
        Thread.sleep(10000)
      }
    
      def demoDelete(): Unit = {
        Connection.db.run(SlickTables.movieTable.filter(_name.like("%Matrix%")).delete)
      }
    }