UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Doma】Spring Boot アプリケーションからPostgresに接続する

Domaを使ってSpring Boot アプリケーションからPostgresに接続する

ドキュメントは以下 springboot-domamaster-maintenance-sample.readthedocs.io

手順はREADMEがわかりやすい github.com

pomの設定は終えた上で

Entityを作る

package com.sample.doma;

import lombok.Data;
import org.seasar.doma.Column;
import org.seasar.doma.Entity;
import org.seasar.doma.Id;
import org.seasar.doma.Table;

@Data
@Entity
@Table(name = "property_mapping")
public class PropertyMapping {

  @Id
  @Column(name = "base_property_id")
  String basePropertyId;

  @Id
  @Column(name = "relate_property_id")
  String relatePropertyId;

  @Id
  @Column(name = "category")
  String category;
}

DAOインターフェースを作る

例として全件取得と複数件登録するメソッドをもつインターフェイスを用意する

@ConfigAutowireable をつけると生成されるDao実装クラスに @Repository@Autowired が付与される

all()の戻りはstreamになるようにしておく

package com.sample.doma;

import org.seasar.doma.BatchInsert;
import org.seasar.doma.Dao;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Stream;

@Dao
@ConfigAutowireable
public interface PropertyMappingDao {
  @Select
  Stream<PropertyMappingTemp> all();

  @BatchInsert(sqlFile = true)
  @Transactional
  int[] insertProperty(List<PropertyMappingTemp> update);
}

META-INF配下にsqlを用意する

ファイル名は次の形式でなければならない
META-INF/Daoのクラスの完全修飾名をディレクトリに変換したもの/Daoのメソッド名.sql

src/main/resources
├── META-INF
│   └── com
│       └── sample
│           └── doma
│               └── PropertyMappingDao
│                   ├── all.sql
│                   └── insertProperty.sql

all.sql

expandを使って、エンティティクラス の定義を参照して自動でカラムのリストに展開するようにする
https://doma.readthedocs.io/en/2.3.0/sql/#expand

select /*%expand*/*
from property_mapping
;

insertProperty.sql

insert into property_mapping
    (base_property_id, relate_property_id, category)
values (
           /*update.basePropertyId*/'base_property_id',
           /*update.relatePropertyId*/'relate_property_id',
           /*update.category*/'category')
on conflict (base_property_id, relate_property_id, category) do nothing
;

アプリケーションを作る

package com.sample.doma;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import java.util.List;
import java.util.stream.Collectors;

@SpringBootApplication
public class SampleApplication {

    public static void main(String[] args) {
        try (ConfigurableApplicationContext context = SpringApplication.run(SampleApplication.class, args)) {
              SampleApplication task = context.getBean(SampleApplication.class);
              task.run();
        }
    }

    private final PropertyMappingDao dao;

    SampleApplication(PropertyMappingDao dao) {
        this.dao = dao;
    }

    public void run() {
        List<PropertyMapping> updated =
            dao
                .all()
                .map(item -> {
                    // 何らかの処理
                })
               .collect(Collectors.toList());
        dao.insertProperty(updated);
    }
}

application.ymlにSQL dialectとPostgresqlの設定を行う

domaのdialectにはPOSTGRESを設定する

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/postgres?stringtype=unspecified
    username: 
    password: 


doma:
  dialect: POSTGRES