Spring 4.1 + MyBatis 3.2 + PostgreSQL 9.3 環境を作る(part 1)

こんにちわ、夏バテもなくなり、猫と戯れる日々を過ごすほげPGです。今回は前回のプロジェクトを改良してDB操作を追加していきます。(ほげッ)

1、各種インストール

PostGreSQLは ここ(https://www.postgresql.jp/download)から9.3を落としてインストールしてください。

2、データベースの作成

pgAdmin III(ゾウさんnアイコン)を起動する。

2-1、ロール作成
新しいログインロールで右クリック>新しいログインロールを選択
WS000000
プロパティタブ ロール名:hoge、コメント:hoge
WS000001
定義タブ パスワード:hoge
WS000002

ロール特権タブ 全部チェック

WS000003
これでOKボタン押下。

2-2、データベース作成
データベースで右クリック>新しいデータベースを選択
WS000004
データベース名にhogedb、オーナーをhogeに設定し、OK押下。
WS000005
WS000006

3、テーブルの作成

以下のSQLをクエリーツールより実施する。

DROP TABLE IF EXISTS tbl_hoge;
CREATE TABLE tbl_hoge (
	id SERIAL NOT NULL,
	name VARCHAR(10) NOT NULL,
	comment VARCHAR(999),
	updated_at timestamp DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (id)
);

WS000001

4、前回プロジェクトの修正

pom.xmlの依存関係に以下を追加。

<!-- DB -->
<dependency>
 <groupId>org.mybatis</groupId>
 <artifactId>mybatis</artifactId>
 <version>3.2.7</version>
</dependency>
<dependency>
 <groupId>org.mybatis</groupId>
 <artifactId>mybatis-spring</artifactId>
 <version>1.2.2</version>
</dependency>
<dependency>
 <groupId>commons-dbcp</groupId>
 <artifactId>commons-dbcp</artifactId>
 <version>1.2.2</version>
</dependency>
<dependency>
 <groupId>org.postgresql</groupId>
 <artifactId>postgresql</artifactId>
 <version>9.3-1102-jdbc4</version>
</dependency>

spring-context.xml を以下のように修正。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:task="http://www.springframework.org/schema/task"
 xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
	<context:component-scan base-package="jp.co.ois.hoge.sandbox" />
	<mvc:annotation-driven />
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<mvc:resources mapping="/resources/**" location="/resources/" />
	<!-- 設定 -->
	<bean id="system"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
		<property name="searchSystemEnvironment" value="true"/>
		<property name="locations">
			<list>
				<value>classpath:system.properties</value>
			</list>
		</property>
	</bean>
	<!-- DB関連 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="defaultAutoCommit" value="false" />
	</bean>
	<!-- トランザクション管理 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>
	<!-- mybatis -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation" value="classpath:mybatis-config.xml" />
		<property name="mapperLocations" value="classpath*:sqlMap/**/*.xml" />
	</bean>
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg index="0" ref="sqlSessionFactory" />
	</bean>
	<tx:annotation-driven />
</beans>

src/java/resources の下にsystem.propertiesを新規作成。内容は以下の通り。

jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/hogedb
jdbc.username=hoge
jdbc.password=hoge

mybatis 用の定義ファイルを作成。
src/java/resources/mybatis-config.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="logImpl" value="LOG4J"/>
	</settings>
	<environments default="production">
		<environment id="production">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver.encoding" value="utf8" />
			</dataSource>
		</environment>
	</environments>
</configuration>

src/java/resources/sqlMap/hoge.xml

<?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="jp.co.ois.hoge.sandbox.hoge">
	<!-- ほげ用 -->
	<select id="list"
			resultType="jp.co.ois.hoge.sandbox.HogeForm">
		SELECT
			id,
			name,
			comment,
			updated_at as "updatedAt"
		FROM tbl_hoge
		ORDER BY updated_at DESC
	</select>
	<select id="select"
			parameterType="int"
			resultType="jp.co.ois.hoge.sandbox.HogeForm">
		SELECT
			Id,
			name,
			comment,
			updated_at as "updatedAt"
		FROM tbl_hoge
		WHERE id = #{Id}
	</select>
	<insert id="insert"
			parameterType="jp.co.ois.hoge.sandbox.HogeForm">
		INSERT INTO tbl_hoge (
			name,
			comment,
			updated_at
		)
		VALUES (
			#{name},
			#{comment},
			now()
		)
	</insert>
	<update id="update"
			parameterType="jp.co.ois.hoge.sandbox.HogeForm">
		UPDATE tbl_hoge
		SET	name = #{name}, comment = #{comment}, updated_at = now()
		WHERE id = #{id}
	</update>
</mapper>

 

5、サンプルの作成

サンプルの構成を以下に示す。
メモ
補足)
・新規入力~挿入までの流れでlistのところは画面に一覧を表示するためにselectしているだけです。
・mybatisとのやり取りはHogeController ではなくHogeLogicという別クラスで処理しています。
・jspは一つの共通jspで処理しています。

HogeController.java

package jp.co.ois.hoge.sandbox;
import java.util.List;
import javax.validation.Valid;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/hoge")
public class HogeController {
	private static final Log log = LogFactory.getLog(HogeController.class);
	@Autowired
	HogeLogic logic;
	@ModelAttribute("hogeForm")
	public HogeForm createForm() {
		return new HogeForm();
	}
	@RequestMapping({"/", "/index"})
	@Transactional(readOnly=true)
	public String index(Model model) {
		log.debug("called.");
		List<HogeForm> list = logic.list();
		model.addAttribute("list", list);
		return "hoge";
	}
	@RequestMapping("/update")
	@Transactional(rollbackFor=Throwable.class)
	public String update(@Valid HogeForm form, BindingResult result, Model model) {
		log.debug("called.");
		if (result.hasErrors()) {
	        model.addAttribute("result", "error");
			return index(model);
		}
		logic.update(form);
        model.addAttribute("result", "success");
		return index(model);
	}
	@RequestMapping("/select")
	@Transactional(readOnly=true)
	public String select(@RequestParam int id, Model model) {
		log.debug("called.");
		HogeForm form = logic.select(id);
		model.addAttribute(form);
		return index(model);
	}
}

HogeLogic.java

package jp.co.ois.hoge.sandbox;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class HogeLogic {
	private static final Log log = LogFactory.getLog(HogeLogic.class);
	@Autowired
	private SqlSession sqlSession;
	public void update(HogeForm form) {
		log.debug("called. "+ form);
		if (form.getId() > 0) {
			sqlSession.update("jp.co.ois.hoge.sandbox.hoge.update", form);
		} else {
			sqlSession.insert("jp.co.ois.hoge.sandbox.hoge.insert", form);
		}
	}
	public List<HogeForm> list() {
		log.debug("called.");
		return sqlSession.selectList("jp.co.ois.hoge.sandbox.hoge.list");
	}
	public HogeForm select(int id) {
		log.debug("called. "+ id);
		return sqlSession.selectOne("jp.co.ois.hoge.sandbox.hoge.select", id);
	}
}

hoge.jsp

<%@page contentType="text/html; charset=utf-8" %>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
	<title>ほげ</title>
</head>
<body>
	<h1>ほげ</h1>
	<form:form modelAttribute="hogeForm" servletRelativeAction="/hoge/update" method="POST">
		<form:hidden path="id" />
		<br><br>
		名前:<form:input path="name" />
		<form:errors path="name" /><br>
		コメント:<form:input path="comment" />
		<form:errors path="comment" /><br>
		<input type="submit" value="更新">
	</form:form>
	${result}<br>
<hr>
<table border=1>
	<tr>
	<th>id</th>
	<th>name</th>
	<th>comment</th>
	<th>updatedAt</th>
	</tr>
<c:forEach var="hoge" items="${list}" varStatus="status">
	<tr onclick="selectHoge(${hoge.id})">
	<td><c:out value="${hoge.id}"/></td>
	<td><c:out value="${hoge.name}"/></td>
	<td><c:out value="${hoge.comment}"/></td>
	<td><c:out value="${hoge.updatedAtString}"/></td>
	</tr>
</c:forEach>
</table>
<br>
<input type="button" value="新規" onclick="newForm()">
<script>
function selectHoge(id) {
	location = "<c:url value="/hoge/select"/>?id="+ id;
}
function newForm() {
	location = "<c:url value="/hoge/"/>";
}
</script>
</body>
</html>

実際に動かしてみる。
ブラウザで以下にアクセス
http://localhost:8080/sandbox/hoge/
WS000002
WS000003
WS000004

今回のプロジェクト一式は以下に置きました。
http://www.ois-yokohama.co.jp/oisblog/file/sandbox2.zip

とりあえず、今回はここまで。

\ 最新情報をチェック /