`
sillycat
  • 浏览: 2550789 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Scala DAO(1)Prequel

 
阅读更多

Scala DAO(1)Prequel

Since there are not many codes in the project, I would like to learn it from the source codes. Maybe this way will be good for my scala skill.

>git clone https://github.com/30ss/prequel.git
>cd prequel
>sbt clean update compile eclipse gen-idea

>sbt publish-local
/Users/carl/.ivy2/local/net.noerd/prequel_2.10/0.3.9.1/jars/prequel_2.10.jar 

I placed this project in a spark project to learn it. Because my rest server project is using slick. 

1. Add Dependencies in build.sbt
    "net.noerd"           %%  "prequel"                   % "0.3.9.1",
    "org.scalatest"       %   "scalatest_2.10"            % "1.9.1"   % "test",
    "org.specs2"          %%  "specs2"                    % "1.13"    % "test",
    "mysql"               %   "mysql-connector-java"      % "5.1.24"

>sbt update gen-idea

2. Some Basic Configuration Class
PrequelDAO
package com.sillycat.easysparkserver.dao

import com.typesafe.config._
import net.noerd.prequel.{IsolationLevels, SQLFormatter, DatabaseConfig}
import com.sillycat.easysparkserver.model.ProductsPrequel

object PrequelDAO extends ProductsPrequel{

  val config = ConfigFactory.load()

  val testDatabase: DatabaseConfig = DatabaseConfig(
    driver = config.getString("database.driver"),
    jdbcURL = config.getString("database.url"),
    username = config.getString("database.username"),
    password = config.getString("database.password"),
    sqlFormatter = SQLFormatter.HSQLDBSQLFormatter,
    isolationLevel = IsolationLevels.RepeatableRead
    //There are some other configuration like driver, jdbcURL, username, password, isolationLevel,
    //sqlFormatter, poolConfig
    //to know the detail, just read the source codes in net.noerd.prequel.DatabaseConfig
  )

  def create: Unit = {
    testDatabase transaction { implicit tx =>
      Products.create
    }
  }

  def drop: Unit = {
    testDatabase transaction { implicit tx =>
      Products.drop
    }
  }

}

This class will manage all the table and business class.

Where the SQL hide, here is the mapping and SQL and business class Product, ProductsPrequel
package com.sillycat.easysparkserver.model

import net.noerd.prequel.SQLFormatterImplicits._
import spark.Logging
import org.joda.time.DateTime
import net.noerd.prequel.Transaction


case class Product(id: Option[Long], brand: String, productName: String, createDate: DateTime)

trait ProductsPrequel extends Logging{

   object Products {
     def create(implicit tx: Transaction){
         tx.execute(
           """create table if not exists PRODUCTS (
             |ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
             |BRAND VARCHAR(20),
             |PRODUCT_NAME VARCHAR(20),
             |CREATE_DATE TIMESTAMP(8)
             |)
           """.stripMargin)
         tx.commit()
     }

     def drop(implicit tx: Transaction){
          tx.execute("""drop table if exists PRODUCTS""")
     }

     def insertProduct(item: Product)(implicit tx: Transaction): Long = {
          tx.execute(
            "insert into PRODUCTS( BRAND, PRODUCT_NAME, CREATE_DATE) values ( ?, ?, ? )",
            item.brand, item.productName, item.createDate
          )
          tx.selectLong(
            """
              |SELECT LAST_INSERT_ID()
            """.stripMargin)
     }

     def loadProducts()(implicit tx: Transaction): Seq[Product] = {
         tx.select(
           """select
             |ID,
             |BRAND,
             |PRODUCT_NAME,
             |CREATE_DATE
             |from
             |PRODUCTS
           """.stripMargin){ r =>
           Product(r.nextLong,r.nextString.getOrElse(""),r.nextString.getOrElse(""),new DateTime(r.nextDate.get.getTime))
         }
     }

     def getProduct(id: Long)(implicit tx: Transaction): Option[Product] = {
          tx.selectHeadOption(
            """select
              |ID,
              |BRAND,
              |PRODUCT_NAME,
              |CREATE_DATE
              |from
              |PRODUCTS
              |where
              |ID = ?
            """.stripMargin, id){ r =>
            Product(r.nextLong,r.nextString.getOrElse(""),r.nextString.getOrElse(""),new DateTime(r.nextDate.get.getTime))
          }
     }

     def deleteProduct(id: Long)(implicit tx: Transaction): Unit = {
        tx.execute(
          """
            |delete from PRODUCTS
            |where ID = ?
          """.stripMargin, id)
     }

     def batchInsertProducts(products: Seq[Product])(implicit tx: Transaction): Unit = {
       tx.executeBatch("insert into PRODUCTS( BRAND, PRODUCT_NAME, CREATE_DATE) values ( ?, ?, ? )") { statement =>
           products.foreach { item =>
             statement.executeWith(item.brand,item.productName,item.createDate)
           }
       }
     }
   }
}

The test case class and How we use the DAO layer in ProductPrequelSpec
package com.sillycat.easysparkserver.model

import org.scalatest.FunSuite
import org.specs2.matcher.ShouldMatchers
import org.scalatest.BeforeAndAfterAll
import com.sillycat.easysparkserver.dao.PrequelDAO
import org.joda.time.DateTime

class ProductPrequelSpec extends FunSuite with ShouldMatchers with BeforeAndAfterAll {

  val dao = PrequelDAO

  override def beforeAll() {
    dao.create
  }

  override def afterAll() {
    dao.drop
  }

  test("Database tables are created and dropped") {
    assert("x" === "x")
  }

  test("Verify Products Insert Operation"){
    val item = Product(None,"CK","good things",DateTime.now)
    dao.testDatabase transaction { implicit tx =>
      val id = dao.Products.insertProduct(item)
      assert(id === 1)
    }
  }

  test("Verify Query Products Operation"){
    dao.testDatabase transaction { implicit tx =>
      val items = dao.Products.loadProducts
      assert(items != Nil)
      assert(items.size === 1)
    }
  }

  test("Verify Get Product Operation"){
    dao.testDatabase transaction { implicit tx =>
      val item = dao.Products.getProduct(1)
      assert(item != None)
      assert(item.get.id.get === 1)
      assert(item.get.brand === "CK")
    }
  }

  test("Verify delete Product Operation"){
    dao.testDatabase transaction { implicit tx =>
      dao.Products.deleteProduct(1)
      val item = dao.Products.getProduct(1)
      assert(item === None)
    }
  }

  test("Verify batch Insert Operation"){
    dao.testDatabase transaction { implicit tx =>
      val items = Seq(Product(None,"CK1","good things1",DateTime.now), Product(None,"CK2","good things2",DateTime.now))
      dao.Products.batchInsertProducts(items)
      val return_items = dao.Products.loadProducts()
      assert(return_items.size === 2)
    }
  }

}

Tips
Error Message:
java.lang.NoSuchMethodError: org.hsqldb.DatabaseURL.parseURL 

Solution:
    "org.hsqldb"          %   "hsqldb"                    % "2.2.4" 
I will not spend time on that, I will change my database to use mysql.

Error Message:
I do not know why the executeBatch is not working. I can not run the statement.executeWith 

Solution:
Find the class package net.noerd.prequel.ReusableStatement and change this class from private to null private
Build the source codes myself and publish-local again.


References:
https://github.com/30ss/prequel

Creating table
http://troels.arvin.dk/db/rdbms/#mix-identity

分享到:
评论

相关推荐

    scala-intellij-bin-2021.1.22.zip

    "scala-intellij-bin-2021.1.22.zip" 是一个包含IntelliJ IDEA的Scala插件的压缩包,版本号为2021.1.22,适用于IntelliJ IDEA的2021.1版本。 Scala插件是IntelliJ IDEA为了提升Scala开发体验而设计的,它提供了丰富...

    Scala考试题1

    1. **var、val 和 def 的区别**: - `var` 定义可变变量,可以多次赋值。 - `val` 定义不可变变量,一旦赋值后不能更改。 - `def` 用于定义函数,它不创建任何实例,只定义行为。 2. **trait(特质)和 abstract...

    scala sdk scala-2.12.3

    1. **编译器**:Scala编译器将Scala源代码转换为Java字节码,使得程序可以在JVM上运行。2.12.3版本的编译器支持最新的语言特性,并对错误报告和编译速度进行了改进。 2. **标准库**:Scala的标准库提供了大量的类和...

    scala3 scala3 scala3 scala3 scala3

    例如,`x => x + 1` 可以直接写为 `(x) + 1`。此外,`def` 和 `val` 的定义现在可以合并,使得函数定义更加紧凑。 模式匹配的增强也是Scala3的重要特性。新的`match type`功能允许在类型级别进行模式匹配,增加了...

    scala-intellij-bin-2016.3.1.zip

    在本压缩包"scala-intellij-bin-2016.3.1.zip"中,包含的是IntelliJ IDEA的一个版本,专门针对Scala语言进行了优化。 IntelliJ IDEA是JetBrains公司开发的,它以其智能代码补全、强大的代码分析和重构工具而闻名。...

    scala-intellij-bin-2019.1.9.zip

    这个"scala-intellij-bin-2019.1.9.zip"压缩包文件是为IntelliJ IDEA开发的一个Scala插件,适用于2019.1.x版本的IDEA集成开发环境。IntelliJ IDEA是一款广泛使用的Java开发工具,由于其优秀的代码补全、重构和调试...

    scala2.12.1Windows镜像包

    1. **Scala语言特性**: - **类型系统**:Scala具有强大的静态类型系统,允许类型推断,使得代码更简洁。 - **面向对象**:支持类、接口、继承和多态,同时引入了特质(trait),提供了一种灵活的实现多重继承的...

    scala-intellij-bin-2019.1.2.zip

    "scala-intellij-bin-2019.1.2.zip"这个压缩包就是针对IntelliJ IDEA的Scala插件,版本为2019.1.2,用于增强IDE对Scala语言的支持。 首先,我们需要理解Scala插件的作用。在IntelliJ IDEA中安装此插件后,用户可以...

    scala-2.12.10.zip

    1. 下载并解压"scala-2.12.10.zip"文件。 2. 将解压后的Scala目录添加到系统的PATH环境变量中,以便在命令行中直接调用 Scala 命令。 3. 确保已安装Java Development Kit (JDK) 8 或更高版本,因为Scala需要JVM才能...

    scala详细总结

    1. Scala 解释器:Scala 解释器是一个交互式的 shell,allows users to interactively evaluate Scala expressions and statements. 2.Scala 编译器:Scala 编译器将 Scala 代码编译为 JVM 可以运行的字节码。 3. ...

    Functional Programming Principles in Scala Assignments Week1

    **标题解析:** "Functional Programming Principles in Scala Assignments Week1" 指的是Coursera上一门关于函数式编程原理的Scala课程的第一周作业。这表明我们即将探讨的内容与Scala编程语言以及函数式编程的基本...

    scala + mybatis 数据库查询

    1. **Scala与MyBatis的集成** - Scala的静态类型系统和强大的表达能力使其成为构建复杂应用程序的良好选择,而MyBatis以其灵活性和易用性在Java世界中占有一席之地。通过使用Scala的Java互操作性,我们可以无缝地在...

    大数据课程-Scala编程基础-1.Scala语言初识_lk_edit.ppt

    【大数据课程-Scala编程基础-1.Scala语言初识】是针对初学者设计的一门课程,旨在教授如何入门Scala编程,特别适合已有Java基础的学员。Scala是一种在2001年由洛桑联邦理工学院(EPFL)的编程方法实验室研发的语言,...

    scala-2.12.10.tgz

    1. Scala简介:Scala由Martin Odersky和他的团队在2003年开发,其名称是“Scalable Language”的缩写。它旨在提高开发效率,提供简洁、可读性强的语法,同时支持大规模并发处理。 2. 安装Scala:在Linux系统中,...

    scala实战高清讲解

    1. **Scala基础** - 类与对象:Scala中的所有数据都是对象,类是创建对象的模板。它支持单例对象和伴生对象,这为设计模式提供了简洁的实现。 - 函数:Scala将函数视为一等公民,可以作为变量赋值、作为参数传递和...

    scala-intellij-bin-2020.1.39.zip

    总结来说,`scala-intellij-bin-2020.1.39.zip`是一个为IntelliJ IDEA 2020.1系列版本打造的Scala编程插件,它提供了丰富的代码编辑、分析、调试和协作功能,旨在提升Scala开发者的生产力和体验。如果你是Scala...

    Scala语法简明教程

    for (i <- 1 to 100 if i % 2 == 0) println(i) ``` - **方法定义**: - 方法定义在Scala中更为简洁,支持默认参数、可变参数、命名参数等多种形式。 ```scala def f(x: Int): Int = x * x def a(x: Int, y: ...

    scala-2.13.0-M1.tgz下载

    在Scala的版本体系中,M1代表“Milestone 1”,这是一个预发布版本,用于测试和反馈,以便在正式发布前进行必要的调整和优化。 Scala 2.13.0-M1引入了许多改进和新特性,旨在提升性能、简化代码和增强语言的表达...

    scala-2.11.8.rar

    1. **编译器源码**:在源码中,你可以看到Scala编译器的实现,包括解析器、类型检查器、优化器等。这有助于理解如何将Scala代码转换为JVM字节码。 2. **标准库源码**:Scala的标准库包含了许多内置数据结构、集合...

    windows版scala-2.11.12.zip

    1. 确保你的系统安装了Java Development Kit (JDK) 7或更高版本,因为Scala需要JDK来运行。 2. 添加Scala和Java的bin目录到PATH环境变量时,需按照正确的顺序,通常是先添加Java的路径,再添加Scala的路径。 3. 使用...

Global site tag (gtag.js) - Google Analytics