准备开发环境
本篇介绍如果设置使用 Slick 的 Scala 开发环境,这里我们使用 SBT 命令行,SBT 使用的目录结构和 Maven 一样,我们可以创建一个目录,比如 Slick ,然后创建如下的缺省目录结构:
- src
- main
- test
- java
- resources
- scala
因为我们打算使用 MySQL 数据库,并使用 Slick 来访问数据库,因此我们在 Slick 的根目录下创建一个 build.sbt,添加相关引用:
name := "Scala Slick Examples"
version := "1.0"
scalaVersion := "2.10.4"
libraryDependencies += "com.typesafe.slick" %% "slick" % "2.0.2"
libraryDependencies += "org.slf4j" % "slf4j-nop" % "1.6.4"
libraryDependencies += "mysql" % "mysql-connector-java" % "5.1.18"
Slick 使用 SLF4J 作为日志库文件。
我们的 MySQL 数据库 Chinook 安装在本地服务器上面,我们在使用 Slick 可以手工创建数据库表 Schema 的定义,也可以使用自动代码生成工具从已有的数据库创建 Table 的 Schema 定义。
我们在命令行输入 sbt,进入 SBT 控制台。
然后我们使用 console,进入 Scala 控制台,注意此时 SBT 自动把 build.sbt 中引用到的库比如 slick, mysql 添加到 Scala 控制台,我们使用如下命令:
scala.slick.model.codegen.SourceCodeGenerator.main(
Array(slickDriver, jdbcDriver, url, outputFolder, pkg, user, password)
)
相关参数如下:
slickDriver Fully qualified name of Slick driver class, e.g. “scala.slick.driver.H2Driver”
jdbcDriver Fully qualified name of jdbc driver class, e.g. “org.h2.Driver”
url jdbc url, e.g. “jdbc:postgresql://localhost/test”
outputFolder Place where the package folder structure should be put
pkg Scala package the generated code should be places in
user database connection user name
password database connection password
例如对于本例,我们使用 mysql 数据库,可以在命令行输入如下命令:注意修改你的用户名和密码:
scala.slick.model.codegen.SourceCodeGenerator.main(
Array("scala.slick.driver.MySQLDriver", "com.mysql.jdbc.Driver",
"jdbc:mysql://127.0.0.1/Chinook",
"./src/main/scala",
"com.guidebee.slick.example", "user", "password")
)
这样自动代码生成工具,就在 /src/main/scala
目录下生成了 Tables.scala 文件
package com.guidebee.slick.example
object Tables extends {
val profile = scala.slick.driver.MySQLDriver
} with Tables
trait Tables {
val profile: scala.slick.driver.JdbcProfile
import profile.simple._
import scala.slick.model.ForeignKeyAction
import scala.slick.jdbc.{GetResult => GR}
lazy val ddl = Album.ddl ++ Artist.ddl ++ Customer.ddl ++ Employee.ddl ++ Genre.ddl ++ Invoice.ddl ++ Invoiceline.ddl ++ Mediatype.ddl ++ Playlist.ddl ++ Playlisttrack.ddl ++ Track.ddl
case class AlbumRow(albumid: Int, title: String, artistid: Int)
implicit def GetResultAlbumRow(implicit e0: GR[Int], e1: GR[String]): GR[AlbumRow] = GR{
prs => import prs._
AlbumRow.tupled((<<[Int], <<[String], <<[Int]))
}
class Album(tag: Tag) extends Table[AlbumRow](tag, "Album") {
def * = (albumid, title, artistid) <> (AlbumRow.tupled, AlbumRow.unapply)
def ? = (albumid.?, title.?, artistid.?).shaped.<>({r=>import r._; _1.map(_=> AlbumRow.tupled((_1.get, _2.get, _3.get)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val albumid: Column[Int] = column[Int]("AlbumId", O.PrimaryKey)
val title: Column[String] = column[String]("Title")
val artistid: Column[Int] = column[Int]("ArtistId")
lazy val artistFk = foreignKey("FK_AlbumArtistId", artistid, Artist)(r => r.artistid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
}
lazy val Album = new TableQuery(tag => new Album(tag))
case class ArtistRow(artistid: Int, name: Option[String])
implicit def GetResultArtistRow(implicit e0: GR[Int], e1: GR[Option[String]]): GR[ArtistRow] = GR{
prs => import prs._
ArtistRow.tupled((<<[Int], <<?[String]))
}
class Artist(tag: Tag) extends Table[ArtistRow](tag, "Artist") {
def * = (artistid, name) <> (ArtistRow.tupled, ArtistRow.unapply)
def ? = (artistid.?, name).shaped.<>({r=>import r._; _1.map(_=> ArtistRow.tupled((_1.get, _2)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val artistid: Column[Int] = column[Int]("ArtistId", O.PrimaryKey)
val name: Column[Option[String]] = column[Option[String]]("Name")
}
lazy val Artist = new TableQuery(tag => new Artist(tag))
case class CustomerRow(customerid: Int, firstname: String, lastname: String, company: Option[String], address: Option[String], city: Option[String], state: Option[String], country: Option[String], postalcode: Option[String], phone: Option[String], fax: Option[String], email: String, supportrepid: Option[Int])
implicit def GetResultCustomerRow(implicit e0: GR[Int], e1: GR[String], e2: GR[Option[String]], e3: GR[Option[Int]]): GR[CustomerRow] = GR{
prs => import prs._
CustomerRow.tupled((<<[Int], <<[String], <<[String], <<?[String], <<?[String], <<?[String], <<?[String], <<?[String], <<?[String], <<?[String], <<?[String], <<[String], <<?[Int]))
}
class Customer(tag: Tag) extends Table[CustomerRow](tag, "Customer") {
def * = (customerid, firstname, lastname, company, address, city, state, country, postalcode, phone, fax, email, supportrepid) <> (CustomerRow.tupled, CustomerRow.unapply)
def ? = (customerid.?, firstname.?, lastname.?, company, address, city, state, country, postalcode, phone, fax, email.?, supportrepid).shaped.<>({r=>import r._; _1.map(_=> CustomerRow.tupled((_1.get, _2.get, _3.get, _4, _5, _6, _7, _8, _9, _10, _11, _12.get, _13)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val customerid: Column[Int] = column[Int]("CustomerId", O.PrimaryKey)
val firstname: Column[String] = column[String]("FirstName")
val lastname: Column[String] = column[String]("LastName")
val company: Column[Option[String]] = column[Option[String]]("Company")
val address: Column[Option[String]] = column[Option[String]]("Address")
val city: Column[Option[String]] = column[Option[String]]("City")
val state: Column[Option[String]] = column[Option[String]]("State")
val country: Column[Option[String]] = column[Option[String]]("Country")
val postalcode: Column[Option[String]] = column[Option[String]]("PostalCode")
val phone: Column[Option[String]] = column[Option[String]]("Phone")
val fax: Column[Option[String]] = column[Option[String]]("Fax")
val email: Column[String] = column[String]("Email")
val supportrepid: Column[Option[Int]] = column[Option[Int]]("SupportRepId")
lazy val employeeFk = foreignKey("FK_CustomerSupportRepId", supportrepid, Employee)(r => r.employeeid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
}
lazy val Customer = new TableQuery(tag => new Customer(tag))
case class EmployeeRow(employeeid: Int, lastname: String, firstname: String, title: Option[String], reportsto: Option[Int], birthdate: Option1, hiredate: Option1, address: Option[String], city: Option[String], state: Option[String], country: Option[String], postalcode: Option[String], phone: Option[String], fax: Option[String], email: Option[String])
implicit def GetResultEmployeeRow(implicit e0: GR[Int], e1: GR[String], e2: GR[Option[String]], e3: GR[Option[Int]], e4: GR[Option1]): GR[EmployeeRow] = GR{
prs => import prs._
EmployeeRow.tupled((<<[Int], <<[String], <<[String], <<?[String], <<?[Int], <<?1, <<?1, <<?[String], <<?[String], <<?[String], <<?[String], <<?[String], <<?[String], <<?[String], <<?[String]))
}
class Employee(tag: Tag) extends Table[EmployeeRow](tag, "Employee") {
def * = (employeeid, lastname, firstname, title, reportsto, birthdate, hiredate, address, city, state, country, postalcode, phone, fax, email) <> (EmployeeRow.tupled, EmployeeRow.unapply)
def ? = (employeeid.?, lastname.?, firstname.?, title, reportsto, birthdate, hiredate, address, city, state, country, postalcode, phone, fax, email).shaped.<>({r=>import r._; _1.map(_=> EmployeeRow.tupled((_1.get, _2.get, _3.get, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val employeeid: Column[Int] = column[Int]("EmployeeId", O.PrimaryKey)
val lastname: Column[String] = column[String]("LastName")
val firstname: Column[String] = column[String]("FirstName")
val title: Column[Option[String]] = column[Option[String]]("Title")
val reportsto: Column[Option[Int]] = column[Option[Int]]("ReportsTo")
val birthdate: Column[Option1] = column[Option1]("BirthDate")
val hiredate: Column[Option1] = column[Option1]("HireDate")
val address: Column[Option[String]] = column[Option[String]]("Address")
val city: Column[Option[String]] = column[Option[String]]("City")
val state: Column[Option[String]] = column[Option[String]]("State")
val country: Column[Option[String]] = column[Option[String]]("Country")
val postalcode: Column[Option[String]] = column[Option[String]]("PostalCode")
val phone: Column[Option[String]] = column[Option[String]]("Phone")
val fax: Column[Option[String]] = column[Option[String]]("Fax")
val email: Column[Option[String]] = column[Option[String]]("Email")
lazy val employeeFk = foreignKey("FK_EmployeeReportsTo", reportsto, Employee)(r => r.employeeid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
}
lazy val Employee = new TableQuery(tag => new Employee(tag))
case class GenreRow(genreid: Int, name: Option[String])
implicit def GetResultGenreRow(implicit e0: GR[Int], e1: GR[Option[String]]): GR[GenreRow] = GR{
prs => import prs._
GenreRow.tupled((<<[Int], <<?[String]))
}
class Genre(tag: Tag) extends Table[GenreRow](tag, "Genre") {
def * = (genreid, name) <> (GenreRow.tupled, GenreRow.unapply)
def ? = (genreid.?, name).shaped.<>({r=>import r._; _1.map(_=> GenreRow.tupled((_1.get, _2)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val genreid: Column[Int] = column[Int]("GenreId", O.PrimaryKey)
val name: Column[Option[String]] = column[Option[String]]("Name")
}
lazy val Genre = new TableQuery(tag => new Genre(tag))
case class InvoiceRow(invoiceid: Int, customerid: Int, invoicedate: java.sql.Timestamp, billingaddress: Option[String], billingcity: Option[String], billingstate: Option[String], billingcountry: Option[String], billingpostalcode: Option[String], total: scala.math.BigDecimal)
implicit def GetResultInvoiceRow(implicit e0: GR[Int], e1: GR1, e2: GR[Option[String]], e3: GR1): GR[InvoiceRow] = GR{
prs => import prs._
InvoiceRow.tupled((<<[Int], <<[Int], <<1, <<?[String], <<?[String], <<?[String], <<?[String], <<?[String], <<1))
}
class Invoice(tag: Tag) extends Table[InvoiceRow](tag, "Invoice") {
def * = (invoiceid, customerid, invoicedate, billingaddress, billingcity, billingstate, billingcountry, billingpostalcode, total) <> (InvoiceRow.tupled, InvoiceRow.unapply)
def ? = (invoiceid.?, customerid.?, invoicedate.?, billingaddress, billingcity, billingstate, billingcountry, billingpostalcode, total.?).shaped.<>({r=>import r._; _1.map(_=> InvoiceRow.tupled((_1.get, _2.get, _3.get, _4, _5, _6, _7, _8, _9.get)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val invoiceid: Column[Int] = column[Int]("InvoiceId", O.PrimaryKey)
val customerid: Column[Int] = column[Int]("CustomerId")
val invoicedate: Column1 = column1("InvoiceDate")
val billingaddress: Column[Option[String]] = column[Option[String]]("BillingAddress")
val billingcity: Column[Option[String]] = column[Option[String]]("BillingCity")
val billingstate: Column[Option[String]] = column[Option[String]]("BillingState")
val billingcountry: Column[Option[String]] = column[Option[String]]("BillingCountry")
val billingpostalcode: Column[Option[String]] = column[Option[String]]("BillingPostalCode")
val total: Column1 = column1("Total")
lazy val customerFk = foreignKey("FK_InvoiceCustomerId", customerid, Customer)(r => r.customerid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
}
lazy val Invoice = new TableQuery(tag => new Invoice(tag))
case class InvoicelineRow(invoicelineid: Int, invoiceid: Int, trackid: Int, unitprice: scala.math.BigDecimal, quantity: Int)
implicit def GetResultInvoicelineRow(implicit e0: GR[Int], e1: GR1): GR[InvoicelineRow] = GR{
prs => import prs._
InvoicelineRow.tupled((<<[Int], <<[Int], <<[Int], <<1, <<[Int]))
}
class Invoiceline(tag: Tag) extends Table[InvoicelineRow](tag, "InvoiceLine") {
def * = (invoicelineid, invoiceid, trackid, unitprice, quantity) <> (InvoicelineRow.tupled, InvoicelineRow.unapply)
def ? = (invoicelineid.?, invoiceid.?, trackid.?, unitprice.?, quantity.?).shaped.<>({r=>import r._; _1.map(_=> InvoicelineRow.tupled((_1.get, _2.get, _3.get, _4.get, _5.get)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val invoicelineid: Column[Int] = column[Int]("InvoiceLineId", O.PrimaryKey)
val invoiceid: Column[Int] = column[Int]("InvoiceId")
val trackid: Column[Int] = column[Int]("TrackId")
val unitprice: Column1 = column1("UnitPrice")
val quantity: Column[Int] = column[Int]("Quantity")
lazy val invoiceFk = foreignKey("FK_InvoiceLineInvoiceId", invoiceid, Invoice)(r => r.invoiceid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
lazy val trackFk = foreignKey("FK_InvoiceLineTrackId", trackid, Track)(r => r.trackid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
}
lazy val Invoiceline = new TableQuery(tag => new Invoiceline(tag))
case class MediatypeRow(mediatypeid: Int, name: Option[String])
implicit def GetResultMediatypeRow(implicit e0: GR[Int], e1: GR[Option[String]]): GR[MediatypeRow] = GR{
prs => import prs._
MediatypeRow.tupled((<<[Int], <<?[String]))
}
class Mediatype(tag: Tag) extends Table[MediatypeRow](tag, "MediaType") {
def * = (mediatypeid, name) <> (MediatypeRow.tupled, MediatypeRow.unapply)
def ? = (mediatypeid.?, name).shaped.<>({r=>import r._; _1.map(_=> MediatypeRow.tupled((_1.get, _2)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val mediatypeid: Column[Int] = column[Int]("MediaTypeId", O.PrimaryKey)
val name: Column[Option[String]] = column[Option[String]]("Name")
}
lazy val Mediatype = new TableQuery(tag => new Mediatype(tag))
case class PlaylistRow(playlistid: Int, name: Option[String])
implicit def GetResultPlaylistRow(implicit e0: GR[Int], e1: GR[Option[String]]): GR[PlaylistRow] = GR{
prs => import prs._
PlaylistRow.tupled((<<[Int], <<?[String]))
}
class Playlist(tag: Tag) extends Table[PlaylistRow](tag, "Playlist") {
def * = (playlistid, name) <> (PlaylistRow.tupled, PlaylistRow.unapply)
def ? = (playlistid.?, name).shaped.<>({r=>import r._; _1.map(_=> PlaylistRow.tupled((_1.get, _2)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val playlistid: Column[Int] = column[Int]("PlaylistId", O.PrimaryKey)
val name: Column[Option[String]] = column[Option[String]]("Name")
}
lazy val Playlist = new TableQuery(tag => new Playlist(tag))
case class PlaylisttrackRow(playlistid: Int, trackid: Int)
implicit def GetResultPlaylisttrackRow(implicit e0: GR[Int]): GR[PlaylisttrackRow] = GR{
prs => import prs._
PlaylisttrackRow.tupled((<<[Int], <<[Int]))
}
class Playlisttrack(tag: Tag) extends Table[PlaylisttrackRow](tag, "PlaylistTrack") {
def * = (playlistid, trackid) <> (PlaylisttrackRow.tupled, PlaylisttrackRow.unapply)
def ? = (playlistid.?, trackid.?).shaped.<>({r=>import r._; _1.map(_=> PlaylisttrackRow.tupled((_1.get, _2.get)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val playlistid: Column[Int] = column[Int]("PlaylistId")
val trackid: Column[Int] = column[Int]("TrackId")
val pk = primaryKey("PlaylistTrack_PK", (playlistid, trackid))
lazy val playlistFk = foreignKey("FK_PlaylistTrackPlaylistId", playlistid, Playlist)(r => r.playlistid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
lazy val trackFk = foreignKey("FK_PlaylistTrackTrackId", trackid, Track)(r => r.trackid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
}
lazy val Playlisttrack = new TableQuery(tag => new Playlisttrack(tag))
case class TrackRow(trackid: Int, name: String, albumid: Option[Int], mediatypeid: Int, genreid: Option[Int], composer: Option[String], milliseconds: Int, bytes: Option[Int], unitprice: scala.math.BigDecimal)
implicit def GetResultTrackRow(implicit e0: GR[Int], e1: GR[String], e2: GR[Option[Int]], e3: GR[Option[String]], e4: GR1): GR[TrackRow] = GR{
prs => import prs._
TrackRow.tupled((<<[Int], <<[String], <<?[Int], <<[Int], <<?[Int], <<?[String], <<[Int], <<?[Int], <<1))
}
class Track(tag: Tag) extends Table[TrackRow](tag, "Track") {
def * = (trackid, name, albumid, mediatypeid, genreid, composer, milliseconds, bytes, unitprice) <> (TrackRow.tupled, TrackRow.unapply)
def ? = (trackid.?, name.?, albumid, mediatypeid.?, genreid, composer, milliseconds.?, bytes, unitprice.?).shaped.<>({r=>import r._; _1.map(_=> TrackRow.tupled((_1.get, _2.get, _3, _4.get, _5, _6, _7.get, _8, _9.get)))}, (_:Any) => throw new Exception("Inserting into ? projection not supported."))
val trackid: Column[Int] = column[Int]("TrackId", O.PrimaryKey)
val name: Column[String] = column[String]("Name")
val albumid: Column[Option[Int]] = column[Option[Int]]("AlbumId")
val mediatypeid: Column[Int] = column[Int]("MediaTypeId")
val genreid: Column[Option[Int]] = column[Option[Int]]("GenreId")
val composer: Column[Option[String]] = column[Option[String]]("Composer")
val milliseconds: Column[Int] = column[Int]("Milliseconds")
val bytes: Column[Option[Int]] = column[Option[Int]]("Bytes")
val unitprice: Column1 = column1("UnitPrice")
lazy val albumFk = foreignKey("FK_TrackAlbumId", albumid, Album)(r => r.albumid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
lazy val genreFk = foreignKey("FK_TrackGenreId", genreid, Genre)(r => r.genreid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
lazy val mediatypeFk = foreignKey("FK_TrackMediaTypeId", mediatypeid, Mediatype)(r => r.mediatypeid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
}
lazy val Track = new TableQuery(tag => new Track(tag))
}
请发表评论