javaのSpringとMybatisについて調査した。(今年はPHPじゃないのをはじめた)
javaのSpringとMybatisについて調査した
1.mybatis-jpetstore-6.0.1-bundle.zip(http://code.google.com/p/mybatis/downloads/list?q=Product=Sample)のソースを流用(これ自体はWEBシステムのサンプルなので)してJAVAバッチを作った。
2.今回は動的SQLを使わなかったがここ(http://www.mybatis.org/core/ja/dynamic-sql.html)を参考にしてあとで試す。
3.pom.xmlを作るのにここ(http://brightgenerous.blogspot.jp/2012/01/spring3-mybatis3.html)を見本にした。
■eclipseでMavenのプロジェクトにした
■App.java(JAVAバッチ)のサンプル
package org.mybatis.jpetstore.app; import java.util.List; import org.mybatis.jpetstore.domain.Category; import org.mybatis.jpetstore.domain.Signon2; import org.mybatis.jpetstore.service.CatalogService; import org.mybatis.jpetstore.service.Signon2Service; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { private static ApplicationContext context; /** * @param args */ public static void main(String[] args) { System.out.println("start"); context = new ClassPathXmlApplicationContext("applicationContext.xml"); CatalogService catalogService = context.getBean(CatalogService.class); Category category = catalogService.getCategory("FISH"); System.out.println("category=" + category.toString()); List<Category> list = catalogService.getCategoryList(); System.out.println("list=" + list); System.out.println("------"); Signon2Service sigon2Service = context.getBean(Signon2Service.class); Signon2 signon2 = sigon2Service.getSignon2("ACID"); System.out.println("sigon2=" + signon2.toString()); signon2 = sigon2Service.getSignon2("ACID","ACID"); System.out.println("sigon2=" + signon2.toString()); System.out.println("------"); Signon2 signon2a = new Signon2(); signon2a.setUserName("ACID"); signon2a.setPassWord("ACID"); signon2 = sigon2Service.getSignon2(signon2a); System.out.println("sigon2=" + signon2.toString()); signon2 = sigon2Service.getSignon2("ACID","ACID"); //System.out.println("sigon2=" + signon2.toString()); // System.out.println("------"); // signon2a = new Signon2(); // signon2a.setUserName("XXXX"); // signon2a.setPassWord("YYYY"); // sigon2Service.insertSignon2(signon2a); // signon2 = sigon2Service.getSignon2(signon2a); // System.out.println("sigon2b=" + signon2.toString()); System.out.println("==before doAll========================"); try { sigon2Service.doAll(); } catch (Exception up) { System.out.println("------"); System.out.println("---Exception---"); System.out.println("Exception==" + up.toString()); } System.out.println("==after doAll========================"); System.out.println("////////"); signon2a = new Signon2(); signon2a.setUserName("ACID"); signon2a.setPassWord("ACID"); Signon2 signon2b = sigon2Service.getSignon2(signon2a); if (signon2b != null) { System.out.println("sigon2b=" + signon2b.toString()); } else { System.out.println("------"); System.out.println("---sigon2b null---"); } } }
■applicationContext.xml ←Springを使う為の基本となる構成ファイル
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright 2010 The myBatis Team Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <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" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!-- in-memory database and a datasource --> <jdbc:embedded-database id="dataSource"> <jdbc:script location="classpath:database/jpetstore-hsqldb-schema.sql"/> <jdbc:script location="classpath:database/jpetstore-hsqldb-dataload.sql"/> </jdbc:embedded-database> <!-- transaction manager, use JtaTransactionManager for global tx --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- enable component scanning and autowire (beware that this does not enable mapper scanning!) --> <context:component-scan base-package="org.mybatis.jpetstore.service" /> <!-- enable transaction demarcation with annotations --> <tx:annotation-driven /> <!-- define the SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="typeAliasesPackage" value="org.mybatis.jpetstore.domain" /> <property name="configLocation" value="classpath:mybatis-config.xml"/> </bean> <!-- scan for mappers and let them be autowired --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="org.mybatis.jpetstore.persistence" /> </bean> </beans>
■log4j.properties ←これは関係ないが自分用に載せておく。・・・よくわかっていないので
# Rules reminder: # DEBUG < INFO < WARN < ERROR < FATAL # Global logging configuration log4j.rootLogger=WARN, stdout # My logging configuration... log4j.logger.org.mybatis.jpetstore=TRACE ## Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n
■mybatis-config.xml ←テーブル項目とEntityBean(変数名は項目名をキャメルにしたものになっている)のマッピングを自動でやってもらう。applicationContext.xmlのSqlSessionFactoryのconfigLocationに設定している。
<?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>
■pom.xml ←Mavenのプロジェクト用。これで動いたというレベルなので、これが100%正解とは言えない
<?xml version="1.0"?> <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>xxxx</groupId> <artifactId>sample</artifactId> <packaging>jar</packaging> <version>6.0.2-SNAPSHOT</version> <name>sample</name> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.1.1</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.1.1</version> </dependency> <!-- Core utilities used by other modules. Define this if you use Spring Utility APIs (org.springframework.core.*/org.springframework.util.*) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.1.0.RELEASE</version> </dependency> <!-- Expression Language (depends on spring-core) Define this if you use Spring Expression APIs (org.springframework.expression.*) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>3.1.0.RELEASE</version> </dependency> <!-- Bean Factory and JavaBeans utilities (depends on spring-core) Define this if you use Spring Bean APIs (org.springframework.beans.*) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>3.1.0.RELEASE</version> </dependency> <!-- Aspect Oriented Programming (AOP) Framework (depends on spring-core, spring-beans) Define this if you use Spring AOP APIs (org.springframework.aop.*) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>3.1.0.RELEASE</version> </dependency> <!-- Application Context (depends on spring-core, spring-expression, spring-aop, spring-beans) This is the central artifact for Spring's Dependency Injection Container and is generally always defined --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.1.0.RELEASE</version> </dependency> <!-- Various Application Context utilities, including EhCache, JavaMail, Quartz, and Freemarker integration Define this if you need any of these integrations --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>3.1.0.RELEASE</version> </dependency> <!-- Transaction Management Abstraction (depends on spring-core, spring-beans, spring-aop, spring-context) Define this if you use Spring Transactions or DAO Exception Hierarchy (org.springframework.transaction.*/org.springframework.dao.*) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>3.1.0.RELEASE</version> </dependency> <!-- JDBC Data Access Library (depends on spring-core, spring-beans, spring-context, spring-tx) Define this if you use Spring's JdbcTemplate API (org.springframework.jdbc.*) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>3.1.0.RELEASE</version> </dependency> <!-- Object-to-Relation-Mapping (ORM) integration with Hibernate, JPA, and iBatis. (depends on spring-core, spring-beans, spring-context, spring-tx) Define this if you need ORM (org.springframework.orm.*) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>3.1.0.RELEASE</version> </dependency> <!-- Object-to-XML Mapping (OXM) abstraction and integration with JAXB, JiBX, Castor, XStream, and XML Beans. (depends on spring-core, spring-beans, spring-context) Define this if you need OXM (org.springframework.oxm.*) --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>3.1.0.RELEASE</version> </dependency> <!-- Web application development utilities applicable to both Servlet and Portlet Environments (depends on spring-core, spring-beans, spring-context) Define this if you use Spring MVC, or wish to use Struts, JSF, or another web framework with Spring (org.springframework.web.*) <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>3.1.0.RELEASE</version> </dependency> --> <!-- Spring MVC for Servlet Environments (depends on spring-core, spring-beans, spring-context, spring-web) Define this if you use Spring MVC with a Servlet Container such as Apache Tomcat (org.springframework.web.servlet.*) <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>3.1.0.RELEASE</version> </dependency> --> <!-- Spring MVC for Portlet Environments (depends on spring-core, spring-beans, spring-context, spring-web) Define this if you use Spring MVC with a Portlet Container (org.springframework.web.portlet.*) <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc-portlet</artifactId> <version>3.1.0.RELEASE</version> </dependency> --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> <exclusions> <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> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.2.8</version> </dependency> </dependencies> </project>
■Signon2.java ←EntityBeanのサンプル
package org.mybatis.jpetstore.domain; import java.io.Serializable; public class Signon2 implements Serializable { private static final long serialVersionUID = 8751282105532159742L; private String userName; private String passWord; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } public String toString() { return getUserName() + "," + getPassWord() ; } }
■Signon2Dao.java ←Daoのサンプル。MapperなのだけどDaoという名前のほうが一般的なのでSignon2Dao.javaにした。「getSignon2ByUsername(String userName);」は直接@Selectアノテーションを使ってみた。
package org.mybatis.jpetstore.persistence; import org.apache.ibatis.annotations.Select; import org.mybatis.jpetstore.domain.Signon2; public interface Signon2Dao { @Select("SELECT USER_NAME, " + "PASS_WORD FROM SIGNON2 " + "WHERE USER_NAME = #{userName}") Signon2 getSignon2ByUsername(String userName); Signon2 getSignon2ByUsernameAndPassword(String userName, String passWord); Signon2 getSignon2ByUsernameAndPassword2(Signon2 signon2); void insertSignon2(Signon2 signon2); void updateSignon2(Signon2 signon2); }
■Signon2Dao.xml ←Daoのサンプル。Mapper.xmlなのだけどDaoという名前のほうが一般的なのでSignon2Dao.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="org.mybatis.jpetstore.persistence.Signon2Dao"> <cache /> <select id="getSignon2ByUsernameAndPassword" parameterType="Signon2" resultType="Signon2"> SELECT USER_NAME, PASS_WORD FROM SIGNON2 WHERE USER_NAME = #{param1} AND PASS_WORD = #{param2} </select> <select id="getSignon2ByUsernameAndPassword2" parameterType="Signon2" resultType="Signon2"> SELECT USER_NAME, PASS_WORD FROM SIGNON2 WHERE USER_NAME = #{userName} AND PASS_WORD = #{passWord} </select> <update id="updateSignon2" parameterType="Signon2"> UPDATE SIGNON2 SET PASS_WORD = #{passWord} WHERE USER_NAME = #{userName} </update> <insert id="insertSignon2" parameterType="Signon2"> INSERT INTO SIGNON2 (USER_NAME,PASS_WORD) VALUES (#{userName}, #{passWord}) </insert> </mapper>
■Signon2Service.java ←トランザクションの動きをテストするため、わざと重複エラーを起こしているよ。
package org.mybatis.jpetstore.service; import org.apache.log4j.Logger; import org.mybatis.jpetstore.domain.Signon2; import org.mybatis.jpetstore.persistence.Signon2Dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service public class Signon2Service { private static Logger log=Logger.getLogger(Signon2Service.class.getName()); @Autowired private Signon2Dao signon2Dao; public Signon2 getSignon2(String username) { return signon2Dao.getSignon2ByUsername(username); } public Signon2 getSignon2(String username, String password) { return signon2Dao.getSignon2ByUsernameAndPassword(username, password); } public Signon2 getSignon2(Signon2 signon2) { return signon2Dao.getSignon2ByUsernameAndPassword2(signon2); } public void insertSignon2(Signon2 signon2) { signon2Dao.insertSignon2(signon2); } public void updateSignon2(Signon2 signon2) { signon2Dao.updateSignon2(signon2); } @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) public void doAll() { // try { log.debug("-- log log log start"); System.out.println("start"); System.out.println("------"); Signon2 signon2b = getSignon2("ACID"); System.out.println("sigon2b=" + signon2b.toString()); signon2b = getSignon2("ACID","ACID"); System.out.println("sigon2b=" + signon2b.toString()); System.out.println("------"); Signon2 signon2a = new Signon2(); signon2a.setUserName("ACID"); signon2a.setPassWord("ACID"); signon2b = getSignon2(signon2a); System.out.println("sigon2=" + signon2b.toString()); signon2b = getSignon2("ACID","ACID"); System.out.println("sigon2=" + signon2b.toString()); System.out.println("------"); signon2a = new Signon2(); signon2a.setUserName("XXXX"); signon2a.setPassWord("YYYY"); insertSignon2(signon2a); insertSignon2(signon2a); // テストのためここで重複エラーを起こす! signon2b = getSignon2(signon2a); System.out.println("sigon2b=" + signon2b.toString()); signon2a.setPassWord("ZZZZ"); updateSignon2(signon2a); signon2b = getSignon2(signon2a); System.out.println("sigon2=" + signon2b.toString()); // ここでキャッチしないで、呼び元でキャッチするほうがいい。(だからコメントアウトした) // doAllを抜けるとき@Transactionalの // rollbackFor=Exception.classによりロールバックされている。例外は帰ってくるので呼び元で処理する。 // ・・・呼び元でtry、catch処理しないと、例外発生で落ちてしまうので注意。 // } catch (Exception up) { // //log the error // log.warn("エラー:" + up); // System.out.println("------"); // System.out.println("---Exception---"); // System.out.println("Exception==" + up.toString()); // throw up; // } } }