5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MysqlでScalikeJDBC入門

Last updated at Posted at 2019-01-26

目的

scalikejdbcをMysqlで動かしてみます。これからscalikejdbcを始める方向けです。

解説したコード全体はこちら: umeneri/scalikejdbc-example: example for scalikejdbc

参考

環境

  • intellij community edition 2018.1
  • scalaVersion 2.12.7
  • sbt.version 1.2.6
  • scalikejdbc 3.3.2

前準備

新規or既存のscalaプロジェクトを立ち上げておきます。

intelljの場合、File > New.. > Projectから、sbtのプロジェクトを作っておきます。

全体の流れ

  1. mysqlのセットアップ
  2. テーブルの作成
  3. コード自動生成
  4. テスト実行 → こちらは別記事

mysqlの立ち上げ

ローカルのmysqlを立ち上げるか、以下のようにdocker-compose.ymlを用意してdocker上で立ち上げます。
dockerでの立ち上げはmacの場合Docker.Appが必要です。

Docker.Appは以下でインストールします。

$ brew cask install docker

docker-compose.ymlの例です。

docker-compose.yml
version: "3"
services:
    example-mysql:
        container_name: example
        image: "mysql:5.6"
        ports:
            - "4306:3306"
        environment:
          MYSQL_ALLOW_EMPTY_PASSWORD: 1
          MYSQL_DATABASE: "example"

上記docker-composeで立ち上げれば「example」という名前のdatabaseが作成されています。

作成されていない場合は、mysqlにログインして以下で作成です。

create database example;

テーブルの作成

例としてmemberを管理するためのテーブルを作成します。

こちらのスクリプトを作ります。

init.sql
DROP TABLE IF EXISTS member;

CREATE TABLE member
(
  id BIGINT NOT NULL AUTO_INCREMENT,
  name VARCHAR(256) NOT NULL,
  description VARCHAR(1000),
  created_at DATETIME NOT NULL,
  updated_at DATETIME NOT NULL,
  PRIMARY KEY (id)
) ENGINE = 'InnoDB', DEFAULT CHARSET=utf8mb4, ROW_FORMAT=DYNAMIC;

insert into member values (1, 'Alice', '', current_timestamp, current_timestamp);
insert into member values (2, 'Bob',  '', current_timestamp, current_timestamp);

memberテーブルを作成します。

$ mysql -h 127.0.0.1 -uroot -P 4306 example < init.sql

build.sbtの設定

build.sbtへ以下を追加。

  • scalikejdbc … 本体
  • scalikejdbc-test … コードの自動生成でテストも生成するため
  • scalikejdbc-config … application.confにscalikejdbc設定を書くため
  • logback-classic … あまり詳しく調べてないのですが、ログ出力に使用
  • mysql-connector-java … mysqlとの連携に必要
  • scalatest … テストコードの自動生成で使用
build.sbt
libraryDependencies ++= Seq(
  "org.scalikejdbc" %% "scalikejdbc" % "3.3.+",
  "org.scalikejdbc" %% "scalikejdbc-test"   % "3.3.+"   % "test",
  "org.scalikejdbc" %% "scalikejdbc-config" % "3.3.+",
  "ch.qos.logback" % "logback-classic" % "1.2.3",
  "mysql" % "mysql-connector-java" % "5.1.29",
  "org.scalatest" %% "scalatest" % "3.0.5" % "test"
)

コードの自動生成

コード自動生成機能を使うため、以下をbuild.sbtへ追加。

enablePlugins(ScalikejdbcPlugin)

自動生成には、以下2つのファイルをprojectディレクトリ直下に入れる必要があります。

scalikejdbc-gen.sbt
libraryDependencies += "mysql" % "mysql-connector-java" % "5.1.29"

addSbtPlugin("org.scalikejdbc" %% "scalikejdbc-mapper-generator" % "3.3.+")
scalikejdbc.properties
# ---
# jdbc settings
jdbc.driver="com.mysql.jdbc.Driver"
jdbc.url="jdbc:mysql://127.0.0.1:4306/example"
jdbc.username=root
jdbc.password=
jdbc.schema=

# ---
# source code generator settings

generator.packageName=models
# generator.lineBreak: LF/CRLF
generator.lineBreak=LF
# generator.template: interpolation/queryDsl
generator.template=queryDsl
# generator.testTemplate: specs2unit/specs2acceptance/ScalaTestFlatSpec
generator.testTemplate=ScalaTestFlatSpec
generator.encoding=UTF-8
# When you're using Scala 2.11 or higher, you can use case classes for 22+ columns tables
generator.caseClassOnly=true
# Set AutoSession for implicit DBSession parameter's default value
generator.defaultAutoSession=true
# Use autoConstruct macro (default: false)
generator.autoConstruct=false
# joda-time (org.joda.time.DateTime) or JSR-310 (java.time.ZonedDateTime java.time.OffsetDateTime)
generator.dateTimeClass=java.time.ZonedDateTime

上記ファイルはjdbcのアクセス先URL等を記述します。デフォルトでのアクセス先をexampleとしています。

自動生成実行

それでは自動生成します。

$ sbt "scalikejdbcGenAll"

コマンド実行後、エラーが無ければ以下2ファイルが生成されています。

  • src/main/scala/models/Member.scala
  • src/test/scala/models/MemberSpec.scala

jdbc設定

アプリケーションコードでscalikejdbcを使用するため、application.confに以下設定を書きます。

src/main/resources/application.conf
# JDBC settings
db.default.driver="com.mysql.jdbc.Driver"
db.default.url="jdbc:mysql://127.0.0.1:4306/example"
db.default.user="root"
db.default.password=""

# Connection Pool settings
db.default.poolInitialSize=10
db.default.poolMaxSize=20
db.default.connectionTimeoutMillis=1000

# Connection Pool settings
db.default.poolInitialSize=5
db.default.poolMaxSize=7
db.default.poolConnectionTimeoutMillis=1000
db.default.poolValidationQuery="select 1 as one"
db.default.poolFactoryName="commons-dbcp2"

試しにMemberのデータにアクセスしてみます。

MysqlAccess.scala
package scalike

import models.Member
import scalikejdbc.config._


object MysqlAccess extends App {
  DBs.setupAll()

  val maybeFound = Member.find(1L)
  val name = maybeFound.get.name
  println(name) // => Alice

}

実行すると、実際のDBへのクエリもログに流れるのでデバッグしやすいですね。


  [SQL Execution]
   select m.id as i_on_m, m.name as n_on_m, m.description as d_on_m, m.created_at as ca_on_m, m.updated_at as ua_on_m from member m where m.id = 1; (8 ms)

  [Stack Trace]
    ...
    models.Member$.find(Member.scala:42)
    scalike.mysqlAccess$.delayedEndpoint$scalike$mysqlAccess$1(MysqlAccess.scala:10)
    scalike.mysqlAccess$delayedInit$body.apply(MysqlAccess.scala:7)
    scala.Function0.apply$mcV$sp(Function0.scala:39)
    scala.Function0.apply$mcV$sp$(Function0.scala:39)
    scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
    scala.App.$anonfun$main$1$adapted(App.scala:80)
    scala.collection.immutable.List.foreach(List.scala:392)
    scala.App.main(App.scala:80)
    scala.App.main$(App.scala:78)
    scalike.mysqlAccess$.main(MysqlAccess.scala:7)
    scalike.mysqlAccess.main(MysqlAccess.scala)
    ...

今回生成したテストはそのままでは通らないので、テストを通すよう書き換えます。(次回へ

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?