程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Spring數據源的靈活配置巧應用

Spring數據源的靈活配置巧應用

編輯:關於JAVA

環境:

Java SE 1.5

Spring-2.5.1

mysql-connector-java-5.1.5.zip

Mysql 5.x

為了從數據庫中取得數據,我們首先需要獲取一個數據庫連接。 Spring通過DataSource對象來完成這個工作。 DataSource是JDBC規范的一部分, 它被視為一個通用的數據庫連接工廠。通過使用DataSource, Container或Framework可以將連接池以及事務管理的細節從應用代碼中分離出來。 作為一個開發人員,在開發和測試產品的過程中,你可能需要知道連接數據庫的細節。 但在產品實施時,你不需要知道這些細節。通常數據庫管理員會幫你設置好數據源。

在使用Spring JDBC時,你既可以通過JNDI獲得數據源,也可以自行配置數據源( 使用Spring提供的DataSource實現類)。使用後者可以更方便的脫離Web容器來進行單元測試。 這裡我們將使用DriverManagerDataSource,不過DataSource有多種實現, 後面我們會講到。使用DriverManagerDataSource和你以前獲取一個JDBC連接 的做法沒什麼兩樣。你首先必須指定JDBC驅動程序的全限定名,這樣DriverManager 才能加載JDBC驅動類,接著你必須提供一個url(因JDBC驅動而異,為了保證設置正確請參考相關JDBC驅動的文檔), 最後你必須提供一個用戶連接數據庫的用戶名和密碼。

以上兩段文字摘自Spring開發文檔原文,下面我寫的一個小的應用,用來測試Srping JDBC支持的效果。

下面這個測試要實現一個目標:通過獲取Spring的數據源來查詢MySQL數據庫testdb的一個表t_user數據。

一、創建項目,加載程序用到的工具包和驅動。並在源代碼目錄中添加Spring的配置文件ApplicationContext.xml,配置內容如下:

<?xml version="1.0" encoding="gb2312"?>
   <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
   <beans>
     <!--數據庫的數據源定義-->
     <bean id="rptds" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
       <property name="driverClassName">
         <value>com.mysql.jdbc.Driver</value>
       </property>
       <property name="url">
         <value>jdbc:mysql://localhost:3306/testdb</value>
       </property>
       <property name="username">
         <value>root</value>
       </property>
       <property name="password">
         <value>leizhimin</value>
       </property>
     </bean>
   </beans>

二、然後創建數據庫環境:

create database if not exists testdb;
   DROP TABLE IF EXISTS t_user;
   CREATE TABLE t_user (
    id int(11) NOT NULL auto_increment,
    firstname varchar(50) default NULL,
    lastname varchar(50) default NULL,
    zipcode varchar(10) default NULL,
    tel varchar(20) default NULL,
    address varchar(200) default NULL,
    PRIMARY KEY (id)
   ) ENGINE=InnoDB DEFAULT CHARSET=gbk;
   insert into t_user(id,firstname,lastname,zipcode,tel,address) values
   (1,'haha','hehe','234444','13577788999','阿斯地方'),
   (2,'lei','aaa','450000','13939012107','鄭州市經三路');

三、Spring Bean容器環境獲取工具類

package com.lavasoft.dbtest;
   import org.springframework.context.support.ClassPathXmlApplicationContext;
   /**
   * Created by IntelliJ IDEA.
   * File: ContextHelper.java
   * User: leizhimin
   * Date: 2008-2-21 14:20:46
   * Spring Bean容器環境獲取工具類
   */
   public final class ContextHelper {
     private static ClassPathXmlApplicationContext _ctx;
   static {
       _ctx = new ClassPathXmlApplicationContext("ApplicationContext.xml");
     }
   private ContextHelper() {
     }
   public static ClassPathXmlApplicationContext getContext() {
       return _ctx;
     }
   }

三、寫獲取數據庫工具類

package com.lavasoft.dbtest;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   import javax.sql.DataSource;
   import java.sql.Connection;
   import java.sql.SQLException;
   import java.sql.CallableStatement;
   /**
   * Created by IntelliJ IDEA.
   * File: DBUtil.java
   * User: leizhimin
   * Date: 2008-2-21 14:26:30
   * 數據庫工具
   */
   public final class DBUtil {
     private static final Log log = LogFactory.getLog(DBUtil.class);
   /**
     * 獲取系統的數據源
     *
     * @return DataSource
     */
     public static DataSource getDataSource() {
       DataSource dataSource = null;
       try {
         dataSource = (DataSource) ContextHelper.getContext().getBean("rptds");
       } catch (Exception e) {
         log.error("獲取數據源出錯,請檢查Spring數據源配置!");
       }
       return dataSource;
     }
   /**
     * 獲取數據庫連接
     *
     * @return Connection
     */
     public static Connection makeConnection() {
       Connection conn = null;
       try {
         conn = getDataSource().getConnection();
       } catch (SQLException e) {
         log.error("通過數據源獲取數據庫連接發生異常!");
         e.printStackTrace();
       }
       return conn;
     }
   /**
     * 執行沒有參數的SQL過程
     *
     * @param procedureName 存儲過程名字
     * @return boolean   返回存儲過程執行的結果,true表示執行成功,false表示執行失敗.
     */
     public static boolean executeBSDProcedure(String procedureName) {
       boolean flag = false;
       String sqlStr = "{call " + procedureName + "()}";
       CallableStatement cs;
       Connection conn = makeConnection();
       try {
         cs = (CallableStatement) conn.prepareStatement(sqlStr);
         cs.executeUpdate(sqlStr);
         flag = true;
       } catch (SQLException e) {
         log.error("調用存儲過程" + sqlStr + "失敗!");
         e.printStackTrace();
       }
       return flag;
     }
   }

四、寫測試類

package com.lavasoft.dbtest;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   import java.sql.Connection;
   import java.sql.Statement;
   import java.sql.ResultSet;
   import java.sql.SQLException;
   /**
   * Created by IntelliJ IDEA.
   * File: Test.java
   * User: leizhimin
   * Date: 2008-2-21 14:41:49
   * Spring 數據源應用測試
   */
   public class Test {
     private static final Log log = LogFactory.getLog(Test.class);
   public static void main(String args[]) {
       Test.test();
     }
   public static void test() {
       String testSql = "select * from t_user";
       Connection conn = DBUtil.makeConnection();
       Statement stmt = null;
       try {
         stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);
         ResultSet rs = stmt.executeQuery(testSql);
         while (rs.next()) {
           String firstName = rs.getString("firstname");
           String lastName = rs.getString("lastname");
           System.out.println(firstName + " " + lastName);
         }
       } catch (SQLException e) {
         e.printStackTrace();
       } finally {
         if (stmt != null) {
           try {
             stmt.close();
           } catch (SQLException e) {
             log.info("關閉Statement對象出現異常!");
             e.printStackTrace();
           }
         }
         if (conn != null) {
           try {
             conn.close();
           } catch (SQLException e) {
             log.error("關閉數據庫連接失敗!");
             e.printStackTrace();
           }
         }
       }
     }
   }

測試運行結果:

haha hehe
   lei aaa
   Process finished with exit code 0

五、數據源置換

Spring實現的DriverManagerDataSource並沒有提供連接池的功能,只是用來作簡單的單機連接測試,並不適合使用於真正的項目當中,可以考慮用比較成熟的數據連接池來取代。Apache DBCP連接池是不錯,如要要替換,則需要加載DBCP相關的工具包。

<?xml version="1.0" encoding="gb2312"?>
   <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
   <beans>
     <!--數據庫的數據源定義-->
     <bean id="rptds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
       <property name="driverClassName">
         <value>com.mysql.jdbc.Driver</value>
       </property>
       <property name="url">
         <value>jdbc:mysql://localhost:3306/testdb</value>
       </property>
       <property name="username">
         <value>root</value>
       </property>
       <property name="password">
         <value>leizhimin</value>
       </property>
     </bean>
   </beans>

現在所使用的是org.apache.commons.dbcp.BasicDataSource作為注入的DataSource實例,為了使用DBCP 的功能,您需要在Classpath路徑中設定commons-dbcp.jar、commons-pool.jar與commons- collections.jar。注意到在dataSource上設定了"destroy-method"屬性,如此可以確保BeanFactory在關閉時也一並關閉BasicDataSource。

六、使用JNDI數據源

如果您的Servlet容器提供了JNDI(Java Naming and Directory Interface)的DataSource,您也可以簡單的換上這個DataSource:

<?xml version="1.0" encoding="gb2312"?>
   <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
   <beans>
     <!--數據庫的數據源定義-->
     <bean id="dataSource"
        class="org.springframework.indi.JndiObjectFactoryBean">
       <property name="jndiName">
         <value>jdbc/testds</value>
       </property>
     </bean>
   </beans>

為了使用org.springframework.indi.JndiObjectFactoryBean,您需要spring-context.jar,"jndiName"實際上要根據您所設定的JNDI查詢名稱。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved