3.3. インフラストラクチャ層の実装¶
インフラストラクチャ層では、RepositoryImplの実装を行う。
RepositoryImplは、Repositoryインタフェースで定義したメソッドの実装を行う。
3.3.1. RepositoryImplの実装¶
以下に、MyBatis3とJPAを使って、リレーショナルデータベース用のRepositoryを作成する方法を紹介する。
3.3.1.1. MyBatis3を使ってRepositoryを実装¶
リレーショナルデータベースとの永続APIとしてMyBatis3を使う場合、MyBatis3から提供されている「Mapperインタフェースの仕組みについて」を利用してRepositoryインタフェースを作成すると、基本的にはRepositoryImplを実装する必要はない。
これは、MyBatis3が、Mapperインタフェースのメソッドと呼び出すステートメント(SQL)のマッピングを自動で行う仕組みになっているためである。
MyBatis3を使用する場合、アプリケーション開発者は、
- Repositoryインタフェース(メソッドの定義)
- マッピングファイル(SQLとO/Rマッピングの定義)
の作成を行う。
Repositoryインタフェース(Mapperインタフェース)の作成例
package com.example.domain.repository.todo; import com.example.domain.model.Todo; // (1) public interface TodoRepository { // (2) Todo findByTodoId(String todoId); }
項番 説明 (1)POJOのインタフェースとして作成する。
MyBatis3のインタフェースやアノテーションなどを指定する必要はない。
(2)Repositoryのメソッドを定義する。
基本的には、MyBatis3のアノテーションを付与する必要はないが、一部のケースでアノテーションを指定する事もある。
マッピングファイルの作成例
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- (3) --> <mapper namespace="com.example.domain.repository.todo.TodoRepository"> <!-- (4) --> <select id="findByTodoId" parameterType="string" resultMap="todoResultMap"> SELECT todo_id, title, finished FROM t_todo WHERE todo_id = #{todoId} </select> <!-- (5) --> <resultMap id="todoResultMap" type="Todo"> <result column="todo_id" property="todoId" /> <result column="title" property="title" /> <result column="finished" property="finished" /> </resultMap> </mapper>
項番 説明 (3)Repositoryインタフェース毎にマッピングファイルを作成する。
マッピングファイルのネームスペース(
mapper
要素のnamespace
属性)には、RepositoryインタフェースのFQCN(Fully Qualified Class Name)を指定する。(4)Repositoryインタフェースに定義したメソッド毎に実行するステートメント(SQL)の定義を行う。
ステートメントID(各ステートメント要素(
select
/insert
/update
/delete
要素のid
属性)には、Repositoryインタフェースのメソッド名を指定する。(5)クエリを発行する場合は、必要に応じてO/Rマッピングの定義を行う。
シンプルなO/Rマッピングであれば自動マッピングを利用する事ができるが、複雑なO/Rマッピングを行う場合は、個別にマッピングの定義が必要となる。
上記例のマッピング定義は、シンプルなO/Rマッピングなので自動マッピングを利用する事もできる。
3.3.1.2. JPAを使ってRepositoryを実装¶
org.springframework.data.jpa.repository.JpaRepository
を使用すると、非常に簡単にRepositoryを作成することが出来る。TodoRepository.java
public interface TodoRepository extends JpaRepository<Todo, String> { // (1) // omitted }
項番 説明 (1)JpaRepositoryを継承したインタフェースを定義するだけで、Todoエンティティに対する基本的なCRUD操作を実装なしで実現できる。
TodoRepository.java
public interface TodoRepository extends JpaRepository<Todo, String> { @Query("SELECT COUNT(t) FROM Todo t WHERE finished = :finished") // (1) long countByFinished(@Param("finished") boolean finished); // omitted }
項番 説明 (1)@Query
アノテーションで、クエリ(JPQL)を指定する。