對JDBC的支持之集成Spring JDBC及最佳實踐

zjyongning 8年前發布 | 26K 次閱讀 JDBC Spring Java開發

來自: http://www.importnew.com/18104.html

7.5 集成Spring JDBC及最佳實踐

大多數情況下Spring JDBC都是與IOC容器一起使用。通過配置方式使用Spring JDBC。

而且大部分時間都是使用JdbcTemplate類(或SimpleJdbcTemplate和NamedParameterJdbcTemplate)進行開發,即可能80%時間使用JdbcTemplate類,而只有20%時間使用其他類開發,符合 80/20 法則。

Spring JDBC通過實現DaoSupport來支持一致的數據庫訪問。

Spring JDBC提供如下DaoSupport實現:

  • JdbcDaoSupport 用于支持一致的JdbcTemplate訪問;
  • NamedParameterJdbcDaoSupport: 繼承JdbcDaoSupport,同時提供NamedParameterJdbcTemplate訪問;
  • SimpleJdbcDaoSupport 繼承JdbcDaoSupport,同時提供SimpleJdbcTemplate訪問。

由于JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate類使用DataSourceUtils獲取及釋放連接,而且連接是與線程綁定的,因此這些JDBC模板類是線程安全的,即JdbcTemplate對象可以在多線程中重用。

接下來看一下Spring JDBC框架的最佳實踐:

1) 首先定義Dao 接口

Java代碼
package cn.javass.spring.chapter7.dao;
import cn.javass.spring.chapter7.UserModel;
public interface IUserDao {
    public void save(UserModel model);
    public int countAll();
}

2 )定義Dao 實現,此處是使用Spring JDBC 實現:

Java代碼
package cn.javass.spring.chapter7.dao.jdbc;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
import cn.javass.spring.chapter7.UserModel;
import cn.javass.spring.chapter7.dao.IUserDao;
public class UserJdbcDaoImpl extends SimpleJdbcDaoSupport implements IUserDao {
  private static final String INSERT_SQL = "insert into test(name) values(:myName)";
  private static final String COUNT_ALL_SQL = "select count(*) from test";

  @Override
  public void save(UserModel model) {
      getSimpleJdbcTemplate().update(INSERT_SQL, new BeanPropertySqlParameterSource(model));
  }
  @Override
  public int countAll() {
      return getJdbcTemplate().queryForInt(COUNT_ALL_SQL);
  }
}

此處注意首先Spring JDBC實現放在dao.jdbc包里,如果有hibernate實現就放在dao.hibernate包里;其次實現類命名如UserJdbcDaoImpl,即×××JdbcDaoImpl,當然如果自己有更好的命名規范可以遵循自己的,此處只是提個建議。

3 )進行資源配置(resources/chapter7/applicationContext-resources.xml ):

Java代碼
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
      <list>
          <value>classpath:chapter7/resources.properties</value>
      </list>
    </property>
</bean>

PropertyPlaceholderConfigurer用于替換配置元數據,如本示例中將對bean定義中的${…}占位符資源用“classpath:chapter7/resources.properties”中相應的元素替換。

Java代碼
<bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
    <property name="targetDataSource">
      <bean class="org.logicalcobwebs.proxool.ProxoolDataSource">
          <property name="driver" value="${db.driver.class}" />
          <property name="driverUrl" value="${db.url}" />
          <property name="user" value="${db.username}" />
          <property name="password" value="${db.password}" />
          <property name="maximumConnectionCount"
                 value="${proxool.maxConnCount}" />
          <property name="minimumConnectionCount"
                 value="${proxool.minConnCount}" />
          <property name="statistics" value="${proxool.statistics}" />
          <property name="simultaneousBuildThrottle"
                   value="${proxool.simultaneousBuildThrottle}" />
          <property name="trace" value="${proxool.trace}" />
      </bean>
    </property>
</bean>

dataSource定義數據源,本示例使用proxool數據庫連接池,并使用LazyConnectionDataSourceProxy包裝它,從而延遲獲取數據庫連接;${db.driver.class}將被“classpath:chapter7/resources.properties”中的“db.driver.class”元素屬性值替換。

proxool數據庫連接池:本示例使用proxool-0.9.1版本,請到proxool官網下載并添加proxool-0.9.1.jar和proxool-cglib.jar到類路徑。

ProxoolDataSource屬性含義如下:

  • driver:指定數據庫驅動;
  • driverUrl:數據庫連接;
  • username:用戶名;
  • password:密碼;
  • maximumConnectionCount:連接池最大連接數量;
  • minimumConnectionCount:連接池最小連接數量;
  • statistics:連接池使用樣本狀況統計;如1m,15m,1h,1d表示沒1分鐘、15分鐘、1小時及1天進行一次樣本統計;
  • simultaneousBuildThrottle:一次可以創建連接的最大數量;
  • trace:true表示被執行的每個sql都將被記錄(DEBUG級別時被打印到相應的日志文件);

4 )定義資源文件(classpath:chapter7/resources.properties ):

Java代碼
proxool.maxConnCount=10
proxool.minConnCount=5
proxool.statistics=1m,15m,1h,1d
proxool.simultaneousBuildThrottle=30
proxool.trace=false
db.driver.class=org.hsqldb.jdbcDriver
db.url=jdbc:hsqldb:mem:test
db.username=sa
db.password=

用于替換配置元數據中相應的占位符數據,如${db.driver.class}將被替換為“org.hsqldb.jdbcDriver”。

5 )dao 定義配置(chapter7/applicationContext-jdbc.xml ):

Java代碼
<bean id="abstractDao" abstract="true">
    <property name="dataSource" ref="dataSource"/>
</bean>   
<bean id="userDao"
     class="cn.javass.spring.chapter7.dao.jdbc.UserJdbcDaoImpl"
    parent="abstractDao"/>

首先定義抽象的abstractDao,其有一個dataSource屬性,從而可以讓繼承的子類自動繼承dataSource屬性注入;然后定義userDao,且繼承abstractDao,從而繼承dataSource注入;我們在此給配置文件命名為applicationContext-jdbc.xml表示Spring JDBC DAO實現;如果使用hibernate實現可以給配置文件命名為applicationContext-hibernate.xml。

6)  最后測試一下吧(cn.javass.spring.chapter7. JdbcTemplateTest ):

Java代碼
@Test
public void testBestPractice() {
    String[] configLocations = new String[] {
            "classpath:chapter7/applicationContext-resources.xml",
            "classpath:chapter7/applicationContext-jdbc.xml"};
    ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations);
    IUserDao userDao = ctx.getBean(IUserDao.class);
    UserModel model = new UserModel();
    model.setMyName("test");
    userDao.save(model);
     Assert.assertEquals(1, userDao.countAll());
}

首先讀取配置文件,獲取IUserDao接口實現,然后再調用IUserDao接口方法,進行數據庫操作,這樣對于開發人員使用來說,只面向接口,不關心實現,因此很容易更換實現,比如像更換為hibernate實現非常簡單。

本系列:

 本文由用戶 zjyongning 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!