Spring訪問資料庫(oracle)配置
1.spring 對資料庫訪問的支援
當我們開發持久層的時候,我們面臨著多種選擇,比如使用JDBC、Hibernate、java持久化API或其它持久化框架。幸好的是spring能夠支援所有這些持久化機制。
DAO(data access boject)資料訪問物件,這個名字就很形象描述了DAO在應用程式中所扮演的角色。DAO提供了資料的讀取、寫入到資料庫中的一種方式。它們應該以介面的方式釋出功能,而應用程式的其它部分就可以通過介面來進行訪問了。
注:服務物件本身並不會處理資料訪問,而是將資料訪問委託給DAO。DAO介面確保其與服務物件的鬆耦合。
2.配置資料來源
spring提供了在spring上下文中配置資料來源Bean的多種方式,包括:
a.通過JDBC驅動程式定義的資料來源;
b.通過JNDI查詢的資料來源;
c.連線池的資料來源;
接下我們就專門來講講從使用連線池獲取連線的資料來源!(即c點)
上下文配置Bean的程式碼:
?12345678910111213141516 | <! --配置資料來源 --> <bean id= "dataSource" class= "org.apache.commons.dbcp.BasicDataSource" > <property name = "driverClassName" value= "oracle.jdbc.driver.OracleDriver" /> <property name = "url" value= "jdbc:oracle:thin:@localhost:1521:orcl" /> <property name = "username" value= "wwo" /> <property name = "password" value= "wwo" /> <! -- 連線池啟動時的初始值 --> <property name = "initialSize" value= "3" /> <! -- 連線池的最大值 --> <property name = "maxActive" value= "300" /> <! -- 最大空閒值.當經過一個高峰時間後,連線池可以慢慢將已經用不到的連線慢慢釋放一部分,一直減少到maxIdle為止 --> <property name = "maxIdle" value= "2" /> <! -- 最小空閒值.當空閒的連線數少於閥值時,連線池就會預申請去一些連線,以免洪峰來時來不及申請 --> <property name = "minIdle" value= "1" /> <! -- end --> </bean> |
注:JDBC驅動資料來源並沒有池的概念,因此沒有存在池屬性的配置!
好了,到這一步,我們已經完成了通過資料來源建立了與資料庫的連線,接下來就是實際訪問資料庫了。
3.在Spring中整合Hibernate
Hibernate一些特性:
a.延遲載入(Lazy loading):例如一個Bean物件由其屬性及另一個Bean物件組成,如果我們只關注的只是這個Bean物件的屬性,那麼我們可以藉助於延遲載入,只抓取需要的資料;
b.預先抓取(Eager fetching):這與延遲載入是相對的,一個Bean所關聯的其它Bean都會被查詢出來,這就節省了多次查詢的成本;
c.級聯(Cascading):有時候刪除一個Bean物件後,也希望其同時能資料庫中刪除掉與其關聯的其它Bean。
Spring對Hibernate ORM框架的支援提供了與這些框架整合點以及一些附加的服務,如下所示:
a.Spring宣告式事務的整合支援;
b.透明的異常處理;
c.執行緒安全的、輕量級的模板類;
d.DAO支援類;
e.資源管理。
4.宣告會話工廠(Session Factory)
使用Hibernate的主要介面是org.hibernate.Session。Session提供了基本的資料訪問功能,如儲存、更新、刪除以及從資料庫載入物件的功能。
能過藉助於Hibernate的SessionFactory來獲取Session物件,SessionFactory主要負責Hibernate Session的開啟、關閉以及管理。
配置在xml上下文的Bean如下:
?123456789101112131415161718 | <bean id= "sessionFactory" class= "org.springframework.orm.hibernate4.LocalSessionFactoryBean" > <property name = "dataSource" ref= "dataSource" /> <property name = "packagesToScan" > <! --掃描一下實體目錄 --> <list> <value>com.blog.entity</value> </list> </property> <property name = "hibernateProperties" > <props> <prop key = "hibernate.dialect" >org.hibernate.dialect.Oracle10gDialect</prop> <prop key = "hibernate.show_sql" > true </prop> <prop key = "hibernate.format_sql" > true </prop> <prop key = "current_session_context_class" >thread</prop> </props> </property> </bean> |
5.建立自己的基礎DAO類
Spring可以通過Spring的Hibernate模板來保證每個事務都使用同一個會話。既然Hibernate能夠對其自己進行管理,那就不必要使用模板類了。接下我們直接將Hibernate Session裝配到自己的DAO類中。
?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 | /** * 基礎dao * * @author ckz * * @param <T> */ public abstract class BaseDAO<T> { /** * 注入sessionFactory */ @Autowired private SessionFactory sessionFactory; /** * 獲得session * * @ return */ protected Session getCurrentSession() { return sessionFactory.getCurrentSession(); } /** * 儲存 * * @param entity * @throws Exception */ public void add (T entity) throws Exception { getCurrentSession().save(entity); } /** * 呼叫儲存過程 * * @param proName * @ return */ public CallableStatement citePro(final String proName){ Session session = getCurrentSession(); CallableStatement proc=session.doReturningWork( new ReturningWork<CallableStatement>() { @Override public CallableStatement execute ( Connection connection ) throws SQLException{ CallableStatement resultSet = connection .prepareCall(proName); return resultSet; } } ); return proc; } /** * 更新 * * @param entity * @throws Exception */ public void update (T entity) throws Exception { getCurrentSession(). update (entity); } /** * 儲存或更新 * * @param entity * @throws Exception */ public void saveOrUpdate(T entity) throws Exception { getCurrentSession().saveOrUpdate(entity); } /** * 刪除 * * @param entity * @throws Exception */ public void delete (T entity) throws Exception { getCurrentSession(). delete (entity); } } |
</dd>