浅谈Slick(2)- Slick101:第一个动手尝试的项目

看完Slick官方网站上关于Slick3.1.1技术文档后决定开始动手建一个项目来尝试一下Slick功能的具体使用方法。我把这个过程中的一些了解和想法记录下来和大家一起分享。首先我用IntelliJ-Idea创建了一个scala项目。下一步就是如何选择数据库了。Slick是集成jdbc的更高层的Query编程语言,可以通过jdbc的url、DataSource等来指定目标数据库类型及相关的参数。对应Slick中的具体函数有:

val db = Database.forConfig("mydb")
val db = Database.forURL("jdbc:h2:mem:test1;DB_CLOSE_DELAY=-1", driver="org.h2.Driver")
val db = Database.forDataSource(dataSource: slick.jdbc.DatabaseUrlDataSource)

在Slick的Database配置方面forConfig("confItem")是比较灵活、方便实用的。confItem是resources/application.conf文件里的一个配置项目。Slick是通过typesafe-config来解析配置文件的。forConfig函数用typesafe-config库里的函数载入application.conf文件解析confItem并获取项目里的数据库配置参数,下面是项目中resources/application.conf文件内容:

h2mem {
    url = "jdbc:h2:mem:slickdemo"
    driver = "org.h2.Driver"
    connectionPool = disabled
    keepAliveConnection = true
}

h2 = {
    url = "jdbc:h2:~/slickdemo;mv_store=false;MODE=MSSQLServer;DB_CLOSE_DELAY=-1;AUTO_SERVER=TRUE"
    driver = org.h2.Driver
    connectionPool = disabled
    keepAliveConnection = true
}

mysql {
  driver = "slick.driver.MySQLDriver$"
  db {
    url = "jdbc:mysql://localhost/slickdemo"
    driver = com.mysql.jdbc.Driver
    keepAliveConnection = true
    user="root"
    password="123"
    numThreads=10
    maxConnections = 12
    minConnections = 4
  }
}

mysqldb = {
  dataSourceClass = "com.mysql.jdbc.jdbc2.optional.MysqlDataSource"
  properties {
    user = "root"
    password = "123"
    databaseName = "slickdemo"
    serverName = "localhost"
  }
  numThreads = 10
  maxConnections = 12
  minConnections = 4
}

postgres {
  driver = "slick.driver.PostgresDriver$"
  db {
    url = "jdbc:postgresql://127.0.0.1/slickdemo"
    driver = "org.postgresql.Driver"
    connectionPool = HikariCP
    user = "slick"
    password = "123"
    numThreads = 10
    maxConnections = 12
    minConnections = 4
  }
}

postgressdb = {
  dataSourceClass = "org.postgresql.ds.PGSimpleDataSource"
  properties = {
    databaseName = "slickdemo"
    user = "slick"
    password = "123"
  }
  connectionPool = HikariCP
  numThreads = 10
  maxConnections = 12
  minConnections = 4
}

mssql {
  driver = "com.typesafe.slick.driver.ms.SQLServerDriver$"
  db {
    url = "jdbc:sqlserver://host:port"
    driver = com.microsoft.sqlserver.jdbc.SQLServerDriver
    connectionTimeout = 30 second
    connectionPool = HikariCP
    user = "slick"
    password = "123"
    numThreads = 10
    maxConnections = 12
    minConnections = 4
    keepAliveConnection = true
  }
}

tsql {
  driver = "slick.driver.H2Driver$"
  db = ${h2mem}
}

在我使用的application.conf文件中汇集了一些常用数据库的配置,我一并提供出来。除h2之外其它都没进行测试验证,具体配置参数和方法要参考数据库开发商提供的技术文档。我在这个示范里选用了h2配置:它会在我的用户根目录下创建一个slickdemo.h2.db数据库文件。
好了,选择了数据库,下面我们就来试试使用它。基本流程是这样的:首先在数据库里创建表,跟着写入一些数据,然后再读出显示。整个过程会涉及:表结构schema定义,数据插写Insert,数据读取Query及简单的Query运算方法和数据显示方法。

现在我们先设计表结构schema:

 1 package com.datatech.learn.slick101
 2 import slick.driver.H2Driver.api._
 3 object slick101 {
 4
 5 /* ----- schema  */
 6   //表字段对应模版
 7   case class AlbumModel (id: Long
 8                    ,title: String
 9                    ,year: Option[Int]
10                    ,artist: String
11                    )
12   //表结构: 定义字段类型, * 代表结果集字段
13   class AlbumTable(tag: Tag) extends Table[AlbumModel](tag, "ALBUMS") {
14     def id = column[Long]("ID",O.AutoInc,O.PrimaryKey)
15     def title = column[String]("TITLE")
16     def year = column[Option[Int]]("YEAR")
17     def artist = column[String]("ARTIST",O.Default("Unknown"))
18     def * = (id,title,year,artist) <> (AlbumModel.tupled, AlbumModel.unapply)
19   }
20   //库表实例
21   val albums = TableQuery[AlbumTable]

在这个示范里我们确定使用H2数据库,所以需要import H2Driver.api。使用了case class AlbumModel作为库表字段对应模版。这样一是可以规范代码,再就是如果遇到一个宽表有很多列的话可以节省许多重复铺垫及避免无谓错误。

现在需要从库表实例albums产生它的schema,然后转换成一个DBIOAction:

  //创建表动作
 val createTableAction = albums.schema.create

这个createTableAction就是个DBIOAction:一个效果描述。我们必须用具体的实现方式Database.run来运算产生实际效果:

1   //数据库实例化
2 val db = Database.forConfig("h2")
3 def main(args: Array[String]): Unit = {
4    val res = db.run(createTableAction).andThen {
5        case Success(_) => println("table ALBUMS created.")
6        case Failure(e) => println(e.getMessage)
7    }
8    Await.result(res, 10 seconds)
9 }

db.run返回Future类型。我们是用Future类型的andThen组件来显示运算结果的:

table ALBUMS created.

Process finished with exit code 0

如果跟着再运算一次应该会产生重复重建错误:

Exception in thread "main" org.h2.jdbc.JdbcSQLException: Table "ALBUMS" already exists; SQL statement:
Table "ALBUMS" already exists; SQL statement: ...

下面是一个插入数据的动作:

1 //插入数据动作
2   val insertAlbumsAction =
3   albums ++= Seq(
4     AlbumModel(0, "Keyboard Cat", Some(2003), "Keyboard Cat‘s Greatest Hits"),
5     AlbumModel(0, "Spice Girls", Some(2010), "Spice"),
6     AlbumModel(0, "Rick Astley", Some(1998), "Whenever You Need Somebody"),
7     AlbumModel(0, "Manowar", None,"The Triumph of Steel"),
8     AlbumModel(0, "Justin Bieber", Some(2011),"Believe"))

运算及显示结果:

 1    val res2 = db.run(insertAlbumsAction).andThen {
 2       case Success(_) => println("albums inserted.")
 3       case Failure(e) => println(e.getMessage)
 4     }
 5     Await.result(res2, 10 seconds)
 6 ---
 7 table ALBUMS created.
 8 albums inserted.
 9
10 Process finished with exit code 0

下面是抽取动作和数据显示函数。我们把新插入的数据再读出来验证插入情况:

//数据抽取动作
  val selectAlbumsAction =
  albums.result
  def printResults[T](fut: Future[Iterable[T]]): Unit =
    Await.result(fut, Duration.Inf).foreach(println)

  val res3 = db.run(selectAlbumsAction)
  printResults(res3)

运算结果:

AlbumModel(1,Keyboard Cat,Some(2003),Keyboard Cat‘s Greatest Hits)
AlbumModel(2,Spice Girls,Some(2010),Spice)
AlbumModel(3,Rick Astley,Some(1998),Whenever You Need Somebody)
AlbumModel(4,Manowar,None,The Triumph of Steel)
AlbumModel(5,Justin Bieber,Some(2011),Believe)

Process finished with exit code 0

下面是完整的示范代码:

 1 package com.datatech.learn.slick101
 2 import scala.concurrent.ExecutionContext.Implicits.global
 3 import scala.concurrent.duration._
 4 import scala.concurrent.{Await, Future}
 5 import scala.util.{Success,Failure}
 6
 7 import slick.driver.H2Driver.api._
 8 object slick101 {
 9
10   /* ----- schema  */
11   //表字段对应模版
12   case class AlbumModel(id: Long
13                         , artist: String
14                         , year: Option[Int]
15                         , title: String
16                        )
17
18   //表结构: 定义字段类型, * 代表结果集字段
19   class AlbumTable(tag: Tag) extends Table[AlbumModel](tag, "ALBUMS") {
20     def id = column[Long]("ID", O.AutoInc, O.PrimaryKey)
21
22     def title = column[String]("TITLE")
23
24     def year = column[Option[Int]]("YEAR")
25
26     def artist = column[String]("ARTIST", O.Default("Unknown"))
27
28     def * = (id, artist, year, title) <> (AlbumModel.tupled, AlbumModel.unapply)
29   }
30
31   //库表实例
32   val albums = TableQuery[AlbumTable]
33
34   //创建表动作
35   val createTableAction = albums.schema.create
36
37   //数据库实例化
38   val db = Database.forConfig("h2")
39
40   //插入数据动作
41   val insertAlbumsAction =
42   albums ++= Seq(
43     AlbumModel(0, "Keyboard Cat", Some(2003), "Keyboard Cat‘s Greatest Hits"),
44     AlbumModel(0, "Spice Girls", Some(2010), "Spice"),
45     AlbumModel(0, "Rick Astley", Some(1998), "Whenever You Need Somebody"),
46     AlbumModel(0, "Manowar", None,"The Triumph of Steel"),
47     AlbumModel(0, "Justin Bieber", Some(2011),"Believe"))
48
49   //数据抽取动作
50   val selectAlbumsAction =
51   albums.result
52
53   def printResults[T](fut: Future[Iterable[T]]): Unit =
54     Await.result(fut, Duration.Inf).foreach(println)
55
56   def main(args: Array[String]): Unit = {
57
58      val res = db.run(createTableAction).andThen {
59        case Success(_) => println("table ALBUMS created.")
60        case Failure(e) => println(e.getMessage)
61      }
62      Await.result(res, 10 seconds)
63
64     val res2 = db.run(insertAlbumsAction).andThen {
65       case Success(_) => println("albums inserted.")
66       case Failure(e) => println(e.getMessage)
67     }
68     Await.result(res2, 10 seconds)
69
70     val res3 = db.run(selectAlbumsAction)
71     printResults(res3)
72   }
73 }
时间: 2024-08-03 22:38:10

浅谈Slick(2)- Slick101:第一个动手尝试的项目的相关文章

浅谈Slick(4)- Slick301:我的Slick开发项目设置

前面几篇介绍里尝试了一些Slick的功能和使用方式,看来基本可以满足用scala语言进行数据库操作编程的要求,而且有些代码可以通过函数式编程模式来实现.我想,如果把Slick当作数据库操作编程主要方式的话,可能需要先制定一套比较规范的模式来应付日常开发(也要考虑团队开发).测试和维护.首先从项目结构来说,我发现由Intellij-Idea IDE界面直接产生的SBT项目结构已经比较理想了.在src/main/resources是scala项目获取配置文件的默认目录.我们可以按照需要在src/ma

浅谈Slick(1)- 基本功能描述

Slick (Scala language-integrated connection kit)是scala的一个FRM(Functional Relational Mapper),即函数式的关系数据库编程工具库.Slick的主要目的是使关系数据库能更容易.更自然的融入函数式编程模式,它可以使使用者像对待scala集合一样来处理关系数据库表.也就是说可以用scala集合的那些丰富的操作函数来处理库表数据.Slick?把数据库编程融入到scala编程中,编程人员可以不需要编写SQL代码.我把Sli

浅谈开发人员是按部门划分还是按项目划分为好

开发人员划分的依据主要依赖于公司开发方式. 如果公司主要以项目开发为主,那么开发人员按部门分配比较好.比如可以分为PC端部门,移动端部门,测试部门,美工部门,实施部门等.这样的好处是人员可以专注于自身技术,一个部门可以同时承担多个项目,因为许多项目的技术要求是相似的.劣处是可能仅仅关注于项目完成,很难对业务逻辑和项目质量进行提炼和优化. 如果公司主要开发一个产品,那么使用扁平化的方式,将开发,美工,测试混合搭配比较好.因为一个产品无论是移动还是PC端,其业务逻辑是相同的,界面风格也要类似.这就要

经验浅谈,新人如何快速上手一个新项目

经验浅谈,总结下自己如何接手一个新项目: 1.向同事问清楚当前的开发环境,而且现今的发展,要区分64位和32位2.搞明白当前项目的运行环境,如果是多项目的话,要搞清楚依赖关系3.让同事帮忙搞定本机可运行项目的环境4.当环境都弄好.项目能启动后,开始代码之旅,也是最重要的一步. a)看配置.通看一遍配置文件,了解当前项目用了哪些框架,做到心中有数 b)学业务(重点*).了解各页面间的跳转及异步请求,写一个临时Filter,拦截/*的所有请求,在doFilter()方法中,打印出每次请求的路径( S

浅谈数据初始化方法

浅谈数据初始化方法 在定制开发的信息化项目实施过程中,我们发现衡量一个项目成功与否,关键看以下三个指标: v人: 系统的利益相关人的需求是否都得到了满足: v系统:软件本身是否可用.易用.稳定.有效率: v数据:数据是否准确.可靠.稳定支持业务的运作: 从这个角度来说,数据在信息系统项目实施过程中有着举足轻重的地位,特别是数据初始化的成功与否是源头和决定因素.下面将数据初始化的过程分解为八个步骤,以确保数据初始化过程的严谨性和科学性. 步骤一:系统数据库表的分析:对信息系统数据库表进行分析,了解

浅谈算法和数据结构

: 一 栈和队列 http://www.cnblogs.com/yangecnu/p/Introduction-Stack-and-Queue.html 最近晚上在家里看Algorithems,4th Edition,我买的英文版,觉得这本书写的比较浅显易懂,而且“图码并茂”,趁着这次机会打算好好学习做做笔记,这样也会印象深刻,这也是写这一系列文章的原因.另外普林斯顿大学在Coursera 上也有这本书同步的公开课,还有另外一门算法分析课,这门课程的作者也是这本书的作者,两门课都挺不错的. 计算

python浅谈正则的常用方法

python浅谈正则的常用方法覆盖范围70%以上 上一次很多朋友写文字屏蔽说到要用正则表达,其实不是我不想用(我正则用得不是很多,看过我之前爬虫的都知道,我直接用BeautifulSoup的网页标签去找内容,因为容易理解也方便,),而是正则用好用精通的很难(看过正则表的应该都知道,里面符号对应的方法规则有很多,很灵活),对于接触编程不久的朋友们来说很可能在编程的过程上浪费很多时间,今天我把经常会用到正则简单介绍下,如果不是很特殊基本都覆盖使用. 1.正则的简单介绍 首先你得导入正则方法 impo

浅谈算法和数据结构(1):栈和队列

浅谈算法和数据结构(1):栈和队列 2014/11/03 ·  IT技术                                         · 2 评论                                      ·  数据结构, 栈, 算法, 队列 分享到: 60 SegmentFault D-Day 2015 北京:iOS 站 JDBC之“对岸的女孩走过来” CSS深入理解之relative HTML5+CSS3实现春节贺卡 原文出处: 寒江独钓   欢迎分享原创

浅谈web前端开发

有部分同学和朋友问到过我相关问题.利用周末我就浅浅地谈谈我对web前端开发的理解和体会,仅仅能浅浅谈谈,高手请自己主动跳过本篇文章. 毕竟我如今经验并非非常足,连project师都算不上,更不用说大牛了.今天也不谈技术.技术非常多人比我掌握得更好,也大同小异.可是每一个人的理解体会是不一样的. 对前端开发的三个整体理解和体会 我对前端开发的整体体会有三: 第一:杂而难,难度甚至超过了一般的后台开发,假设有人认为前端开发简单仅仅能说明他还没有入门. 第二:web前端开发正在向响应式和移动端方向大步