云自無心水自閑

          天平山上白云泉,云自無心水自閑。何必奔沖山下去,更添波浪向人間!
          posts - 288, comments - 524, trackbacks - 0, articles - 6
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          日歷

          <2010年2月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28123456
          78910111213

          隨筆檔案

          積分與排名

          • 積分 - 1129359
          • 排名 - 27

          最新評論

          IBatis3中使用自定義數據源C3P0

          Posted on 2010-02-01 12:57 云自無心水自閑 閱讀(3929) 評論(2)  編輯  收藏 所屬分類: Java心得體會iBatis
          IBatis2中提供了3種DataSource的配置:JNDI, Apache DBCP, IBatis自帶的SimpleDataSource。但在IBatis3中只提供了兩種DataSource: UNPOOLED, POOLED。
          如果要實現自定義的DataSource,就需要通過擴展DataSourceFactory。本文就演示一下這個過程。
          準備工作:Connection Pool的選擇,通過搜索發現目前比較流行的免費數據庫連接池主要有3種:Apache DBCP, C3P0, Proxool。
          看了一下,Proxool的最新版本是0.9.1(2008-08-23), C3P0的最新版本是0.9.1.2(2007-05-21), DBCP最新版本是1.2.2(2007-04-04)
          好像這3個項目都已經挺長時間沒有更新了。但是總體評價上C3P0無論從穩定上還是效率上都要好一點。
          (具體這3個項目誰更優秀,并不是本文的重點,本文主要是介紹一下如何在IBatis3中自定義數據源)
          大致步驟:
          1、實現org.apache.ibatis.datasource.DataSourceFactory接口,主要是2個方法
          a、public DataSource getDataSource() 如何具體地得到一個數據源
          b、public void setProperties(Properties properties) 如何設置數據源的參數屬性
          2、實現javax.sql.DataSource,這個就是提供給DataSourceFactory的實例
          3、在IBatis3中引用新加入的數據源

          1. 從代碼中可以看出,IBatis3與IBatis2不同,不再通過一個Configuration類來進行數據源屬性的設置,而是使用反射機制直接調用數據源的方法來設置參數。
          這就要求配置文件中的參數名稱必須與數據源類中的方法名匹配.
           1 public class C3p0DataSourceFactory implements DataSourceFactory {
           2 
           3     private DataSource dataSource;
           4 
           5     public C3p0DataSourceFactory() {
           6         dataSource = new C3p0DataSource();
           7     }
           8 
           9     public DataSource getDataSource() {
          10         return dataSource;
          11     }
          12 
          13     public void setProperties(Properties properties) {
          14         Properties driverProperties = new Properties();
          15         MetaObject metaDataSource = MetaObject.forObject(dataSource);
          16         for (Object key : properties.keySet()) {
          17             String propertyName = (String) key;
          18             if (propertyName.startsWith(DRIVER_PROPERTY_PREFIX)) {
          19                 String value = properties.getProperty(propertyName);
          20                 driverProperties.setProperty(propertyName
          21                         .substring(DRIVER_PROPERTY_PREFIX_LENGTH), value);
          22             } else if (metaDataSource.hasSetter(propertyName)) {
          23                 String value = (String) properties.get(propertyName);
          24                 Object convertedValue = convertValue(metaDataSource,
          25                         propertyName, value);
          26                 metaDataSource.setValue(propertyName, convertedValue);
          27             } else {
          28                 throw new DataSourceException("Unkown DataSource property: "
          29                         + propertyName);
          30             }
          31         }
          32         if (driverProperties.size() > 0) {
          33             metaDataSource.setValue("driverProperties", driverProperties);
          34         }
          35     }
          36 
          37     @SuppressWarnings("unchecked")
          38     private Object convertValue(MetaObject metaDataSource, String propertyName,
          39             String value) {
          40         Object convertedValue = value;
          41         Class targetType = metaDataSource.getSetterType(propertyName);
          42         if (targetType == Integer.class || targetType == int.class) {
          43             convertedValue = Integer.valueOf(value);
          44         } else if (targetType == Long.class || targetType == long.class) {
          45             convertedValue = Long.valueOf(value);
          46         } else if (targetType == Boolean.class || targetType == boolean.class) {
          47             convertedValue = Boolean.valueOf(value);
          48         }
          49         return convertedValue;
          50     }
          51 
          52     private static final String DRIVER_PROPERTY_PREFIX = "driver.";
          53     private static final int DRIVER_PROPERTY_PREFIX_LENGTH = DRIVER_PROPERTY_PREFIX
          54             .length();
          55 
          56 }
          57 

          2. 數據源類,其中的一堆setter就是用于設置屬性的。
           1 public class C3p0DataSource implements DataSource {
           2 
           3     private ComboPooledDataSource dataSource;
           4     public C3p0DataSource() {
           5         this.dataSource = new ComboPooledDataSource();
           6     }
           7     
           8     public Connection getConnection() throws SQLException {
           9         return dataSource.getConnection();
          10     }
          11 
          12     public Connection getConnection(String username, String password)
          13             throws SQLException {
          14         return dataSource.getConnection(username, password);
          15     }
          16 
          17     public PrintWriter getLogWriter() throws SQLException {
          18         return dataSource.getLogWriter();
          19     }
          20 
          21     public int getLoginTimeout() throws SQLException {
          22         return dataSource.getLoginTimeout();
          23     }
          24 
          25     public void setLogWriter(PrintWriter out) throws SQLException {
          26         dataSource.setLogWriter(out);
          27     }
          28 
          29     public void setLoginTimeout(int seconds) throws SQLException {
          30         dataSource.setLoginTimeout(seconds);
          31     }
          32     
          33     
          34     public synchronized void setDriver(String driver) {
          35         try {
          36             dataSource.setDriverClass(driver);
          37         } catch (Exception e) {
          38         }
          39     }
          40     
          41     public void setUrl(String url) {
          42         dataSource.setJdbcUrl(url);
          43     }
          44     
          45     public void setUsername(String username) {
          46           dataSource.setUser(username);
          47     }
          48 
          49     public void setPassword(String password) {
          50         dataSource.setPassword(password);
          51     }
          52     
          53     public void setInitialPoolSize(int initialPoolSize) {
          54         dataSource.setInitialPoolSize(initialPoolSize);
          55     }
          56     
          57     public void setMaxPoolSize(int maxPoolSize) {
          58         dataSource.setMaxPoolSize(maxPoolSize);
          59     }
          60       
          61     public void setMinPoolSize(int minPoolSize) {
          62         dataSource.setMinPoolSize(minPoolSize);
          63     }
          64     
          65     public void setPreferredTestQuery(String preferredTestQuery) {
          66         dataSource.setPreferredTestQuery(preferredTestQuery);
          67     }
          68     
          69     public void setPoolPingQuery(String poolPingQuery) {
          70         dataSource.setPreferredTestQuery(poolPingQuery);
          71     }
          72 }

          3. 在配置文件Configuration.xml中,可以先定義數據源的別稱,然后就象POOLED和UNPOOLED一樣使用別稱來引用數據源。
          <Configuration>
              ...
              <typeAlias>
                  <typeAlias type="com.test.datasource.C3p0DataSourceFactory" alias="C3P0"/>
              </typeAlias>
              <environments default="development">
                  <environment id="development">
                      <transactionManager type="JDBC"/>
                      <dataSource type="C3P0">
                          <property name="driver" value="${jdbc.driver}"/>
                          <property name="url" value="${jdbc.url}"/>
                          <property name="username" value="${jdbc.username}"/>
                          <property name="password" value="${jdbc.password}"/>
                          <property name="poolPingQuery" value="${pingquery}"/>           
                      </dataSource>
                  </environment>
              </environments>
              ...
          <Configuration>






          評論

          # re: IBatis3中使用自定義數據源C3P0  回復  更多評論   

          2010-11-07 01:39 by wppurking
          1. public class C3p0 extends UnpooledDataSourceFactory;
          (com.package.c3p0_ibatis)

          2. 配置文件中設置
          <environments default="development">
          <environment id="development">
          <transactionManager type="JDBC"/>
          <dataSource type="com.package..C3p0"> <!-- 配置全名 -->
          <!-- 連接池設置由C3p0.properties自己決定 -->
          </dataSource>
          </environment>
          </environments>

          3. 將 c3p0.properties 文件放入 classpath 中

          這樣省去很多代碼,還可以完全設置 c3p0 的各個配置屬性,簡單很多,試一下?

          # re: IBatis3中使用自定義數據源C3P0  回復  更多評論   

          2010-11-07 01:41 by wppurking
          補充一下:繼承后需要與 PooledDataSourceFactory 做同樣的操作,編寫自己的無參構造方法: this.dataSource = new ComboPooledDataSource();
          主站蜘蛛池模板: 中阳县| 九江县| 嵊州市| 响水县| 余姚市| 修武县| 齐齐哈尔市| 乌兰县| 博客| 台江县| 繁峙县| 确山县| 临沂市| 仁化县| 湛江市| 句容市| 托克托县| 宝应县| 育儿| 剑阁县| 炎陵县| 监利县| 朝阳县| 五原县| 武邑县| 织金县| 昌邑市| 吉安市| 沧源| 阆中市| 丰宁| 芜湖市| 湖南省| 昭觉县| 襄垣县| 历史| 克什克腾旗| 寿宁县| 双柏县| 两当县| 固镇县|