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.
<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深入學習及搭建(十四)——SpringMVC和MyBatis整合
文件拷貝 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