• 开涛spring3(7.5)


    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接口

        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实现:

        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):

    <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”中相应的元素替换。

    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):

    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):

        <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):

        @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实现非常简单。

     

  • 相关阅读:
    Android Studio的project中两个build.gradle配置的区别
    build script和all projects作用和区别
    让overflow:auto页面滚动条出现时不跳动
    GreenDao设置数据版本
    Greendao 缓存问题
    js中文编码到C#后台解码
    content-type: application/json没有设置导致的500错误
    Android的Device File Explorer刷新文件
    adb server version (31) doesn't match this client (40); killing...
    Sqlserver远程过程调用失败
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4315361.html
Copyright © 2020-2023  润新知