27
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MyBatisでjava8のjava.time.LocalDateTimeを扱う

Last updated at Posted at 2015-03-11

# 概要
業務でMyBatisを使っているのですがjavaのバージョンを8に上げるにあたり、折角Date and Time API (JSR 310) で日付関連が便利になったと言われているので、DTOのフィールドをLocalDateTimeにしようとして調べた結果です。

MyBatisの公式ドキュメントに書いてあったので簡単にできました。

table (mysql)

CREATE TABLE `sample` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `created` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

結果を格納するDTO

sample.domain.SampleDto.java
import java.time.LocalDateTime;
import lombok.Data;

@Data
public class SampleDto {
    private int id;
    private LocalDateTime created;
}

このcreatedをSQLの結果とマッピングしたい。

## TypeHandler
どうやらorg.apache.ibatis.type.TypeHandlerorg.apache.ibatis.type.BaseTypeHandlerを実装してjdbcのクラスとマッピングすると良いよって事らしい。
今回はBaseTypeHandlerを実装してみました。

sample.mybatis.handlers.LocalDateTimeTypeHandler.java
@MappedTypes(LocalDateTime.class)
public class LocalDateTimeTypeHandler
        extends BaseTypeHandler<LocalDateTime> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType) throws SQLException {
        ps.setTimestamp(i, Timestamp.valueOf(parameter));
    }

    @Override
    public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Timestamp timestamp = rs.getTimestamp(columnName);
        if (timestamp == null) {
            return null;
        } else {
            return timestamp.toLocalDateTime();
        }
    }

    @Override
    public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        Timestamp timestamp = rs.getTimestamp(columnIndex);
        if (timestamp == null) {
            return null;
        } else {
            return timestamp.toLocalDateTime();
        }
    }

    @Override
    public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        Timestamp timestamp = cs.getTimestamp(columnIndex);
        if (timestamp == null) {
            return null;
        } else {
            return timestamp.toLocalDateTime();
        }
    }
}

## mybatis-config.xml

mybatis-config.xmlに作成したTypeHandlerを探すように設定を追加します。

mybatis-config.xml
<configuration>
  <typeHandlers>
    <typeHandler handler="sample.mybatis.handlers.LocalDateTimeTypeHandler"/>
  </typeHandlers>
</configuration>

または

mybatis-config.xml
<configuration>
  <typeHandlers>
    <package name="sample.mybatis.handlers"/>
  </typeHandlers>
</configuration>

同一パッケージにまとめて実装してpackage指定する方が楽かなぁ。

Mapper

public interface SampleMapper {

    @Select("SELECT * FROM sample)
    List<SampleDto> selectAll();

    @Insert("insert into sample (created) values ( #{created} )")
    @SelectKey(before = false, keyProperty = "id", resultType = int.class, statement = { "select last_insert_id()" })
    int insert(SampleDto sampleDto);
}

あとは普通にMapper使うだけで検索・登録ともにDBとマッピングされます。

27
27
2

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
27
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?