PlayFrameworkからデータベースを扱う為、JDBCドライバとマイグレーションツールEvolutionsを導入する。
依存ライブラリの導入
build.sbt
libraryDependencies += jdbc libraryDependencies += "org.postgresql" % "postgresql" % "42.2.12" libraryDependencies += evolutions
ドライバのバージョンは https://jdbc.postgresql.org/ この辺りから最新のバージョンを確認して指定した。
データベース DSNの指定
データソースの指定は、conf/application.conf
に記述する。
例えばDockerでこのようなPostgreSQLを起動して接続する場合、
$ docker run --name play-sample-db -p 5432:5432 -e POSTGRES_USER=play -e POSTGRES_PASSWORD=play -e POSTGRES_DB=playdb -v $(pwd)/pgdata:/var/lib/postgresql/data -d postgres:12.2
application.conf
は以下のように記述する。
db.default.driver=org.postgresql.Driver db.default.url="jdbc:postgresql://localhost:5432/playdb" db.default.user=play db.default.password=play
Evolutionsでマイグレーションを定義する
マイグレーションファイルはconf/
以下にevolutions/dbname/
ディレクトリを作成して定義・配置する。
dbname
は例えば環境ごと(product, develop, test)にマイグレーションを変更したい場合等は個別に環境ごとのdbnameのディレクトリを作成すればよい。
exp.
/conf/ db-product/ db-develop/ db-test/
マイグレーションファイルの作成
マイグレーションファイルは作成したディレクトリ以下に1.sql, 2.sql, ...と作成していく。
コメントで進行とロールバック時の挙動を指定する。
1.sql
# --- !Ups create table people( id serial primary key, name text not null, mail text not null, tel text ); insert into people (name, mail, tel)values('Terry', 'terry@letitride.jp', '000-0000-0000'); insert into people (name, mail, tel)values('Mike', 'mike@letitride.jp', '111-1111-1111'); insert into people (name, mail, tel)values('Mika', 'mika@letitride.jp', '222-2222-2222'); insert into people (name, mail, tel)values('Bob', 'bob@letitride.jp', '333-3333-3333'); # --- !Downs drop table people;
定義後、ブラウザからアクセスするとマイグレーションの実行確認を求められるので、許可すると指定のスクリプトが実行される。
尚、自動で実行したい場合、application.conf
に
applyEvolutions.default = true
を指定しておけばよい。
データベースの利用
PlayFrameworkからデータベースの利用は、以下のように記述する。
Fetch
import play.api.db.Database import java.sql.SQLException //Databaseインスタンスをinjectする class PeopleController @Inject()(db: Database ) extends AbstractController { ...
def foo = { try{ db.withConnection{ conn => val stmt = conn.createStatement val rs = stmt.executeQuery("select * from people") while(rs.next){ val id = rs.getInt("id") val name = rs.getString("name") } } }catch{ case e:SQLException => //...error } }
Write
def bar = { try { db.withConnection{ conn => val ps = conn.prepareStatement("insert into people (name, mail, tel)values(?, ?, ?)") ps.setString(1, "name") ps.setString(2, "mail@domain.com") ps.setString(3, "00-0000-0000") ps.executeUpdate() } } catch{ case e:SQLException => //...error } }
リンク