上一篇SpringMVC之web.xml讓我們了解到配置一個web項目的時候,如何做基礎的DispatcherServlet相關配置,作為SpringMVC上手的第一步,而application-context.xml則讓我們了解到如何將數據庫信息加載到項目中,包含關鍵的數據庫連接信息、sqlSessionFactory、事務等關鍵因素。
file:C:/properties/ymeng.properties
select 1 from DUAL
file:C:/properties/ymeng.properties
使用了file前綴引導spring從c盤固定的路徑加載數據庫連接信息。
剛看到這個類的時候,你也許會有一種似曾相識的感覺,沒錯,她繼承了PropertyPlaceholderConfigurer類,只不過我為她加了一層神秘的色彩(Encrypt嘛),其作用呢,就是為了不直接在項目運行環境中暴露數據庫連接信息,比如說數據庫用戶名、密碼、URL等,這樣就等於系統多了一層的安全級別,個人覺得還是非常有用的,所以我之前總結了一篇SpringMVC使用隱式jdbc連接信息。
標題寫的是SpringMVC,同樣適用於Spring,那麼這裡我就不再唠叨了。
select 1 from DUAL
使用了dbcp的數據庫連接池。
DBCP(DataBase connection pool),數據庫連接池。是 apache 上的一個 java 連接池項目,也是 tomcat 使用的連接池組件。單獨使用dbcp需要2個包:commons-dbcp.jar,commons-pool.jar由於建立數據庫連接是一個非常耗時耗資源的行為,所以通過連接池預先同數據庫建立一些連接,放在內存中,應用程序需要建立數據庫連接時直接到連接池中申請一個就行,用完後再放回去。
destroy-method=”close”的作用就是當數據庫連接不使用的時候,就把該連接重新放到數據池中,方便下次使用調用.很關鍵的一個元素。
關於數據庫連接信息URL、username等就不解釋了。
關於數據庫連接池信息我到現在還沒有搞得很明白,之前也調查了很多次,不見效果,無奈。。。。
testOnBorrow、validationQuery:通過“select 1 from DUAL”查詢語句來驗證connection的有效性。網上還有很多資源對這塊有專業的解釋,反正我是沒有看得太明白,之前也曾專門調查過這塊東西,現在也回想不起來了,以後再碰到的時候再補充進來。
sqlSessionFactory對於Spring以及mybatis來說就比較關鍵了,spring在建立sql連接使都會使用到這個。由於我的不專業性,所以關於更深入的解釋,我就不來了,反正對於我來說,這段配置就是為了和數據庫連接鏈接、創建事務管理。
創建sqlSessionFactory時,可能還需要為mybatis配置別名,那麼此處改為如下格式:
mybatis-config.xml
這樣在mapper的xml文件中就可以使用Deals,而不再是com.honzh.biz.database.entity.Deals全名。
transactionManager就是為了開啟事務。通過tx:annotation-driven就可以直接在方法或者類上加“@transactional”來開啟事務回滾。關於這段,我也必須誠實的說,我只停留在會用的基礎上。
通過spring的IOC機制(依賴注入),配置springcontext的管理器,該類的具體內容見如下:
package com.honzh.common.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* SpringContextHolder
* Spring Context Holder
* Create on : 2011-12-31
*
* Copyright (C) Ecointel Software Co.,Ltd.
*
* @author peng.shi [email protected]
* @version Ecointel v1.0.0
*/ public class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext applicationContext; public void setApplicationContext(ApplicationContext applicationContext) { SpringContextHolder.applicationContext = applicationContext; } /** * 得到Spring 上下文環境 * @return */ public static ApplicationContext getApplicationContext() { checkApplicationContext(); return applicationContext; } /** * 通過Spring Bean name 得到Bean * @param name bean 上下文定義名稱 */ @SuppressWarnings("unchecked") public static
如此,我們就可以輕松的通過SpringContextHolder.getBean方法獲取對應的bean類,就不再通過new關鍵字來創建一個類了,當然該類必須有注解標識,比如說@Service、@Component等。
該段配置的目的就是掃描mapper接口,也就是你sql語句的地方。當系統啟動運行時,spring會加載你的mapper類,然後檢查對應的sql語句是否正確,比如字段名是否匹配等等,若不匹配系統自然會報錯。另外特別注意的是basePackage的value值一定要正確,我就曾深受其害。
ps:
這裡請注意,當mybatis-3.1.1-SNAPSHOT.jar的版本為3.0以上時,這樣的配置就可能會引發這樣的錯誤
org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class ‘${driver}’
有同仁解釋了一下這個道理,見如下
在spring裡使用org.mybatis.spring.mapper.MapperScannerConfigurer 進行自動掃描的時候,設置了sqlSessionFactory 的話,可能會導致PropertyPlaceholderConfigurer失效,也就是用${jdbc.username}這樣之類的表達式,將無法獲取到properties文件裡的內容。 導致這一原因是因為,MapperScannerConigurer實際是在解析加載bean定義階段的,這個時候要是設置sqlSessionFactory的話,會導致提前初始化一些類,這個時候,PropertyPlaceholderConfigurer還沒來得及替換定義中的變量,導致把表達式當作字符串復制了。 但如果不設置sqlSessionFactory 屬性的話,就必須要保證sessionFactory在spring中名稱一定要是sqlSessionFactory ,否則就無法自動注入。又或者直接定義 MapperFactoryBean ,再或者放棄自動代理接口方式。
那麼此時的簡單解決辦法就是將xml改為如下格式:
<code class="language-xml hljs "> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.honzh.biz.database.mapper"> </property></bean> </code>