MyBatis3がMyBatis2に比べて結構使いやすくなっています。
特に実装クラスを必要としないMapperの機能が便利です。
他には、XMLでognl式が使えたり、使いやすいタグが増えています。
Spring3 + MyBatis3の実装例で試してみます。
まず、データクラスを作成します。
- User.java
-
- package com.brightgenerous.sample.application.bean;
- import java.io.Serializable;
- public class User implements Serializable {
- private static final long serialVersionUID = -1056270813521861315L;
- private Integer m_id;
- private String m_name;
- private String m_email;
- public Integer getId() {
- return m_id;
- }
- public void setId(Integer x_id) {
- m_id = x_id;
- }
- public String getName() {
- return m_name;
- }
- public void setName(String x_name) {
- m_name = x_name;
- }
- public String getEmail() {
- return m_email;
- }
- public void setEmail(String x_email) {
- m_email = x_email;
- }
- }
次に、Dao(Mapper)インターフェースを作成します。
- UserDao.java
-
- package com.brightgenerous.sample.application.dao;
- import com.brightgenerous.sample.application.bean.User;
- public interface UserDao {
- User select(User x_user);
- int insert(User x_user);
- int update(User x_user);
- int delete(User x_user);
- }
そして、UserDao.javaと同じパッケージにUserDao.xmlを置きます。(拡張子以外のファイル名を同じにする)
それだけでインターフェースとXMLファイルが関連付けられます。
- UserDao.xml
-
- <!--xml version="1.0" encoding="UTF-8" ?-->
- <!--DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd"-->
- <mapper namespace="com.brightgenerous.sample.application.dao.UserDao">
- <cache flushinterval="3600000">
- <resultmap type="User" id="User">
- <result column="id" property="id">
- <result column="name" property="name">
- <result column="email" property="email">
- </result></result></result></resultmap>
- <select id="select" parametertype="User" resulttype="User" resultmap="User">
- select
- *
- from
- t_user
- and 1 = 0
- and id = #{id}
- </select>
- <insert id="insert" parametertype="User">
- <selectkey keyproperty="id" resulttype="Integer" order="BEFORE">
- select coalesce((select max(id) from t_user),0) + 1 as id
- </selectkey>
- insert into
- t_user (
- id,
- name,
- ) values (
- #{id},
- #{name},
- #{email}
- )
- </insert>
- <update id="update" parametertype="User">
- update
- t_user
- set
- name = #{name},
- email = #{email}
- where
- id = #{id}
- </update>
- <delete id="delete" parametertype="User">
- delete from
- t_user
- where
- id = #{id}
- </delete>
- </cache></mapper>
最後に、トランザクション境界となるServiceクラスを作成します。
- UserService.java
-
- package com.brightgenerous.sample.application.service;
- import javax.inject.Inject;
- import com.brightgenerous.sample.application.bean.User;
- import com.brightgenerous.sample.application.dao.UserDao;
- public class UserService {
- @Inject
- private UserDao m_userDao;
- public User get(User x_user) {
- return m_userDao.select(x_user);
- }
- public void update(User x_user) {
- m_userDao.update(x_user);
- }
- }
あとは設定ファイルを書くだけです。
注入先フィールドのInjectアノテーションはjavax.inject.Injectです。
実は、上記のすべてのクラスでMyBatisやSpringに関するインポートがないのです。
- applicationContext.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:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemalocation="
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.1.xsd
- http://www.springframework.org/schema/jee
- http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">
- <!-- DATABASE CONFIG -->
- <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="locations" value="classpath:database.properties">
- </property></bean>
- <!-- DATA SOURCE -->
- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
- <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="true">
- <property name="removeAbandoned" value="true">
- </property></property></property></property></property></property></bean>
- <!-- TRANSACTION -->
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource">
- </property></bean>
- <bean id="transactionAttributeSource" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
- <property name="properties">
- <props>
- <prop key="regist*">PROPAGATION_REQUIRED</prop>
- <prop key="update*">PROPAGATION_REQUIRED</prop>
- <prop key="delete*">PROPAGATION_REQUIRED</prop>
- <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
- </props>
- </property>
- </bean>
- <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <property name="transactionManager" ref="transactionManager">
- <property name="transactionAttributeSource" ref="transactionAttributeSource">
- </property></property></bean>
- <bean id="beanNameAutoProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
- <property name="interceptorNames" value="transactionInterceptor">
- <property name="beanNames" value="*Service">
- </property></property></bean>
- <!-- MYBATIS3 SPRING3 -->
- <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="configLocation" value="classpath:sqlMapConfig.xml">
- <property name="dataSource" ref="dataSource">
- </property></property></bean>
- <!-- PACKAGE IMPLEMENTS -->
- <context:component-scan base-package="com.brightgenerous.sample.application.service" name-generator="com.brightgenerous.extension.spring3.FqcnBeanNameGenerator" use-default-filters="false">
- <context:include-filter type="regex" expression=".*Service">
- </context:include-filter></context:component-scan>
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <property name="basePackage" value="com.brightgenerous.sample.application.dao">
- </property></bean>
- </beans>
applicationContext.xmlには
com.brightgenerous.extension.spring3.FqcnBeanNameGeneratorというクラスがありますが、
これは、ただFQCNを返すだけのSpringのBeanNameGenerator実装です。
database.propertiesファイルは特にここで書くほどでもないので省略します。
- sqlMapConfig.xml
- <!--xml version="1.0" encoding="UTF-8" ?-->
- <!--DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-config.dtd"-->
- <configuration>
- <settings>
- <setting name="cacheEnabled" value="true">
- <setting name="lazyLoadingEnabled" value="true">
- <setting name="multipleResultSetsEnabled" value="true">
- <setting name="aggressiveLazyLoading" value="true">
- <setting name="useColumnLabel" value="true">
- <setting name="useGeneratedKeys" value="false">
- <setting name="autoMappingBehavior" value="PARTIAL">
- <setting name="defaultExecutorType" value="REUSE">
- <setting name="safeRowBoundsEnabled" value="true">
- <setting name="mapUnderscoreToCamelCase" value="false">
- </setting></setting></setting></setting></setting></setting></setting></setting></setting></setting></settings>
- <typealiases>
- <package name="com.brightgenerous.sample.application.bean">
- </package></typealiases>
- </configuration>
実行方法は以下のようになります。
- UserServiceTestSpring
- package com.brightgenerous.sample.application.service;
- import com.brightgenerous.sample.application.bean.User;
- import com.brightgenerous.sample.application.dao.UserDao;
- import org.junit.Before;
- import org.junit.Test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class UserServiceTestSpring {
- private ApplicationContext context;
- @Before
- public void before() {
- context = new ClassPathXmlApplicationContext("applicationContext.xml");
- }
- @Test
- public void test01() {
- UserService service = context.getBean(UserService.class);
- User user = new User();
- user.setId(Integer.valueOf(1));
- user = service.get(user);
- user.setName(user.getName() + "-");
- service.update(user);
- }
- }
これ以上ソースコードの記述量を減らせないんじゃないのかと思えるほど、簡単になりました。
設定ファイルは一度書いてしまえば、以降は編集しないので、
実際に作成するファイルはデータクラス、Mapperインターフェース、MapperのXMLファイル、サービスクラスの4つです。
次回は、SpringをGuiceに置き換えて同じ機能を実現してみようと思います。
具体的には、Springでの設定ファイルにあたる部分をソースで書くだけで、Mapperやサービスクラスには手を加えません。
これ動かないよ。嘘書かないで
返信削除