1. 程式人生 > >Springmvc+Apache Camel+Mybatis整合例項及分析

Springmvc+Apache Camel+Mybatis整合例項及分析

Spring MVC+Apache Camel+Mybatis整合例項及分析

最近在學習camel,公司之前做過的專案使用到了camel進行了很多工作。就連資料庫的操作也是通過camel來完成的。至於用camel來操作資料庫有什麼優點,目前就我自己的體會來說,利用camel能簡化CRUD操作service層的程式碼。沒用camel以前,各個物件的CRUD操作我都會有對應的service去處理。即使這些service很多都只是簡單地繼承一個CrudServcie然後用泛型限制一下該service處理的實體物件。這樣service的介面和實現類看上去很多,但是重複率極高。如果使用了camel,那麼我們就可以用camel來寫一個通用的service,這樣不管你是什麼實體類的操作,只要傳入型別和要呼叫的方法名就可以了。由於涉及到公司機密,所以我不會貼出成熟的原始碼,但是我可以提供一個自己的列子。我想只要從這個列子出發,稍作改進就能達到上文所提的效果。


例子的架構是這樣的:springmvc camel mybatis
依賴由maven來管理,其pom.xml的內容請下載列子原始碼檢視。
springmvc的配置就不用貼出來了,隨處可見。
這裡重點講一下spring跟配置檔案裡的一些配置專案,尤其是下面這一段:
[html]
<!-- 資料來源配置 使用事務控制 --> 
    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" 
        destroy-method="close"> 
        <property name="driverClassName" value="com.

mysql.jdbc.Driver" /> 
        <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8" /> 
        <property name="username" value="root" /> 
        <property name="password" value="fanly" /> 
        <property name="defaultAutoCommit" value="false" /> 
    </bean> 
 
    <bean id="transactionManager" 
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
        <property name="dataSource" ref="myDataSource" /> 
    </bean> 
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
        <property name="dataSource" ref="myDataSource" /> 
        <property name="configLocation" value="classpath:SqlMapConfig.xml" /> 
    </bean> 
    <bean id="required" class="org.apache.camel.spring.spi.SpringTransactionPolicy"> 
        <property name="transactionManager" ref="transactionManager" /> 
        <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" /> 
    </bean> 
    <bean id="mybatis" class="org.apache.camel.component.mybatis.MyBatisComponent"> 
        <property name="sqlSessionFactory" ref="sqlSessionFactory" /> 
    </bean> 
    <!-- 資料來源配置結束 --> 

<!-- 資料來源配置 使用事務控制 -->
    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
  destroy-method="close">
  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8" />
  <property name="username" value="root" />
  <property name="password" value="fanly" />
  <property name="defaultAutoCommit" value="false" />
 </bean>

    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="myDataSource" />
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="myDataSource" />
        <property name="configLocation" value="classpath:SqlMapConfig.xml" />
    </bean>
    <bean id="required" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="transactionManager" />
        <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" />
    </bean>
    <bean id="mybatis" class="org.apache.camel.component.mybatis.MyBatisComponent">
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>
    <!-- 資料來源配置結束 -->需要注意的是最後一項的配置,通過MyBatisComponent類,camel就知道如何通過使用者設定的路由來和mybatis進行互動了。這個MyBatisComponent實現了camel的component介面,至於component介面是用來幹什麼的,可以參考我的博文或者去檢視官方手冊。其實你可以把component簡單裡理解為camelContext和其他系統通訊的標準,不同的系統實現了component介面,就可以通過這個介面實現用camel標準API進行通訊。
這裡需要注意的是,MyBatisComponent有一個configurationUri屬性,他的預設值為SqlMapConfig.xml,也就是說在預設情況下MyBatisComponent會去載入類路徑下的SqlMapConfig.xml去初始化一些配置和使用者編寫的mapper檔案,你當然可以修改這個預設行為,怎麼修改呢?通過property注入你的配置檔案位置唄。這裡需要指出的是,之前我們單獨使用mybatis的時候,一種方式是定義一個mapper介面,然後在對應的mapper.xml中將該mapper問價的namespace設定為mapper介面的全路徑,這樣在執行時,mybatis會利用mapper.xml生成的代理類來作為mapper介面的實現類為程式提供資料訪問層的服務。那麼我們使用MyBatisComponent來和資料庫互動的時候,還要不要定義mapper介面呢?事實證明,我們不再需要定義mapper介面,我們只需要實現mapper.xml即可,那麼MyBatisComponent是如何載入到我們所實現的mapper.xml的呢?我們只要在SqlMapConfig.xml中指定我們的mapper.xml檔案即可。本例項程式碼的SqlMapConfig.xml檔案內容如下所示:
[html]
<?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="cacheEnabled" value="true" /> 
    </settings> 
 
    <mappers> 
        <mapper resource="com/ugarden/mapper/UserMapper.xml" /> 
    </mappers> 
     
</configuration> 

<?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="cacheEnabled" value="true" />
 </settings>

 <mappers>
  <mapper resource="com/ugarden/mapper/UserMapper.xml" />
 </mappers>
 
</configuration>我們再看看UserMapper.xml的內容:
[html]
<?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.ugarden.repository.UserMapper"> 
 
    <resultMap id="UserResult" type="com.ugarden.entity.User"> 
        <result property="id" column="id" /> 
        <result property="email" column="email" /> 
        <result property="realName" column="real_name" /> 
        <result property="password" column="password" /> 
    </resultMap> 
 
    <sql id="columns"> 
       <![CDATA[
          id,password,email,show_name,real_name
         ]]> 
    </sql> 
 
    <insert id="batchInsertUsers" parameterType="list" useGeneratedKeys="false"> 
    <![CDATA[
        INSERT INTO kf_user (
            id ,
            password ,
            email ,
            real_name
        ) VALUES 
      ]]> 
    <foreach collection="list" item="item" separator=","> 
      <![CDATA[
          ( 
            #{item.id} ,
            #{item.password} ,
            #{item.email} ,
            #{item.realName} 
          )
        ]]> 
    </foreach> 
    </insert> 
 
    <insert id="insert" parameterType="com.ugarden.entity.User" useGeneratedKeys="false" keyProperty="id"> 
    <![CDATA[
        INSERT INTO kf_user (
            id ,
            password ,
            email ,
            real_name 
        ) VALUES (
            #{id} ,
            #{password} ,
            #{email} ,
            #{realName} 
        )
    ]]> 
    </insert> 
 
    <update id="update" parameterType="com.ugarden.entity.User"> 
    <![CDATA[
        UPDATE kf_user SET
            password = #{password} ,
            email = #{email} ,
            real_name = #{realName} ,
        WHERE 
            id = #{id}
    ]]> 
    </update> 
 
    <delete id="deleteUsersRolesById" parameterType="string"> 
     <![CDATA[
        DELETE FROM kf_user_role
        WHERE 
          user_id = #{userId}
      ]]> 
    </delete> 
 
</mapper> 

<?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.ugarden.repository.UserMapper">

 <resultMap id="UserResult" type="com.ugarden.entity.User">
  <result property="id" column="id" />
  <result property="email" column="email" />
  <result property="realName" column="real_name" />
  <result property="password" column="password" />
 </resultMap>

 <sql id="columns">
       <![CDATA[
          id,password,email,show_name,real_name
         ]]>
 </sql>

 <insert id="batchInsertUsers" parameterType="list" useGeneratedKeys="false">
    <![CDATA[
        INSERT INTO kf_user (
          id ,
         password ,
         email ,
         real_name
        ) VALUES
      ]]>
 <foreach collection="list" item="item" separator=",">
      <![CDATA[
        (
         #{item.id} ,
         #{item.password} ,
         #{item.email} ,
         #{item.realName}
          )
        ]]>
 </foreach>
 </insert>

 <insert id="insert" parameterType="com.ugarden.entity.User" useGeneratedKeys="false" keyProperty="id">
    <![CDATA[
        INSERT INTO kf_user (
         id ,
         password ,
         email ,
         real_name
        ) VALUES (
         #{id} ,
         #{password} ,
         #{email} ,
         #{realName}
        )
    ]]>
 </insert>

 <update id="update" parameterType="com.ugarden.entity.User">
    <![CDATA[
        UPDATE kf_user SET
         password = #{password} ,
         email = #{email} ,
         real_name = #{realName} ,
        WHERE
         id = #{id}
    ]]>
 </update>

 <delete id="deleteUsersRolesById" parameterType="string">
  <![CDATA[
        DELETE FROM kf_user_role
        WHERE
          user_id = #{userId}
   ]]>
 </delete>

</mapper>


我們在這裡也設定了 namespace="com.ugarden.repository.UserMapper",但是我的專案裡是沒有對應的介面的,這裡不設定會不會出問題在寫本文的時候還沒有試驗。寫上總是好些,免得讓人感到迷茫。
那麼我們如何通過camel的API來操作資料庫呢?下面是UserServcie.java的內容:


[java]
@Service 
public class UserService { 
    @Autowired 
    private ProducerTemplate producerTemplate; 
    @Autowired 
    private CamelContext camelContext; 
     
    public void insertUser() throws Exception { 
         
        //init test user entity  
        User user = new User(); 
        user.setEmail("fanly" + System.currentTimeMillis() + "@126.com"); 
        user.setPassword("123456"); 
        user.setId(String.valueOf(System.currentTimeMillis())); 
        user.setRealName("張雙"); 
         
        Exchange in = this.camelContext.getEndpoint("direct:start").createExchange(ExchangePattern.InOut); 
        in.getIn().setBody(user); 
         
        Exchange out = this.producerTemplate.send("mybatis:insert?statementType=Insert", in); 
         
        if (null != out.getException()) { 
            throw out.getException(); 
        } 
         
    } 

@Service
public class UserService {
 @Autowired
 private ProducerTemplate producerTemplate;
 @Autowired
 private CamelContext camelContext;
 
 public void insertUser() throws Exception {
  
  //init test user entity
  User user = new User();
  user.setEmail("fanly" + System.currentTimeMillis() + "@126.com");
  user.setPassword("123456");
  user.setId(String.valueOf(System.currentTimeMillis()));
  user.setRealName("張雙");
  
  Exchange in = this.camelContext.getEndpoint("direct:start").createExchange(ExchangePattern.InOut);
  in.getIn().setBody(user);
  
  Exchange out = this.producerTemplate.send("mybatis:insert?statementType=Insert", in);
  
  if (null != out.getException()) {
   throw out.getException();
  }
  
 }
}


略懂camel的童鞋們立馬就明白了,這裡首先通過camelContext獲取到一個Endpoint,然後獲取到輸入過程的Exchange物件,由於資料的來源是我們程式提供的,所以endpoint的uri就設定為direct:start。然後將我們要新增的user物件新增到message物件的body中,再將我們的message物件路由到資料庫中,我們是通過producerTemplate物件向camelContext物件發出訊息的,路由資訊附加在了第一個引數中,即"mybatis:insert?statementType=Insert"如果你不懂這個引數的意思,去camel官方看看camel-mybatis的說明就明白了。這句的意思大概就是告訴camelContext物件,我要通過mybatis這個component物件呼叫一個名叫insert的方法,該方法的statement型別為Insert型別,將Message物件body裡的資料插入到資料庫。
你可能會問,你這個service裡面的producerTemplate,camelContext是哪裡來的,為什麼你通過一個"mybatis:insert?statementType=Insert"引數,camelContext就知道要去找那個component來進行路由呢?
莫慌,請看spring根配置檔案的如下配置內容:
[html]
<!-- camel context inti --> 
<camelContext id="camel" trace="true" xmlns="http://camel.apache.org/schema/spring"> 
    <package>com.ugarden</package> 
lt;/camelContext> 

 <!-- camel context inti -->
 <camelContext id="camel" trace="true" xmlns="http://camel.apache.org/schema/spring">
     <package>com.ugarden</package>
</camelContext>camelContext就是這樣來的,spring一啟動的時候他就存在了,如果你有多個camelContext例項的時候,你就要用id來區分注入了。
那producerTemplate是哪裡來的呢?剛開始我也糾結這個問題,最後看了一下camelContext的createProducerTemplate的方法註釋,發現它是和camelContext一起初始化的,這樣就能解釋為什麼spring能幫我們注入了。
那camel如何知道"mybatis:insert?statementType=Insert"中mybatis指的是哪個呢?您還記得這段配置嗎?
[html]
<bean id="mybatis" class="org.apache.camel.component.mybatis.MyBatisComponent"> 
    <property name="sqlSessionFactory" ref="sqlSessionFactory" /> 
 </bean> 

<bean id="mybatis" class="org.apache.camel.component.mybatis.MyBatisComponent">
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
 </bean>你看看他的ID,我想如果有多個數據源的時候,我再做如下配置:
[html]
<bean id="mybatis1" class="org.apache.camel.component.mybatis.MyBatisComponent"> 
    <property name="sqlSessionFactory" ref="sqlSessionFactory" /> 
 </bean> 

<bean id="mybatis1" class="org.apache.camel.component.mybatis.MyBatisComponent">
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
 </bean>那麼我是不是可以通過"mybatis1:insert?statementType=Insert"這樣來路由呢?是不是試過才知道,寫完我就去試一試,camel官方的uri支援範圍裡是絕對沒有mybatis1這種東西的。


現在回到文章開始的問題來,我們如何通過camel來做一個統一的service層呢?很簡單,我們只需要將要呼叫的方法名,body裡要路由到資料庫的物件,通過引數的方式傳遞進來不就可以容納一切變化了嗎?從此以後我們只需要通過資料表生成以下mapper.xml,再謝謝特殊的sql就好了。只要是資料庫的操作,我們都可以通過camel實現的一個superService類搞定。
最後附上整個例子的原始碼供童鞋們下載交流。專案在我的資源欄目裡,當然是免積分的了。

相關推薦

Springmvc+Apache Camel+Mybatis整合例項分析

Spring MVC+Apache Camel+Mybatis整合例項及分析 最近在學習camel,公司之前做過的專案使用到了camel進行了很多工作。就連資料庫的操作也是通過camel來完成的。至於用camel來操作資料庫有什麼優點,目前就我自己的體會來說,利用came

spring、mybatis整合原始碼簡單分析

配置 <bean id="localDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">

Netty入門例項分析

import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel

Spring SpringMvc 3.0 + MyBatis 整合--補充關於.properties檔案的讀取

上篇文章中關於.propertis檔案的每條記錄在xml檔案裡面配置,如下圖 新方法: 專案啟動時候自動掃描.propertis裡面的每條內容到map中. 配置檔案: <bean id

MyBatis簡單例項配置檔案解析

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/

Spring SpringMvc 3.0 + MyBatis 整合

一、使用的jar包就不詳細講解了,下載了Mybatis 和 Spring 的jar包基本上都新增上去了、 一圖概括:(這是我使用的ar包,有些不是Mybatis 和 Spring 的 ) 二、 web.xml配置檔案 <?xml version="1.0" en

Apache Camel框架整合Spring

Apache Camel提供了和Spring的整合,通過Spring容器(ApplicationContext)來管理Camel的CamelContext,這樣的話,就不需要寫程式碼來控制CamelContext的初始化,啟動和停止了.Camel會隨著Spring的啟動而啟

Java GC 分析,JVM生產環境引數例項分析,JVM詳細配置

什麼是 Java GC Java GC(Garbage Collection,垃圾收集,垃圾回收)機制,是Java與C++/C的主要區別之一,作為Java開發者,一般不需要專門編寫記憶體回收和垃圾清理程式碼,對記憶體洩露和溢位的問題,也不需要像C程式設計師那樣戰戰兢兢。這是

JVM系列四:生產環境引數例項分析

java application專案(非web專案) 改進前: -Xms128m-Xmx128m-XX:NewSize=64m-XX:PermSize=64m-XX:+UseConcMarkSweepGC-XX:CMSInitiatingOccupancyFraction=78-XX:ThreadStac

MyBatis整合Spring原理分析

目錄MyBatis整合Spring原理分析MapperScan的祕密簡單總結 假如不結合Spring框架,我們使用MyBatis時的一個典型使用方式如下: public class UserDaoTest { private SqlSessionFactory sqlSessionFactory

Spring+SpringMVC+MyBatis深入學習搭建(十四)——SpringMVCMyBatis整合

文件拷貝 conf lips glib ide doc from ive body 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/7010363.html 前面講到:Spring+SpringMVC+MyBatis深入學習及搭建(

springMVC整合mybatis+generator例項

我們在eclipse中新建一個maven-app的專案。將專案build Path。將jdk換成自己的!!同樣將tomcat配好。 首先看包的結構  在pom.xml檔案中新增 <project xmlns="http://maven.apache.org/POM/

Spring+SpringMVC+Mybatis+Mysql整合例項

       本文要實現Spring+SpringMVC+Mybatis+Mysql的一個整合,實現了SpringMVC控制訪問的頁面,將得到的頁面引數傳遞給Spring中的Mybatis的bean類,然後查詢Mysql資料的功能,並通過JSP顯示出來。建議可以先看筆者另

Spring+SpringMVC+MyBatis深入學習搭建(九)——MyBatis和Spring整合

1.整合思路需要Spring通過單例方式管理SqlSessionFactory。Spring和MyBatis整合生成代理物件,使用SqlSessionFactory建立SqlSession。(Spring和MyBatis整合自動完成)持久層的mapper都需要由Spring進

mybatis整合springmvc時的錯誤org.apache.ibatis.binding.BindingException: Invalid bound statement (not found

今天在除錯mybatis,新增一個搜尋功能的時候報了一個這個錯誤 <span style="white-space:pre"> </span>rg.springframewor

Apache Shiro+SpringMVC+Hibernate Search+Hibernate+Bootstrap企業資訊管理系統基礎框架搭建整合例項程式碼教程

轉載:http://www.zuidaima.com/share/1764524204903424.htm 問題1:非常非常非常抱歉!!以為我的疏忽導致static目錄沒放進原來的專案!!浪費大家精力調bug。。。實在很對不起,現在重新上傳!!希望有問題的同學可以私信我或者Q群私聊(我不是很常上qq,但願發

SpringMVC + Spring + Mybatis + Maven整合例項

一、說明: 目前工作中的開發框架主要是 spring ,使用的是 springMVC+ spring + spring JdbcTemplate ,最近學習了一下Mybatis、Maven這些內容,所以嘗試使用 springMVC + Spring + Mybatis +

dubbo SpringMVC MyBatis 整合環境 開發中遇到的一些錯誤提示解決辦法

1.Handler processing failed; nested exception is java.lang.NoSuchMethodError找不到這個方法,後面給出相應方法路徑解決辦法:1.檢查呼叫的路徑是否正確2.是不是存在同名檔案,有可能查詢到另一個檔案裡,而

Spring+SpringMVC+mybatis+easyui整合例項-----easyUI介面部分

首先簡單介紹下easyui的使用。  我們從datagrid表格入手,先顯示一個簡單的表格來說明一下easyui的使用。後面再加一個功能完整的表格 首先方法寫好,還是使用之前的例子,沒看過之前部落格的可以翻一下。  StudentDaoIF.java @Select(

SpringMVC+Spring+Hibernate+Mybatis+Shiro等整合開發(2)

    spring+hibernate+mybatis整合    上面我們整合spring 和springmvc 因為都是spring的東西所以只要保證版本一致就能順利的跑起來。我使用的本本如下<properties> <spring.ve