Java
jpa
springframework

SpringDataでリポジトリを使ってDBアクセスする。

DBへのアクセスを自動で作成する便利インターフェース

JPAリポジトリとは、DBへのCRUDを自動で実装してくれる便利インターフェースです。
環境を設定してしまえば、相当少ないコード量でDBのアクセス機能が実装できるのですが、環境を設定するまでが結構難儀なのでまとめました。

SpringDataのライブラリを導入する

下の記事を参考に、とりあえずJDBCテンプレートが動くまで。

SpringDataJPAアクセス1
SpringDataJPAアクセス2

リポジトリインターフェースを作る

リポジトリ本体を作ります。

MyPesononalDataDaoRepository.java
package com.tsugaruinfo.repository;

@Repository
public interface MyPesononalDataDaoRepository
    extends JpaRepository<Mypersonaldata, Integer> {

}

ただのインターフェースですね。中身を実装する必要はありません。

リポジトリをDIに登録

Bean構成ファイルにリポジトリを登録します。

appllicatio-config.xml
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">



        <!-- JPA Repository 設定 -->
    <jpa:repositories base-package="com.tsugaruinfo.repository" />

     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="dataSource" ref="dataSource" />
    </bean>


ポイントは二つ

1.名前空間の追加

名前空間にtxとjpaを追加

application-config.xml
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"

スキーマに

application-config.xml
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"

を加えてJPAとTransactionのBeanが使用できるようにします。
Transactionはリポジトリ生成の際に、JPAが勝手に使ってしまうからです。

2.リポジトリのパッケージとTransactionManagerの追加

ここがDI登録のメインですね
jpaのリポジトリパッケージとtransactionManagerというBeanを登録します。

appliction-config.xml
        <!-- JPA Repository 設定 -->
    <jpa:repositories base-package="com.tsugaruinfo.repository" />

     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="dataSource" ref="dataSource" />
    </bean>

実際に使うときは”com.tsugaruinfo.repository”を自分のパッケージに変更してください。
これでリポジトリがDIコンテナに登録されました。

@Autowiredでインジェクションする

今回はServletでの実装です。(まぁ、教本の通りに・・・)

BeanAutowiredFilterServlet.java
public class BeanAutowiringFilterServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


    @Override
    public void init() throws ServletException {
        super.init();
        SpringBeanAutowiringSupport
            .processInjectionBasedOnCurrentContext(this);
    }

このSpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);という命令が@Autowiredアノテーションを使う鍵です。
この命令が走った瞬間、DIに登録されているBeanがアノテーションのついてる変数にインジェクション(注入)されます。

注入するような変数はクラスのフィールドになってると思うので、コンストラクタで実行するといいかもしれません。
今回は親クラスを立てて、サーブレットの初期化メソッドで実行。

SpringBootだと
@SpringBootApplicationというアノテーションで自動で走るみたいですね

インジェクション(注入)して実体化する

MyPersonalDataServlet.java
@WebServlet("/person")
public class MyPersonalDataServlet extends BeanAutowiringFilterServlet {
    private static final long serialVersionUID = 1L;


    @Autowired
    MyPesononalDataDaoRepository repository;

サーブレットのフィールドに注入しました。
newしなくてもJPAとDIコンテナが実体化してくれます。

さっそく実行

サーブレットで実行してみます。
DBの内容を全取得

MyPersonalDataServlet.java
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        List<Mypersonaldata> list = repository.findAll();

        request.setAttribute("entities", list);

        response.getWriter().append("Served at: ").append(request.getContextPath());

        request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
    }
index.jsp
<!DOCTYPE html>

<%@ page import="java.util.List" %>
<%@ page import="com.tsugaruinfo.model.Mypersonaldata" %>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

<html>
    <head>
        <meta charset="utf-8">
        <title>JPA Sample1</title>
    </head> 
    <body>
        <h1>Welcome to JPA Sample!</h1>

        <form method="post" action="person">
        <table>
            <tr><td>Name:Input<input type ="text" name="name"></td></tr>
            <tr><td>Mail:Input<input type ="text" name="mail"></td></tr>
            <tr><td>Age:Input<input type ="text" name="age"></td></tr>
            <tr><td><input type ="submit" value="追加"></td></tr>
        </table>
        </form>
        <c:url value="/showMessage.html" var="messageUrl" />
        <a href="${messageUrl}">Click to enter</a>
        <ol>

            <% for(Object entity : (List)request.getAttribute("entities")){ %>
                <li><%=entity %></li>
            <% } %>
        </ol>
    </body>
</html>

結果

image.png

リポジトリが動いていることをちゃんと確認できました。