Help us understand the problem. What is going on with this article?

猿でも作れるサーバサイドKotlin入門【Spring Boot, Doma2】Part1

初めに

この記事を見ているということはもうKotlinが熱い!っていう話をする必要はないと思いますが、KotlinはJavaとの互換性が高く、将来的にはAndroid、iPhone、Webを全てKotlinで書くようになるかもしれません。アツイ!!
現在では企業が続々とKotlinを開発に取り入れており、方々でその有用性がうたわれています。
・「Kotlinで書くとJavaには戻れない」Androidアプリ開発にKotlinを導入したヤフーが感じたメリット
・Android開発を受注したからKotlinをガッツリ使ってみたら最高だった

僕はインターン先であるZOZOテクノロジーズのAndroidエンジニアの方に聞いてKotlinの存在を知りました。

Kotlinを用いてWebで何かしてみたいと思い、少し勉強しようとしたところ、なかなか情報が出てきません(Androidアプリを作ったりするやつはありますがサーバサイドの情報があまり出てこない、、)。

この記事はそんなKotlinである程度のWebアプリを作ってみたい!という人のためのものです。チュートリアル的な役割を果たせれば幸いです。

今回は名刺作成のWebアプリを作ってみます!(フレームワークはSpring Boot、Doma2を用います)
できるアプリの外観は以下の画像のような感じです。

スクリーンショット 2018-12-02 17.02.30.png
「Hello Kotlin!」をクリックすると
スクリーンショット 2018-12-02 17.02.41.png
プロフィール一覧へ移動します(ここには作成済みの名刺のリストが表示されます)。
左下の作成ボタンを押すと、
スクリーンショット 2018-12-02 17.03.05.png
このようなプロフィール作成画面へ移ります。
スクリーンショット 2018-12-02 17.04.23.png
情報を入力して「作成」ボタンを押すと
スクリーンショット 2018-12-02 17.04.45.png
作成された名刺が表示されます!(電話番号はテキトーです)
スクリーンショット 2018-12-02 17.05.01.png
プロフィール一覧画面へ戻ると作成した名刺が追加されていて、横の編集ボタンを押すと
スクリーンショット 2018-12-02 17.05.17.png
このように情報の編集ができます。

では作っていきましょう!
なおこの記事は
・サーバーサイドKotlin (Spring Boot / Doma 2) 入門
こちらの記事を参考にさせていただいてます。
ぜひこちらも見てみてください!

他にも
・プログラマに優しい現実指向JVM言語 Kotlin入門
・Spring Boot (Kotlin) はじめの一歩
これらの記事もKotlinを進める上で参考になると思いますので、ぜひ参照してみてください。

この記事で作る最終的なアプリケーションはGitHubにソースコードをあげています。
(お役に立てればGitHub上でstarをつけてもらえると嬉しいです!)
・GitHubのレポジトリはこちら

準備

それでは準備に入っていきます!

IntelliJのインストール(すでに入ってる人は飛ばしてください)

スクリーンショット 2018-12-08 15.08.45.png

まずはIntelliJ IDEA(インテリジェイ アイディア)をインストールします。IntelliJはJetBrains社が開発した、Javaを中心とした数多くのプログラミング言語に対応した統合開発環境(開発で必要な動作をGUIで行える便利なツール)です。
(余談ですが、実はKotlinもJetBrains社のエンジニアが開発した言語なのです!)

  1. こちらのページへアクセスします。今回はWebアプリケーションなのでUltimateのダウンロードをクリックしてください!
  2. 「idealU-2018.3.dmg」のような名前でダウンロードされるのでダウンロードできたらクリックして立ち上げてみます。
  3. 無事立ち上げられれば完了です!(学生ライセンスを用いている人など色々なパターンが存在すると思うので自分の環境に合わせてIntelliJを使えるようにしてください。)

より詳しくはこの記事などを参考にしてみてください!
・【初心者向け】すぐできるIntelliJ IDEAの最初の使い方

JDKのインストール(すでに入ってる人は飛ばしてください)

次にJavaを使えるようにするためJDK(Java Development Kit)をインストールします(KotlinはJavaを拡張した言語であるためJavaを自身の環境にインストールする必要があります)。
僕のPCにはデフォルトでインストールされていたのですが、もしインストールされてなければ
1. Oracleのサイトのダウンロードページへアクセスします。
2. DOWNLOADボタンを押すと環境ごとのインストールページへ遷移します。
スクリーンショット_2018-12-03_0_31_53.png
3. Licenseを読んで、よければAccept License Agreementにチェックを入れて、自身の環境に合ったものをインストールしてください。
スクリーンショット_2018-12-03_0_33_37.png
4. ダウンロードできたら自身のPCでクリックして開いてインストールウィザードに従ってインストールを完了させましょう。
5. 正常にインストールされたというウィンドウが出たらインストール完了です!

Dockerのインストール(すでに入ってる人は飛ばしてください)

DockerとはDocker Inc.(旧DotCloud社)によって開発されたコンテナ仮想化ツールです。簡単に言うとめんどくさい環境構築の手間を省いてくれる素晴らしいツールです(他にも多くの使い方があります)。ぜひご自分でも調べてみてください。
1. まずDockerをダウンロードするページへアクセスし、「Download from Docker Store」をクリックします。
2. 次に「Please Login to Download」をクリックします。
3. そして「Create Account」をクリックしてDocker IDを作成しましょう。
4. 自身のPCにインストールされた「Docker.dmg」を開きましょう。
5. ドラッグ&ドロップしてインストールを環境させてください。
スクリーンショット 2018-12-03 1.31.51.png
6. そしてDockerを起動後、Docker IDでログインしてください。これでDockerが使えるようになります!

5分でアプリを立ち上げてみる!(忙しい人用)

順を追って自分でコードを書いてで立ち上げたいという方は飛ばしてください!

急いでいて動作確認だけしたいという方は以下の手順を取ってもらえれば自分のPCでアプリケーションの動作を確認することができます。

最終的なアプリケーションのコードをクローンしてdockerで立ち上げます。
(参考になればstarをつけて頂けると嬉しいです!)

$ git clone git@github.com:shierote/kotlin-example.git
$ cd kotlin-example
$ docker-compose up

ターミナルを別タブで開いて

$ cd ~/(kotlin-exampleをインストールしたディレクトリ)/kotlin-example
$ ./gradlew clean bootRun

そしてhttp://localhost:8080にアクセスしてみましょう。見事、画面が表示されれば立ち上げ完了です!

ひな形を作ってIntelliJで開く

さていよいよアプリケーションを作っていきます!

Spring Initializrでひな形を作る

ひな形はSpring Initializrを使って作成します。
Spring Initializrにアクセスすると次のようなページが表示されます。ここで今回のアプリケーションの設定を行います。
スクリーンショット 2018-12-03 0.48.12.png

  1. まず環境を選択します。セレクトボックスで選択ができます。それぞれ「Grandle Project」「Kotlin」「2.1.1」を選択しましょう。
  2. プロジェクト名を指定します。なんでも良いですが、特に指定がなければ今回は「kotlin-spring-boot-doma-demo」とします。
  3. ここが忘れがちなのですが、タグ形式でより詳細な設定をします。「Search for dependencies」で検索してそれぞれ「Web」「DevTools」「Thymeleaf(タイムリーフ)」を選択します。 スクリーンショット_2018-12-03_0_49_26.png 設定をしたら「Generate Project」ボタンを押してください。 ひな形をzip形式でダウンロードすることができます。 先ほどダウンロードしたzipファイルをクリックして解凍してください。

IntelliJ IDEAで開く

IntelliJをクリックした後、次のような画面が表示されます。
スクリーンショット 2018-12-03 2.13.16.png
「Open」をクリックして、先ほど解凍して生成されたフォルダを選択し、開きます。
すると以下のような画面が表示されますが、何も変えずに「OK」を押してください。
スクリーンショット_2018-12-03_2_18_16.png
もしJVMをインストールしていないと図のピンクの部分が選択されず開けないと思うのでJVMをインストールしてください。

次の項目からいよいよページを作っていきます!

ホーム画面を作る

スクリーンショット 2018-12-02 17.02.30.png
さてまず始めにホーム画面を作ります!
IntelliJ上で src/main/kotlin/com/example/kotlinspringbootdomademoのフォルダを右クリックして「Kotlin File/Class」を選択してください。
スクリーンショット 2018-12-03 2.35.54.png
Buildが終わっていないと下の画像のように「Kotlin File/Class」が選択肢に出てこないのでBuildが終わるまで待ってみてください。なおテンプレートを編集する場合は「Edit Template File」を選択するとテンプレートを編集することができます!
スクリーンショット_2018-12-03_2_26_39.png

「Kotlin File/Class」を選択できたら下図のようなメニューが現れます。
Nameを HomeController 、Kindを Classにしてファイルを作成してください。

スクリーンショット 2018-12-03 2.52.15.png

そして以下のようにファイルを編集します。

src/main/kotlin/com/example/kotlinspringbootdomademo/HomeController.kt
package com.example.kotlinspringbootdomademo

import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping


@Controller
class HomeController {
    @GetMapping("")
    fun index(model: Model): String {
        model.addAttribute("message", "Hello Kotlin!")
        return "home"
    }
}

@GetMappingはSpringが提供するアノテーションです。アノテーションについてはこちらの記事などを参考にしてください。
・Spring FrameworkのControllerの基本的なアノテーション

そしてHTMLを作成します。
src/main/resources/templatesのフォルダを右クリックしてみてください。
新たにファイルを追加するときはファイルを作りたい親フォルダを右クリックして「New」->「File」をクリックします。
スクリーンショット 2018-12-03 3.07.51.png
そしてファイル名を入力します。
スクリーンショット 2018-12-03 3.08.06.png

ここでHTMLテンプレートにはThymeleaf(タイムリーフ)を使用しています。
Thymeleafでは th:~とすることでKotlinと関連づけて様々なHTMLを生成することができます。
ここではth:text="${message}"でControllerから受け取った変数messageの値("Hello Kotlin!")を出力しています。
(Railsでいう <%= %>などに近いです。)
タイムリーフの他の使い方については以下の記事などを参照してください。
・Spring Boot で Thymeleaf 使い方メモ

ファイルを作成後、内容は以下のようにしてください。

src/main/resources/templates/home.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>名刺作成アプリ</title>
    <link th:href="@{/css/app.css}" rel="stylesheet" />
</head>
<body>
<div class="container">
    <a class="hello-title" th:text="${message}" th:href="@{/customers}"></a>
</body>
</div>
</html>

上のファイルの <link th:href="@{/css/app.css}" rel="stylesheet" />では /css/app.cssのcssファイルを読み込むよう設定しています。こうすることによりCSSを外部ファイル化することができます( src/main/resources/static/との相対パスです)。
ディレクトリを作りたい時も同様に、親フォルダを右クリックして「New」->「Directory」をクリックしてディレクトリ名を決めます。
スクリーンショット 2018-12-03 3.07.51.png

CSSは今回のメインではないので以下のファイルの内容をコピペしてください(HOMEも含め全ページのCSSが含まれています、330行近く)。
・『こちらのファイル』にアクセスして全文をコピペ!
また cssディレクトリを作成する時も同様に右クリックで作成してください。

src/main/resources/static/css/app.css
:root {
    --mcolor: #C12B2B;
    --bcolor: #150E0E;
    --fcolor: #FFFFFF;
    --scolor: #707070;
}

html, body {
    height: 96%;

}
.
.
.
/* 全文はURLにアクセスして確認 */

ここまでファイルを作成したら一度起動コマンドを叩いてブラウザで確認してみましょう。
プロジェクトディレクトリ(今回で言えば「kotlin-spring-boot-doma-demo」)に移動して以下のコマンドを叩いてみてください。

$ cd kotlin-spring-boot-doma-demo
$ ./gradlew clean bootRun

エラーが出ずに立ち上げができたら(コマンドが完了せずに立ち上がったままの状態)http://localhost:8080/にアクセスしてみてください!無事以下のように表示されたら成功です!
スクリーンショット 2018-12-02 17.02.30.png

今「Hello Kotlin!」をクリックすると、下のようなエラーが出ます。ここからプロフィール詳細ページ(http://localhost:8080/customers)を作ってちゃんとページが表示されるようにしましょう!
スクリーンショット 2018-12-03 4.00.19.png

DB(Postgresql、Docker)、Doma2の準備

DB(Postgresql、Docker)の作成

プロフィール一覧画面ではデータベースからデータを呼び出しているのでページを作る前にまずデータベースを作る必要があります。ここからDBを作ってアプリと関連させていきましょう!

DBはdockerを用いて設定していきます。またPostgreSQLを使用します。

以下の3ファイルを作成してdockerを立ち上げます。

~(kotlin-spring-boot-doma-demo)/docker-compose.yml
version: "3"
services:
  postgres:
    build: ./docker/postgres/
    image: kotlin-demo-postgres
    ports:
      - 5432:5432
    container_name: kotlin-demo-postgres-container
~/docker/postgres/Dockerfile
FROM postgres:9.5.3

COPY ./docker-entrypoint-initdb.d /docker-entrypoint-initdb.d
~/docker/postgres/docker-entrypoint-initdb.d/init-db.sh
#!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
    CREATE DATABASE kotlindemo;
EOSQL

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" kotlindemo <<-EOSQL
    BEGIN;

    create table customer (
        id serial,
        name varchar(50),
        email varchar(50),
        phone_number varchar(50),
        github_name varchar(50),
        twitter_name varchar(50),
        main_org varchar(50),
        sub_org varchar(50)
    );

    insert into customer(name, email, github_name, phone_number, twitter_name, main_org, sub_org) values ('hoge', 'hoge@example.com', 'hoge', 'hoge', 'hoge','hoge','hoge');
    insert into customer(name, email, github_name, phone_number, twitter_name, main_org, sub_org) values ('fuge', 'fuge@example.com', 'hoge', 'hoge', 'hoge','hoge','hoge');
    insert into customer(name, email, github_name, phone_number, twitter_name, main_org, sub_org) values ('piyo', 'piyo@example.com', 'hoge', 'hoge', 'hoge','hoge','hoge');

    COMMIT;
EOSQL

ここまで設定できたらdockerを立ち上げましょう。

$ docker-compose up

Creating kotlin-demo-postgres-container ... done
Attaching to kotlin-demo-postgres-container
kotlin-demo-postgres-container | The files belonging to this database system will be owned by user "postgres".
kotlin-demo-postgres-container | This user must also own the server process.
kotlin-demo-postgres-container |
kotlin-demo-postgres-container | The database cluster will be initialized with locale "en_US.utf8".
kotlin-demo-postgres-container | The default database encoding has accordingly been set to "UTF8".
kotlin-demo-postgres-container | The default text search configuration will be set to "english".
kotlin-demo-postgres-container |
kotlin-demo-postgres-container | Data page checksums are disabled.
kotlin-demo-postgres-container |
kotlin-demo-postgres-container | fixing permissions on existing directory /var/lib/postgresql/data ... ok
kotlin-demo-postgres-container | creating subdirectories ... ok
kotlin-demo-postgres-container | selecting default max_connections ... 100
kotlin-demo-postgres-container | selecting default shared_buffers ... 128MB
kotlin-demo-postgres-container | selecting dynamic shared memory implementation ... posix
kotlin-demo-postgres-container | creating configuration files ... ok
kotlin-demo-postgres-container | creating template1 database in /var/lib/postgresql/data/base/1 ... ok
kotlin-demo-postgres-container | initializing pg_authid ... ok
kotlin-demo-postgres-container | initializing dependencies ... ok
kotlin-demo-postgres-container | creating system views ... ok
kotlin-demo-postgres-container | loading system objects' descriptions ... ok
kotlin-demo-postgres-container | creating collations ... ok
kotlin-demo-postgres-container | creating conversions ... ok
kotlin-demo-postgres-container | creating dictionaries ... ok
kotlin-demo-postgres-container | setting privileges on built-in objects ... ok
kotlin-demo-postgres-container | creating information schema ... ok
kotlin-demo-postgres-container | loading PL/pgSQL server-side language ... ok
kotlin-demo-postgres-container | vacuuming database template1 ... ok
kotlin-demo-postgres-container | copying template1 to template0 ... ok
kotlin-demo-postgres-container | copying template1 to postgres ... ok
kotlin-demo-postgres-container | syncing data to disk ... ok
kotlin-demo-postgres-container |
kotlin-demo-postgres-container | Success. You can now start the database server using:
kotlin-demo-postgres-container |
kotlin-demo-postgres-container |     pg_ctl -D /var/lib/postgresql/data -l logfile start
kotlin-demo-postgres-container |
kotlin-demo-postgres-container |
kotlin-demo-postgres-container | WARNING: enabling "trust" authentication for local connections
kotlin-demo-postgres-container | You can change this by editing pg_hba.conf or using the option -A, or
.
.
.

DB(PostgreSQL)の内容を確認したいときは以下のコマンドを叩いて確認してみましょう(ターミナルで別ウインドウを開いて実行してみましょう)。

$ docker exec -it kotlin-demo-postgres-container psql -U postgres kotlindemo


psql (9.5.3)
Type "help" for help.

kotlindemo=# select * from customer;
 id | name |      email       | phone_number | github_name | twitter_name | main_org | sub_org
----+------+------------------+--------------+-------------+--------------+----------+---------
  1 | hoge | hoge@example.com | hoge         | hoge        | hoge         | hoge     | hoge
  2 | fuge | fuge@example.com | hoge         | hoge        | hoge         | hoge     | hoge
  3 | piyo | piyo@example.com | hoge         | hoge        | hoge         | hoge     | hoge
(3 rows)

kotlindemo=#

上記のように表示されていれば成功です!
うまくテーブルが作成されていないときは docker-compose upが正常にできていない場合が多いので docker-composeのコマンドを打って確認してみましょう。こちらの記事でコマンドがまとめられています。
・docker-compose コマンドまとめ

Doma2の準備

ここまでできたら次はDBとKotlinのアプリを繋げるためにDoma2の準備をします。Doma2はJava製のDBアクセスフレームワーク(DBに接続するための作業を色々やってくれるやつ)で、2-way SQL(SQLファイルを外部ファイル化できる)のが特徴です。
Doma2の詳細についてはこちらの公式ドキュメントを見てみて下さい!
Doma2公式ドキュメント

Doma2の設定をするため、次のファイルのすでにある内容を削除して以下のように書き換えて下さい。

~/build.gradle
buildscript {
    ext {
        kotlinVersion = '1.2.70'
        springBootVersion = '2.1.0.RELEASE'
        postgresqlVersion = '42.1.4'
        springBootDomaVersion = '1.1.1'
        domaVersion = '2.19.0'
    }
    repositories {
        mavenCentral()
        maven {url 'https://oss.sonatype.org/content/repositories/snapshots/'}
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.70")
        classpath("org.jetbrains.kotlin:kotlin-allopen:1.2.70")
    }
}

apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
compileKotlin {
    kotlinOptions {
        freeCompilerArgs = ["-Xjsr305=strict"]
        jvmTarget = "1.8"
    }
}
compileTestKotlin {
    kotlinOptions {
        freeCompilerArgs = ["-Xjsr305=strict"]
        jvmTarget = "1.8"
    }
}

repositories {
    mavenCentral()
}

apply plugin: 'java'
processResources.destinationDir = compileJava.destinationDir
compileJava.dependsOn processResources

dependencies {
    implementation('org.springframework.boot:spring-boot-starter-thymeleaf')
    implementation('org.springframework.boot:spring-boot-starter-web')
    implementation('com.fasterxml.jackson.module:jackson-module-kotlin')
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    runtimeOnly('org.springframework.boot:spring-boot-devtools')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
    compile "org.postgresql:postgresql:42.1.4"
    compile "org.seasar.doma:doma:2.19.0"
    compile "org.seasar.doma.boot:doma-spring-boot-starter:1.1.1"
}

application.propertiesをyml形式に直すため、ファイル名を application.ymlに変更します。そしてapplication.ymlでdomaがpostgresを使うこと、またデータベースの各種設定を記述します。
(本番にあげる場合はセキュリティの問題があるので、username、passwordを変更した上で環境変数化する必要がありますが、今回は扱いません。ご自分で調べていただけるとです。)

src/main/resources/application.yml
doma:
  dialect: postgres

spring.datasource.driver-class-name: org.postgresql.Driver
spring.datasource.url: jdbc:postgresql://localhost:5432/kotlindemo
spring.datasource.username: postgres
spring.datasource.password:

ここからは src/main/java配下にDomaの設定を追加していきます。
まずDomaのEntityを作成します。Entity(エンティティ)とは、データベースのテーブルやクエリの結果セットに対応したもので、アプリケーション上でのクラスとDBの紐づけをしています。
より詳しくは以下のドキュメントを参照してください。

・Doma Entity 公式ドキュメント
今回のようにかなり多くのディレクトリを作成しなければいけない時、非常にめんどくさいので僕は以下のようにmkdirコマンドにpオプション(parent)をつけて一気に作成しています。よければ参考にしてください。

$ mkdir -p src/main/java/com/example/kotlinspringbootdomademo/infrastructure/doma/entity/
src/main/java/com/example/kotlinspringbootdomademo/infrastructure/doma/entity/CustomerDomaEntity.java
package com.example.kotlinspringbootdomademo.infrastructure.doma.entity;

import org.seasar.doma.*;
import org.seasar.doma.jdbc.entity.NamingType;

@Entity(naming = NamingType.SNAKE_UPPER_CASE)
@Table(name = "customer")
public class CustomerDomaEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer id;

    public String name;

    public String email;

    public String phone_number;

    public String github_name;

    public String twitter_name;

    public String main_org;

    public String sub_org;
}

そしてDomaのDaoインターフェースを作成します。
Data Access Object (Dao) はデータベースアクセスのためのインタフェースです。外部化したSQLファイルへの呼び出しを定義します。
より詳しくは以下のドキュメントを参照してください。
・Doma Dao 公式ドキュメント

src/main/java/com/example/kotlinspringbootdomademo/infrastructure/doma/dao/CustomerDomaDao.java
package com.example.kotlinspringbootdomademo.infrastructure.doma.dao;

import com.example.kotlinspringbootdomademo.infrastructure.doma.entity.CustomerDomaEntity;
import org.seasar.doma.boot.ConfigAutowireable;
import org.seasar.doma.*;

import java.util.List;

@ConfigAutowireable
@Dao
public interface CustomerDomaDao {
    @Select
    List<CustomerDomaEntity> selectAll(); //呼び出すファイル名の指定(selectAll.sql)
}

そして上記で呼び出しているSQLファイルを作成します。

src/main/resources/META-INF/com/example/kotlinspringbootdomademo/infrastructure/doma/dao/CustomerDomaDao/selectAll.sql
select
    /*%expand*/*
from
    customer
order by
    id desc

ここまででJavaコードによるDomaの設定は終わりです。ここからいよいよプロフィール一覧画面を作っていきましょう!

プロフィール一覧画面を作る

スクリーンショット 2018-12-08 15.12.48.png
プロフィール一覧画面を作っていきます!
まずドメインのモデルを作成します!

src/main/kotlin/com/example/kotlinspringbootdomademo/domain/model/Customer.kt
package com.example.kotlinspringbootdomademo.domain.model

data class Customer(val id: Int? = null, val name: String, val email: String, val phone_number: String, val github_name: String, val twitter_name: String, val main_org: String, val sub_org: String)

Repositoryのインターフェースを実装します。

src/main/kotlin/com/example/kotlinspringbootdomademo/domain/repository/CustomerRepository.kt
package com.example.kotlinspringbootdomademo.domain.repository

import com.example.kotlinspringbootdomademo.domain.model.Customer

interface CustomerRepository {
    fun findAll(): List<Customer>
}

Repositoryの実装を作成します(ここでDomaのEntity(Java)をドメインのModel(Kotlin)に詰め替えています)。

src/main/kotlin/com/example/kotlinspringbootdomademo/infrastructure/domarepository/CustomerRepositoryDomaImpl.kt
package com.example.kotlinspringbootdomademo.infrastructure.domarepository

import com.example.kotlinspringbootdomademo.domain.model.Customer
import com.example.kotlinspringbootdomademo.domain.repository.CustomerRepository
import com.example.kotlinspringbootdomademo.infrastructure.doma.dao.CustomerDomaDao
import com.example.kotlinspringbootdomademo.infrastructure.doma.entity.CustomerDomaEntity
import org.springframework.stereotype.Repository

@Repository
class CustomerRepositoryDomaImpl(
        private val customerDomaDao: CustomerDomaDao
): CustomerRepository {
    override fun findAll(): List<Customer> {
        return customerDomaDao.selectAll().map { _mapToModel(it) }
    }

    private fun _mapToModel(domaEntity: CustomerDomaEntity): Customer {
        return Customer(
                id = domaEntity.id,
                name = domaEntity.name,
                email = domaEntity.email,
                phone_number = domaEntity.phone_number,
                github_name = domaEntity.github_name,
                twitter_name = domaEntity.twitter_name,
                main_org = domaEntity.main_org,
                sub_org = domaEntity.sub_org
        )
    }
}
src/main/kotlin/com/example/kotlinspringbootdomademo/application/controller/web/CustomerController.kt
package com.example.kotlinspringbootdomademo.application.controller.web

import com.example.kotlinspringbootdomademo.domain.repository.CustomerRepository
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping

@Controller
@RequestMapping("/customers")
class CustomerController(
        private val customerRepository: CustomerRepository
) {
    @GetMapping("")
    fun index(model: Model): String {
        val customers = customerRepository.findAll()
        model.addAttribute("customers", customers)
        return "customers/index"
    }
}
src/main/resources/templates/customers/index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>名刺作成アプリ</title>
    <link th:href="@{/css/app.css}" rel="stylesheet" />
</head>
<body>
<div class="container">
    <div class="index-wrapper">
        <h1 class="index-title">プロフィール一覧</h1>
<ul th:unless="${customers.isEmpty()}">
    <li th:each="customer: ${customers}">
        <a th:text="${customer.name}" th:href="@{/customers/__${customer.id}__}" class="customer-name"></a>
        <a th:href="@{/customers/__${customer.id}__/edit}" class="customer-edit">編集</a>
        <form th:object="${customer}" th:action="@{/customers/__${customer.id}__}" th:method="delete">
            <input type="submit" value="削除" class="customer-delete"/>
        </form>
    </li>
</ul>
    <a th:href="@{/customers/new}" th:class="new-btn">作成</a>
    </div>
</div>
</body>
</html>

ここまで編集できたら bootRunを一度 で切って再起動します。

$ ./gradlew clean bootRun

そしてエラーが出ずに立ち上げができたらhttp://localhost:8080/にアクセスしてみてください!無事以下のように表示されたら成功です!
まだ詳細ページを見ること、作成、編集、削除をできるようにしていないのでこの状態で他のページにアクセスするとエラーになります。

スクリーンショット 2018-12-08 15.12.48.png

長くなったのでPart1はこの辺にしようと思います!

参考になれば是非いいねをお願いします!

Part2も近日中に公開します!

・GitHubのレポジトリ
・猿でも作れるサーバサイドKotlin入門【Spring Boot, Doma2】Part2(近日公開)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした