热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

看完Slick官方网站上关于Slick3.1.1技术文档后决定开始动手建一个项目来尝试一下Slick功能的具体使用方法。我把这个过程中的一些了解和想法记录下来和大家一起分享。首先我用Intell

   看完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 }

 

 

 

 

 

 

 

 

 

 

 

 

 


推荐阅读
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 本文介绍了[从头学数学]中第101节关于比例的相关问题的研究和修炼过程。主要内容包括[机器小伟]和[工程师阿伟]一起研究比例的相关问题,并给出了一个求比例的函数scale的实现。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
  • 本文介绍了在MacOS系统上安装MySQL的步骤,并详细说明了如何设置MySQL服务的开机启动和如何修改MySQL的密码。通过下载MySQL的macos版本并按照提示一步一步安装,在系统偏好设置中可以找到MySQL的图标进行设置。同时,还介绍了通过终端命令来修改MySQL的密码的具体操作步骤。 ... [详细]
  • MySQL语句大全:创建、授权、查询、修改等【MySQL】的使用方法详解
    本文详细介绍了MySQL语句的使用方法,包括创建用户、授权、查询、修改等操作。通过连接MySQL数据库,可以使用命令创建用户,并指定该用户在哪个主机上可以登录。同时,还可以设置用户的登录密码。通过本文,您可以全面了解MySQL语句的使用方法。 ... [详细]
  • 本文介绍了在使用Laravel和sqlsrv连接到SQL Server 2016时,如何在插入查询中使用输出子句,并返回所需的值。同时讨论了使用CreatedOn字段返回最近创建的行的解决方法以及使用Eloquent模型创建后,值正确插入数据库但没有返回uniqueidentifier字段的问题。最后给出了一个示例代码。 ... [详细]
  • 本文介绍了如何使用PHP代码将表格导出为UTF8格式的Excel文件。首先,需要连接到数据库并获取表格的列名。然后,设置文件名和文件指针,并将内容写入文件。最后,设置响应头部,将文件作为附件下载。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
author-avatar
1098502132_027279
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有