Flex

BlazeDS + SpringFramework + MyBatis + HSQLDBの連携

【 BlazeDS + SpringFramework + MyBatis + HSQLDBの連携 】



Spring Framework3.0.5 - DI(Dependency Injection)コンテナ
MyBatis3.0.6 - O/R Mapper
HSQLDB2.2.5 - Java製RDB



Spring2.0.x + iBatis2.x + HSQLDB1.8.xを Spring3.0.5 + MyBatis3.0.6 + HSQLDB2.2.5で置き換えてみました。
こちらはXMLベースでの実装となります。

packageの階層に注意してください。



[ db.script -抜粋- ]
---
CREATE CACHED TABLE MESSAGE(
    ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,
    NAME VARCHAR(255) NOT NULL,
    MAIL VARCHAR(255) NOT NULL,
    MESSAGE VARCHAR(65535) NOT NULL,
    DAY VARCHAR(255) NOT NULL
    );
[ EOF ]
---



[ web.xml ]
---
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
    <display-name>Spring BlazeDS</display-name>

    <!-- Contextに渡すXML -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext-xml.xml</param-value>
    </context-param>


    <!-- Filter config with GZIP -->
    <filter>
        <filter-name>CompressingFilter</filter-name>
        <filter-class>
            com.planetj.servlet.filter.compression.CompressingFilter
        </filter-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>statsEnabled</param-name>
            <param-value>false</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>CompressingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
   
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
   
    <servlet>
        <servlet-name>MessageBrokerServlet</servlet-name>
        <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
        <init-param>
            <param-name>services.configuration.file</param-name>
            <param-value>/WEB-INF/flex/services-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>HttpContextUtilServlet</servlet-name>
        <servlet-class>com.chocbanana.http.HttpContextUtilServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>


    <servlet-mapping>
        <servlet-name>MessageBrokerServlet</servlet-name>
        <url-pattern>/messagebroker/*</url-pattern>
    </servlet-mapping>
</web-app>
[EOF]
---


[ HttpContextUtilServlet.java ]
---
package com.chocbanana.http;

import java.io.Serializable;

import javax.servlet.ServletException;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;


public class HttpContextUtilServlet extends javax.servlet.http.HttpServlet implements Serializable {

    private static WebApplicationContext ctx;
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        try{
            //dao.shutdown();
        }catch(Exception e){
            e.printStackTrace();
        }
        super.destroy();
    }

    @Override
    public synchronized void init() throws ServletException {
        // TODO Auto-generated method stub
        super.init();
        try{
            if(ctx == null) ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public synchronized static WebApplicationContext getContext(){
        return ctx;
    }
}
[EOF]
---


[ 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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- jdbc.propertiesを認識させる propertyConfigurer -->
    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>
                    classpath:/com/chocbanana/dao/database.properties
                </value>
            </list>
        </property>
    </bean>

    <!-- jdbc.propertiesの設定値をdataSourceにインジェクション -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${db.driver}" />
        <property name="url" value="${db.url}" />
        <property name="username" value="${db.user}" />
        <property name="password" value="${db.pass}" />
    </bean>

    <!-- MyBatisのフロントになるsqmMapClientを構成。プロパティ値にMapper.xmlのパスを指定するだけ -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath:/com/chocbanana/dao/Mapper.xml" />
    </bean>
   
    <!-- トランザクション制御のインターセプターを構成 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
   
    <!-- 実装クラスのTransactionalアノテーションでジョイントポイントの認識をさせる  -->
    <!-- @transaction-managerのデフォルトは"transactionManager"だが念のため指定  -->
    <!-- @proxy-target-classをtureにしておく。CGLIBでプロキシーを作る方が多少速いらしい -->
    <!-- -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
   
    <!-- XMLベースのDAO -->
    <bean id="daoXml" class="com.chocbanana.dao.Db2Dao">
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>
</beans>
[EOF]
---

[ database.properties ]
---
#Wed Apr 01 22:43:23 JST 2009
db.pass=
#db.url=jdbc\:hsqldb\:file:/Users/hoehoe/Documents/workspace/WEB-INF/resource/db
db.url=jdbc\:hsqldb\:file:C:/Documents and Settings/hoehoe/My Documents/EclipseProject/SpringBlazeDS/WEB-INF/resource/db
db.driver=org.hsqldb.jdbc.JDBCDriver
db.user=sa
[EOF]
---




[ Db2DaoInterface.java ]
---
/*
 * Created on 2005/06/19
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package com.chocbanana.dao;

import java.util.ArrayList;

import org.springframework.dao.DataAccessException;
import com.chocbanana.bean.PostMessage;
/**
 * @author hoehoe
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public interface Db2DaoInterface {
   
    ArrayList<PostMessage> getMessages() throws DataAccessException;
    int putMessages(PostMessage Message) throws DataAccessException;
   
    void shutdown() throws DataAccessException;
   
}
[EOF]
---

[ Db2Dao.java ]
---
/*
 * Created on 2005/06/18
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package com.chocbanana.dao;

import java.sql.SQLException;
import java.util.ArrayList;

import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.chocbanana.bean.PostMessage;

/**
 * @author hoehoe
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class Db2Dao extends SqlSessionDaoSupport implements Db2DaoInterface{
    @SuppressWarnings("unchecked")
    @Transactional(readOnly=true, propagation=Propagation.REQUIRED)
    public ArrayList<PostMessage> getMessages() throws DataAccessException{
        return (ArrayList<PostMessage>) getSqlSession().selectList("com.chocbanana.dao.Mapper.getMessage");
    }
   
    @Transactional(readOnly=false, rollbackFor=SQLException.class)
    public int putMessages(PostMessage message) throws DataAccessException{
        return getSqlSession().insert("com.chocbanana.dao.Mapper.putMessage", message);
    }

    public void shutdown() throws DataAccessException{
        getSqlSession().selectOne("shutdown");
    }
}
[EOF]
---


[ /com/chocbanana/dao/Mapper.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">
<!--
    Copyright 2010-2011 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.
-->

<!--
    version: $Id: UserMapper.xml 2444 2010-09-15 07:38:37Z simone.tripodi $
-->
<mapper namespace="com.chocbanana.dao.Mapper">
    <select id="getMessage"  resultType="com.chocbanana.bean.PostMessage">
        SELECT TOP 1000 * FROM MESSAGE ORDER BY ID DESC
    </select>

    <insert id="putMessage" parameterType="com.chocbanana.bean.PostMessage" >
        INSERT INTO MESSAGE (NAME, MAIL, MESSAGE, DAY) VALUES (#{name}, #{mail}, #{message}, #{day})
    </insert>

    <!-- database shutdown -->
    <sql id="shutdown">shutdown</sql>
</mapper>
[EOF]
---



[ FlexService.java ]
---
package com.chocbanana.ws;

import java.text.SimpleDateFormat;
import java.util.ArrayList;

import com.chocbanana.bean.*;
import com.chocbanana.dao.Db2DaoInterface;
import com.chocbanana.http.HttpContextUtilServlet;

@SuppressWarnings("serial")
public class FlexService implements java.io.Serializable{
   
    private static Db2DaoInterface dao;
    private static final String BEAN_TYPE = "daoXml";

    public FlexService(){
        dao = (Db2DaoInterface) HttpContextUtilServlet.getContext().getBean(BEAN_TYPE);
    }
    public ArrayList<ResultMessage> getMessages(){
       
        ArrayList<ResultMessage> result = new ArrayList<ResultMessage>();
        try{
            ArrayList<PostMessage> list = dao.getMessages();
            java.util.Iterator<PostMessage> it = list.iterator();
            ResultMessage resultMsg = null;

            while(it.hasNext()){
                PostMessage _msg = it.next();
                resultMsg = new ResultMessage();
                resultMsg.setMessage(
                        _msg.getId() +  " " +
                        _msg.getName() + " " +
                        _msg.getMail() + " " +
                        _msg.getDay() + " " + "\n\n" +
                        _msg.getMessage());
                result.add(resultMsg);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return result;
       
    }
    public int putMessages(PostMessage message) {
        int ret=0;
        String day = "";
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
        day = format.format(new java.util.Date());
        message.setDay(day);
       
        if("".equals(message.getMessage())){
            return 0;
        }
       
        try{
            ret = dao.putMessages(message);
        }catch(Exception e){
            e.printStackTrace();
        }
            return ret;
    }
}
---


- Flexのソースコード一覧 -

[ SpringBlazeDS.mxml ]
---
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               minWidth="950" minHeight="500" viewSourceURL="srcview/index.html">

    <fx:Script source="SpringBlazeDS.as"/>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
        <s:RemoteObject id="srv" endpoint="{'http://{server.name}:{server.port}/SpringBlazeDS/messagebroker/amf'}" destination="flexService" showBusyCursor="true">
            <s:method name="getMessages" result="resultMessage(event)" fault="faultMessage(event)"/>
        </s:RemoteObject>
    </fx:Declarations>

    <s:Panel x="0" y="0" width="100%" height="100%" title="SpringBlazeDS">
        <s:HGroup x="10" y="10" width="100%" verticalAlign="middle">
            <s:Spacer width="20" height="10"/>
            <s:Button id="btn_post" label="Post" click="btn_post_clickHandler(event)"
                      fontWeight="bold"/>
            <s:Spacer width="15" height="10"/>
            <s:Button id="btn_reload" label="Reload" click="btn_reload_clickHandler(event)"
                      fontWeight="bold"/>
        </s:HGroup>
        <s:Spacer x="10" y="39" width="20" height="10"/>
        <s:HGroup x="10" y="56" width="100%" height="85%">
            <s:DataGrid width="100%" height="100%" dataProvider="{srv.getMessages.lastResult}" creationComplete="d1_creationCompleteHandler(event)">
                <s:columns>
                    <s:ArrayList>
                        <s:GridColumn dataField="message" headerText="" />
                    </s:ArrayList>
                </s:columns>
            </s:DataGrid>
            <s:Spacer width="10" height="10"/>
        </s:HGroup>
       
    </s:Panel>
</s:Application>
[ EOF ]
---


[ SpringBlazeDS.as ]
---

import flash.events.MouseEvent;

import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

protected function btn_post_clickHandler(event:MouseEvent):void
{
    // TODO Auto-generated method stub
    var post:Post = Post(PopUpManager.createPopUp(this, Post, true));
    post.addEventListener(FlexEvent.REMOVE, closePopUp);
    PopUpManager.centerPopUp(post);
}
private function closePopUp(e:FlexEvent):void{
    srv.getMessages();
}

public function resultUser(event:ResultEvent):void{

}
protected function btn_reload_clickHandler(event:MouseEvent):void
{
    // TODO Auto-generated method stub
    srv.getMessages();
}

protected function d1_creationCompleteHandler(event:FlexEvent):void
{
    // TODO Auto-generated method stub
    srv.getMessages();
}

public function resultMessage(event:ResultEvent):void{

}

public function faultMessage(event:FaultEvent):void{
    Alert.show(event.toString());
}
[ EOF ]
---


[ Post.mxml ]
---
<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               width="800" height="400" creationComplete="t1_creationCompleteHandler(event)" close="t1_closeHandler(event)" title="PostMessage">
   
    <fx:Script>
        <![CDATA[
            import com.chocbanana.bean.PostMessge;
           
            import mx.controls.Alert;
            import mx.events.CloseEvent;
            import mx.events.FlexEvent;
            import mx.managers.PopUpManager;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
           
            protected function btn_cancel_clickHandler(event:MouseEvent):void
            {
                // TODO Auto-generated method stub
                txt_message.text = "";
            }
           
            protected function btn_post_clickHandler(event:MouseEvent):void
            {
                // TODO Auto-generated method stub
                var post:PostMessge = new PostMessge();
                post.name = txt_name.text;
                if(post.name == ""){
                    post.name = "以下、名無しに変わりましてfxug-nagoyaがお送りします";
                }
                post.mail = "sage";
                post.message = txt_message.text;
                if(post.message == ""){
                    Alert.show("本文が空です。");
                    return;
                }
                srv.putMessages(post);
            }
           
            protected function t1_closeHandler(event:CloseEvent):void
            {
                // TODO Auto-generated method stub
                PopUpManager.removePopUp(this);
            }
           
            protected function t1_creationCompleteHandler(event:FlexEvent):void
            {
                // TODO Auto-generated method stub
                txt_message.setFocus();
            }
           
            protected function method1_resultHandler(event:ResultEvent):void
            {
                // TODO Auto-generated method stub
                PopUpManager.removePopUp(this);
               
            }
           
            protected function method1_faultHandler(event:FaultEvent):void
            {
                // TODO Auto-generated method stub
                Alert.show(event.message.toString());
            }
           
        ]]>
    </fx:Script>
   
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
        <s:RemoteObject id="srv" endpoint="{'http://{server.name}:{server.port}/SpringBlazeDS/messagebroker/amf'}" destination="flexService" showBusyCursor="true">
            <s:method name="putMessages" result="method1_resultHandler(event)" fault="method1_faultHandler(event)" />
        </s:RemoteObject>
    </fx:Declarations>
    <s:VGroup x="10" y="10" width="780" height="346">
        <s:HGroup verticalAlign="middle">
            <s:Label text="Name: "/>
            <s:TextInput id="txt_name" width="320" text="以下、名無しに変わりましてfxug-nagoyaがお送りします"/>
        </s:HGroup>
        <s:VGroup width="770" verticalAlign="bottom">
            <s:Spacer height="5" width="5" />
            <s:Label text="Message: "/>
            <s:TextArea id="txt_message" width="100%" height="200"/>
        </s:VGroup>
        <s:Spacer width="20" height="10"/>
        <s:HGroup width="100%" horizontalAlign="right" verticalAlign="middle">
            <s:Button id="btn_cancel" label="Cancel" click="btn_cancel_clickHandler(event)"/>
            <s:Spacer width="20" height="10"/>
            <s:Button id="btn_post" label="Post" click="btn_post_clickHandler(event)"
                      fontWeight="bold"/>
            <s:Spacer width="20" height="10"/>
        </s:HGroup>
    </s:VGroup>

</s:TitleWindow>

[ EOF ]
---


このページの先頭へ