Ktor(kotlin)でJDBIを使う with postgres
はじめに
今回は、KtorでJDBIを使ってDB(postgres)にアクセスしてみます。
最終ゴールは、dbのテーブルの情報全てをJson形式でgetできるところまでです。
使用技術/ツール
- IntelliJ IDEA
- Kotlin
- Ktor
- Postgres
- JDBI (データベースアクセス)
- gradle
- docker-compose
IntelliJ IDEAのインストール
以下のリンクからインストールします
https://www.jetbrains.com/ja-jp/idea/
ダウンロードをクリックして次のページへ進みます。
今回は次のページで、Communityの方のダウンロードを押します
(M1なら、ダウンロードの右の▼を押して「.dmg(Apple Silicon)」を選択)
InteliJを開き、プラグインから以下をインストールします。
- Japanese Language Pack/日本語言語パック (日本語にします。英語でよければ不要)
- Ktor(Obsolete) (Ktorのプロジェクトを簡単に作れます。もしかしたら名前少し違うかも)
プロジェクトの作成
IntelliJを開きます。
新規プロジェクトを作成します。
Ktorを選択します
- Jacksonを追加しておきます
- RoutingとContentNegotiationは自動で選択されるみたいです。
Routing → 名前の通りルーティングに必要
Jackson → Json形式にするのに必要、(ContentNegotiationもこれに使うみたい)
作ったプロジェクトを確認してみる
こんな感じになっているかと
- Application.kt
Mainクラスです。
本来は分けるべきですが、今回は全部の処理をここに書きます。
- application.conf
アプリの設定とかDB情報とか書きます
- build.gradle
ライブラリの追加とかします
Application.ktを開きます
Application.ktを右クリックし、実行を選択してみます。
http://0.0.0.0:8080 を開くと「HELLO WORLD!」が表示されます。
http://0.0.0.0:8080/json/jackson を開くとJson形式で、以下が表示されます。
{
"hello": "world"
}
routing {}の箇所でパスと対応する処理が書かれています。
DBを準備、DBに接続
今回はdocker-composeで作ります。
※dockerのインストールはお願いします🙇♂️
ルートディレクトリ(src、resources、gradleなどがある階層)に
「docker-compose.yml」というファイルを作成します。
プロジェクトを右クリック→新規→ファイル で作成できます。
version: '3'
services:
postgres:
image: postgres:13.1
container_name: ktor_jdbi_postgress
ports:
- 5435:5432
volumes:
- ./postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: sample
POSTGRES_PASSWORD: sample
POSTGRES_DB: sample
POSTGRES_INITDB_ARGS: '--encoding=UTF-8'
TZ: 'Asia/Tokyo'
restart: always
※5432~5434は既に使っていて使えないので、5435にしました。(使ってなければ5432でも大丈夫です)
※user、password、dbは全て「sample」にしましたが、好きなもので大丈夫です。container_nameも
IntelliJの下の方からターミナルを開きます。
以下のコマンドを実行します。
docker-compose up -d
psqlでデータ追加&確認
以下のコマンドを実行し、パスワードを入れることで接続できます
psql -h localhost -p 5435 -U sample -d sample
テーブルを作成します。
(シンプルにするためidも自動ではなく自分で入れちゃいます)
CREATE TABLE Shohin
(shohin_id CHAR(4) NOT NULL,
name VARCHAR(100) NOT NULL,
price INTEGER ,
PRIMARY KEY (shohin_id));
テーブルができてることを確認します。
以下のコマンドを実行します。テーブル一覧が表示されます。
\dt
¥dt (←windowsはこうかも)
データの追加
データの追加
INSERT INTO Shohin VALUES ('0001', 'Tシャツ', 1000);
INSERT INTO Shohin VALUES ('0002', '穴あけパンチ', 500);
INSERT INTO Shohin VALUES ('0003', 'カッターシャツ', 4000);
INSERT INTO Shohin VALUES ('0004', '包丁', 3000);
INSERT INTO Shohin VALUES ('0005', '圧力鍋', 6800);
INSERT INTO Shohin VALUES ('0006', 'フォーク', 500);
INSERT INTO Shohin VALUES ('0007', 'おろしがね', 880);
INSERT INTO Shohin VALUES ('0008', 'ボールペン',100);
データの確認
select * from shohin;
成功してたらこんな感じで表示されます。
shohin_id | name | price
-----------+----------------+-------
0001 | Tシャツ | 1000
0002 | 穴あけパンチ | 500
0003 | カッターシャツ | 4000
0004 | 包丁 | 3000
0005 | 圧力鍋 | 6800
0006 | フォーク | 500
0007 | おろしがね | 880
0008 | ボールペン | 100
(8 rows)
pgAdminでデータ追加&確認
Serverを右クリックし 作成 > サーバ を押します。
一般の名称は自分の好きな名前をつけてください。
接続の方で、先程設定した情報を入力します
psqlで追加した場合は、
「データベース」>「sample」>「スキーマ」>「public」>「テーブル」>「shohin」 と進み、shohinを右クリックしてデータの閲覧ができます。
psqlで追加してない場合は、
上の「ツール」>「クエリツール」からテーブルとデータを追加できます。
psqlの方と同じsqlを実行してください。
JDBIを使ってktorでDBに接続
build.gradleに追加します。
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
....
implementation "org.postgresql:postgresql:42.2.12" //⇦追加
implementation 'org.jdbi:jdbi3-sqlobject:3.20.0' //⇦追加
implementation 'org.jdbi:jdbi3-kotlin:3.20.0' //⇦追加
}
nameの一覧を表示してみる。
val jdbi = Jdbi.create("jdbc:postgresql://localhost:5435/sample","sample","sample")
.installPlugin(SqlObjectPlugin())
interface ShohinDao {
@SqlQuery("SELECT name FROM shohin")
fun selectNameList(): List<String>
}
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
...
...
...
routing {
get("/") {
val shohinDao: ShohinDao = jdbi.onDemand(ShohinDao::class.java)
val names = shohinDao.selectNameList()
call.respond(names)
}
}
fun main(args...の上に「jdbi」と「ShohinDao」を作成します。
routingの中をこの様に編集します。
これで実行してみると
以下のような結果になります。
[
"Tシャツ",
"穴あけパンチ",
"カッターシャツ",
"包丁",
"圧力鍋",
"フォーク",
"おろしがね",
"ボールペン"
]
shoshinの情報を全て表示してみる。
全ての情報を取得し、kotlinのオブジェクト(data class)にマッピングします。
val jdbi = Jdbi.create("jdbc:postgresql://localhost:5435/sample","sample","sample")
.installPlugin(SqlObjectPlugin())
.installPlugin(KotlinPlugin()) //⇦追加 これでkotlinのオブジェクトに当てはめれる
interface ShohinDao {
@SqlQuery("SELECT name FROM shohin")
fun selectNameList(): List<String>
@SqlQuery("SELECT * FROM shohin")
fun selectAll(): List<Shohin>
}
data class Shohin(
@ColumnName("shohin_id") // 名前が違う場合はこれでできる
val id: String,
val name: String,
val price: Int
)
...
...
...
routing {
get("/") {
val shohinDao: ShohinDao = jdbi.onDemand(ShohinDao::class.java)
val shohin = shohinDao.selectAll()
call.respond(shohin)
}
}
これで実行してみると
以下のような結果になります。
[
{
"id": "0001",
"name": "Tシャツ",
"price": 1000
},
{
"id": "0002",
"name": "穴あけパンチ",
"price": 500
},
{
"id": "0003",
"name": "カッターシャツ",
"price": 4000
},
{
"id": "0004",
"name": "包丁",
"price": 3000
},
{
"id": "0005",
"name": "圧力鍋",
"price": 6800
},
{
"id": "0006",
"name": "フォーク",
"price": 500
},
{
"id": "0007",
"name": "おろしがね",
"price": 880
},
{
"id": "0008",
"name": "ボールペン",
"price": 100
}
]
無事dbの情報を表示することができました!
お疲れ様でした
おまけ
依存関係のバージョンに問題があって気づかず少しハマりました。
確認したらSLF4Jでjava.lang.NoSuchMethodErrorが出ていました。
バージョンを上げることで解決しました
Author And Source
この問題について(Ktor(kotlin)でJDBIを使う with postgres), 我々は、より多くの情報をここで見つけました https://qiita.com/toki_k/items/1bf9bfe8022f7031b029著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .