LoginSignup
4
3

More than 3 years have passed since last update.

Spring boot+Doma2でめちゃくちゃハマった話

Last updated at Posted at 2020-04-04

経緯

最近コードをきれいにするためにStrutsからSpring bootに乗り換えました。
そのついでにDoma2を導入しようと考えて早速調べながらやってみました。
でも全然うまくいかなかったのでやり遂げて気持ち良いついでに手順を書いとこうと思います。

環境

Springboot 2.2.6
STS4
Maven
Mysql

手順

1.pomにdomaを書く

実はここが一番の難所でした。
ネットに書いている通りやっているのに全くうまくいかんやんと何時間も失いました。

pom.xml

         <dependency>
            <groupId>org.seasar.doma.boot</groupId>
            <artifactId>doma-spring-boot-starter</artifactId>
            <version>1.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.seasar.doma.boot</groupId>
            <artifactId>doma-spring-boot-core</artifactId>
            <version>1.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.seasar.doma</groupId>
            <artifactId>doma</artifactId>
            <version>2.28.0</version>
        </dependency>

ネットにはdoma-spring-boot-starterだけでいいみたいに書いてあるんですけど、うまくいかず上記のようにすると出来ました。
全然わからないので詳しい人教えてください。

2.application.propertiesにDBの設定記述

application.properties
spring.datasource.url=jdbc:mysql://IPアドレス:3306/スキーマ名
spring.datasource.username=ユーザ
spring.datasource.password=パスワード
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.database=MYSQL

3実際に処理を記述する

スクリーンショット 2020-04-04 16.33.44.png

Entityクラス

@EntityでDomaがDTOかどうかを認識しているみたいです。
このアノテーションがないとDAOでエラーが出されます。

Sample.java
package jp.co.sample.bean;

import org.seasar.doma.Entity;

@Entity
public class Sample {
    private int id;
    private long userid;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public long getUserid() {
        return userid;
    }
    public void setUserid(long userid) {
        this.userid = userid;
    }

}


DAO

@Daoは先ほどの@Entityと同様Doma側でDAOであると認識するために必要みたいです。

@ConfigAutowireableがないとDaoをAutowired出来ません。
ここはハマりやすいポイントみたいなのでお気をつけください。

SampleDao.java
package jp.co.sample.dao;

import org.seasar.doma.Dao;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;

import jp.co.sample.bean.Sample;

@Dao
@ConfigAutowireable
public interface SampleDao {

    @Select
    public Sample select(long userid);

}


DAOはインターフェースとして宣言して実装クラスは以下のようにdomaで自動生成してくれるみたいです。
すんごい。

SampleDaoImpl.java
package jp.co.sample.dao;

/** */
@org.springframework.stereotype.Repository()
@javax.annotation.Generated(value = { "Doma", "2.25.1" }, date = "2020-04-04T16:30:55.817+0900")
public class SampleDaoImpl extends org.seasar.doma.internal.jdbc.dao.AbstractDao implements jp.co.sample.dao.SampleDao {

    static {
        org.seasar.doma.internal.Artifact.validateVersion("2.25.1");
    }

    private static final java.lang.reflect.Method __method0 = org.seasar.doma.internal.jdbc.dao.AbstractDao.getDeclaredMethod(jp.co.sample.dao.SampleDao.class, "select", long.class);

    /**
     * @param config the config
     */
    @org.springframework.beans.factory.annotation.Autowired()
    public SampleDaoImpl(org.seasar.doma.jdbc.Config config) {
        super(config);
    }

    @Override
    public jp.co.sample.bean.Sample select(long userid) {
        entering("jp.co.sample.dao.SampleDaoImpl", "select", userid);
        try {
            org.seasar.doma.jdbc.query.SqlFileSelectQuery __query = getQueryImplementors().createSqlFileSelectQuery(__method0);
            __query.setMethod(__method0);
            __query.setConfig(__config);
            __query.setSqlFilePath("META-INF/jp/co/sample/dao/SampleDao/select.sql");
            __query.setEntityType(jp.co.sample.bean._Sample.getSingletonInternal());
            __query.addParameter("userid", long.class, userid);
            __query.setCallerClassName("jp.co.sample.dao.SampleDaoImpl");
            __query.setCallerMethodName("select");
            __query.setResultEnsured(false);
            __query.setResultMappingEnsured(false);
            __query.setFetchType(org.seasar.doma.FetchType.LAZY);
            __query.setQueryTimeout(-1);
            __query.setMaxRows(-1);
            __query.setFetchSize(-1);
            __query.setSqlLogType(org.seasar.doma.jdbc.SqlLogType.FORMATTED);
            __query.prepare();
            org.seasar.doma.jdbc.command.SelectCommand<jp.co.sample.bean.Sample> __command = getCommandImplementors().createSelectCommand(__method0, __query, new org.seasar.doma.internal.jdbc.command.EntitySingleResultHandler<jp.co.sample.bean.Sample>(jp.co.sample.bean._Sample.getSingletonInternal()));
            jp.co.sample.bean.Sample __result = __command.execute();
            __query.complete();
            exiting("jp.co.sample.dao.SampleDaoImpl", "select", __result);
            return __result;
        } catch (java.lang.RuntimeException __e) {
            throwing("jp.co.sample.dao.SampleDaoImpl", "select", __e);
            throw __e;
        }
    }

}

Serivceクラス

この例ではServiceクラスはほぼ無意味になってしまいますね。

SampleService.java
package jp.co.sample.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jp.co.sample.bean.Sample;
import jp.co.sample.dao.SampleDao;

@Service
public class SampleService {

    @Autowired
    SampleDao dao;

    public Sample getSample(long userid) {
        return dao.select(userid);
    }
}

Controllerクラス

SampleController.java
package jp.co.sample.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import jp.co.sample.bean.Sample;
import jp.co.sample.service.SampleService;

@RequestMapping("/sample")
@Controller
public class SampleController {

    @Autowired
    SampleService service;

    @RequestMapping("/index")
    public String index(Model model) {
        Sample sample =  service.getSample(1234567);
        model.addAttribute("bean", sample);
        return "index";
    }
}

以上で処理の記述は終わりです。
Spring bootを起動してエラーが出なければ無事成功です。

よくあるエラーとして、フォルダ構成は合っているのに対象のsqlファイルがありませんと怒られることがあります。
それはプロジェクトの更新をした際にビルドパスの設定がおかしくなることがありますので以下のリンクを参考にしてみてください。
https://qiita.com/nesheep5/items/37bd1913211fcf3aebf1

感想

本当に何時間も費やしてできると気持ちがいいですね。
Domaでこれからたくさんsql文を流していきたいと思います。
あとDomaはログにsql文が勝手に出るからすっごいいいね。
スクリーンショット 2020-04-03 23.14.20.png

4
3
1

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
4
3