ぺんぎんらぼ

お笑いとマンガ好きなしょぼしょぼWeb系エンジニアの日記です。たまに絵を描きます。

お笑いとマンガ好きなしょぼしょぼWeb系エンジニアの日記です

Spring MVCとMyBatisを連携させる~設定編~

事前準備編で準備したMySQLのDBに、このSpringモジュールからアクセスするための設定を行います。

STSで自動生成された時はHomeController.javaしかなかったのですが、
今回はControllerパッケージと、Serviceパッケージ、Persistenceパッケージを作成して、それぞれの層に必要なクラスを作っておきました。
とにかくSpringとO/Rマッパー部分の連携がやりたかったので、JSPで表示するまでは後回しにしました。渡す値はControllerから固定値をあげて、DBから取得した値もControllerまで渡して、System.out.print();でコンソール表示までして、GOALとしています。

それぞれの設定の意味を理解して、こちらに書きおろそうと思ったのですが、時間がかかりそうなので、
コードだけ載せて終わります…orz あとプロジェクト名をきちんとDialy→Diaryに直しました。

ファイル一覧

 1. パッケージ構成
 2. pom.xml
 3. servlet-context.xml
 4. root-context.xml
 5. mybatis.xml ←新規作成
 6. HomeController.java
 7. HomeService.javaとHomeServiceImpl.java ←新規作成
 8. SelectContentMapper.xmlとSelectContentMapper.java ←新規作成

 web.xmlはデフォルトから変更なし

ファイルの中身

1. パッケージ構成

赤枠部分を追加。Controller、Service、Persistenceの3層構成にして、それぞれの下にbean、entityパッケージを作成して、この中にビーン、エンティティになるクラスを入れてます。

2. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.labo</groupId>
    <artifactId>diary</artifactId>
    <name>Diary</name>
    <packaging>war</packaging>
    <version>1.0.0-BUILD-SNAPSHOT</version>
    <properties>
        <java-version>1.6</java-version>
        <org.springframework-version>3.1.1.RELEASE</org.springframework-version>
        <org.aspectj-version>1.6.10</org.aspectj-version>
        <org.slf4j-version>1.6.6</org.slf4j-version>
    </properties>
    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework-version}</version>
            <exclusions>
                <!-- Exclude Commons Logging in favor of SLF4j -->
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                 </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
 
        <!-- JDBC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
 
 
        <!-- AspectJ -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj-version}</version>
        </dependency>
 
        <!-- Logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${org.slf4j-version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${org.slf4j-version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.mail</groupId>
                    <artifactId>mail</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.jms</groupId>
                    <artifactId>jms</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jdmk</groupId>
                    <artifactId>jmxtools</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jmx</groupId>
                    <artifactId>jmxri</artifactId>
                </exclusion>
            </exclusions>
            <scope>runtime</scope>
        </dependency>
 
        <!-- @Inject -->
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
 
        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
 
        <!-- Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
 
        <!-- mySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
        </dependency>
        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.3</version>
        </dependency>
        <!-- MyBatis-spring連携 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.1</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3. servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
 
<!-- SpringMVCの書き方ですよという宣言 -->
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
      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">
 
    <!-- アノテーションを利用しますよという宣言 -->
    <annotation-driven />
 
    <!-- DispatcherServlet経由で静的リソースにアクセスするための設定 -->
    <resources mapping="/resources/**" location="/resources/" />
    <!-- mapping属性はURL上のパスでlocationは物理上のパス。URL「{コンテキストパス}/resources」が物理上の「WEB-INF/resources/」に置き換わる -->
 
    <!-- DIコンテナにViewResolverを登録 -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- InternalResourceViewResolverはプレフィックスとサフィックスからViewオブジェクトを生成するUrlBasedViewRedolverのサブクラス -->
 
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
        <!-- InternalResourceViewResolverにView名を渡すと「{プレフィックス}{View名}{サフィックス}」のViewオブジェクトが生成される -->
 
    </beans:bean>
 
    <!-- Controllerクラスを自動でDIコンテナに登録 -->
    <context:component-scan base-package="com.labo.diary.controller" />
 
    <!-- Serviceを追加 -->
    <context:component-scan base-package="com.labo.diary.service" />
 
    <!-- persistenceを追加 -->
    <context:component-scan base-package="com.labo.diary.persistence" />
 
</beans:beans>

4. root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
 
    <!-- このファイルもBean定義ファイルとして利用できる -->
    <!-- servlet-context.xmlを使わずにroot-context.xmlを使うと
        定義情報をDAO用、サービス用、単体テスト用、など分散して書くことができるので便利 -->
 
    <!-- MyBatis設定 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/penguindatabase" />
        <property name="username" value="username" /><!-- MySQLインスコ時に設定したusername -->
        <property name="password" value="password" /><!-- MySQLインスコ時に設定したpassword -->
    </bean>
 
    <!-- トランザクションマネージャー -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
 
    <!-- トランザクション境界を設定 -->
    <tx:annotation-driven transaction-manager="transactionManager" />
 
    <!-- SQLセッションファクトリー -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="/WEB-INF/spring/mybatis.xml" />
        <property name="dataSource" ref="dataSource" />
    </bean>
 
    <!-- xxxMapper.xmlの記述を省略できる -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.labo.diary.persistence" />
    </bean>
 
</beans>

5. mybatis.xml ← 新規作成

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>
</configuration>

6. HomeController.java

package com.labo.diary.controller;
 
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 org.springframework.web.bind.annotation.RequestMethod;
 
import com.labo.diary.controller.form.Content;
import com.labo.diary.service.HomeService;
import com.labo.diary.service.bean.ContentResponse;
 
@Controller
public class HomeController {
 
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
 
    // 追加
    @Autowired
    HomeService homeService;
 
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);
 
        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
 
        String formattedDate = dateFormat.format(date);
 
        model.addAttribute("serverTime", formattedDate );
 
        // 追加
        Content content = new Content();
        ContentResponse contentResult = homeService.init(1);
        content.setId(contentResult.getId());
        content.setName(contentResult.getName());
 
        System.out.println("DBから取得した結果を出力");
        System.out.println("contentResult.getId()=" + contentResult.getId());
 
        return "home";
    }
}

7. HomeService.javaとHomeServiceImpl.java

package com.labo.diary.service;
 
import com.labo.diary.service.bean.ContentResponse;
 
public interface HomeService {
 
    public ContentResponse init(int id);
 
}
package com.labo.diary.service;
 
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
import com.labo.diary.persistence.SelectContentMapper;
import com.labo.diary.persistence.entity.ContentResult;
import com.labo.diary.service.bean.ContentResponse;
 
@Service
public class HomeServiceImpl implements HomeService {
 
    private static final Logger logger = LoggerFactory.getLogger(HomeServiceImpl.class);
 
    @Autowired
    SelectContentMapper selectContentMapper;
 
    @Override
    public ContentResponse init(int id) {
 
        // Mapperアクセス
        ContentResponse contentResponse = new ContentResponse();
        ContentResult content = selectContentMapper.selectContent(id);
        contentResponse.setId(content.getId());
        contentResponse.setName(content.getName());
 
        return contentResponse;
    }
}

8. SelectContentMapper.xmlとSelectContentMapper.java ← 新規作成

<?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">
<mapper namespace="com.labo.diary.persistence.SelectContentMapper">
    <select id="selectContent" parameterType="int" resultType="com.labo.diary.persistence.entity.ContentResult">
        SELECT * FROM CONTENT WHERE ID=#{id}
    </select>
</mapper>
package com.labo.diary.persistence;
 
import com.labo.diary.persistence.entity.ContentResult;
 
public interface SelectContentMapper {
    public ContentResult selectContent(int id);
}
起動

Tomcatを起動して、エラーが出力されていないことを確認!

リクエスト「http://localhost:80080/diary/」を送信。
MyBatis連携でDBから取得した値がControllerまで戻ってきて、表示されました。

以上でした。