`
jinnianshilongnian
  • 浏览: 21432037 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2404633
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2997324
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5631174
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257473
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1593044
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248922
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5847149
Group-logo
跟我学Nginx+Lua开...
浏览量:697994
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:780320
社区版块
存档分类
最新评论

【第七章】 对JDBC的支持 之 7.5 集成Spring JDBC及最佳实践 ——跟我学spring3

阅读更多

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

 

原创内容,转载请注明出处【http://sishuok.com/forum/blogPost/list/0/2493.html

21
2
分享到:
评论
21 楼 Persistence_ 2017-11-25  
properties配置文件中配置信息千万不要有空格
20 楼 newboy2004 2015-11-22  
17楼说的对 要不改成你这样 要不改成?占位符这样
19 楼 piaomiaowc1 2013-07-10  
我知道了,每个属性前都要加: values(:loginName,:username,:password,:description)";
这样就OK了,哈哈,这个号博客!感谢啊,学习spring,此博客足以,别的都是浮云!!
18 楼 piaomiaowc1 2013-07-10  
private static final String INSERT_SQL = "insert into user1(login_name,username,password,description) values(:loginName,username,password,description)";


test 类里:
ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocations);
IUserDao userDao = ctx.getBean(IUserDao.class);
User model = new User();
model.setId("10");
model.setLoginName("wohahha");
model.setUsername("hahaha");
model.setPassword("1234");
model.setDescription("yonghu");
userDao.save(model);
Assert.assertEquals(2, userDao.countAll()); 

结果怎么是:
1  wohahha  null null null null
2  wohahha  null null  null null
我这样错在哪里?请大侠 指正,谢谢!!
17 楼 neil.zhi 2013-02-23  
  @Override 
  public void save(UserModel model) { 
      getSimpleJdbcTemplate().update(INSERT_SQL, new BeanPropertySqlParameterSource(model)); 
  }

是不是应该写成
  @Override 
  public void save(UserModel model) { 
      getSimpleJdbcTemplate().getNamedParameterJdbcOperations().update(INSERT_SQL, new BeanPropertySqlParameterSource(model)); 
  }
16 楼 jinnianshilongnian 2013-01-14  
at1943 写道
springjdbc不知怎么处理枚举呐?

这个需要自己单独处理/或者考虑覆盖/实现如BeanPropertySqlParameterSource实现自己的策略
15 楼 at1943 2013-01-13  
springjdbc不知怎么处理枚举呐?
14 楼 jinnianshilongnian 2012-11-07  
Navee 写道
我觉得这个最佳实践如果加上findById,findAll这两个返回数据对象实例的方法就比较好了。
最近研究spring jdbctemplate,发现findById这样返回实例的方法里面用的都是匿名内部RowMap实现类,感觉这样比较麻烦,如果为每个持久化对象单独写一个RowMap实现类,感觉也比较麻烦,不知道实际开发的时候会如何处理,请楼主赐教

spring jdbc仅仅做了点简单封装, 对于每一个Model都需要RowMapper 
13 楼 Navee 2012-11-07  
我觉得这个最佳实践如果加上findById,findAll这两个返回数据对象实例的方法就比较好了。
最近研究spring jdbctemplate,发现findById这样返回实例的方法里面用的都是匿名内部RowMap实现类,感觉这样比较麻烦,如果为每个持久化对象单独写一个RowMap实现类,感觉也比较麻烦,不知道实际开发的时候会如何处理,请楼主赐教
12 楼 jinnianshilongnian 2012-09-27  
leo117 写道
    IUserDao userDao = ctx.getBean(IUserDao.class);  
这一句有点糊涂,在元数据中并没有定义这个IUserDao,只有该接口的一个实现的bean实例。getBean这么智能?如果有多个可以get到的Bean怎么办?


元数据中必须定义

这个是根据类型找,如果有多个 会报不唯一错误 可以通过primary指定冲突时选择的那一个
11 楼 leo117 2012-09-27  
    IUserDao userDao = ctx.getBean(IUserDao.class);  
这一句有点糊涂,在元数据中并没有定义这个IUserDao,只有该接口的一个实现的bean实例。getBean这么智能?如果有多个可以get到的Bean怎么办?
10 楼 jinnianshilongnian 2012-09-08  
一日一博 写道
希望能加上SpringJdbc声明式事务的管理配置。。。。

这个在事务那一章有
9 楼 一日一博 2012-09-07  
希望能加上SpringJdbc声明式事务的管理配置。。。。
8 楼 xlbaby0402 2012-08-25  
simpleJdbcTemplate已经被Deprecated了。
7 楼 b_l_east 2012-05-22  
jinnianshilongnian 写道
b_l_east 写道
请问一下楼主,在继承Support类后,如何通过注释的方式注入DataSource。

貌似继承之后只能使用XML配置的方式了,能否有什么好的方法呢?!


添加一个自定义的注入方法,让其转发给super的setDataSource

@Autowired
public void setDs(ds) {
   super.setDataSource(ds);
}


如此。。。也好。
6 楼 jinnianshilongnian 2012-05-21  
b_l_east 写道
请问一下楼主,在继承Support类后,如何通过注释的方式注入DataSource。

貌似继承之后只能使用XML配置的方式了,能否有什么好的方法呢?!


添加一个自定义的注入方法,让其转发给super的setDataSource

@Autowired
public void setDs(ds) {
   super.setDataSource(ds);
}
5 楼 b_l_east 2012-05-21  
请问一下楼主,在继承Support类后,如何通过注释的方式注入DataSource。

貌似继承之后只能使用XML配置的方式了,能否有什么好的方法呢?!
4 楼 jinnianshilongnian 2012-03-10  
downpour 写道
挺想看到一些使用感悟的,包括怎么写代码能够提高程序的可读性和可扩展性。

加油!


嗯,我会加油的! 感谢大哥的支持。
3 楼 downpour 2012-03-09  
挺想看到一些使用感悟的,包括怎么写代码能够提高程序的可读性和可扩展性。

加油!
2 楼 jinnianshilongnian 2012-03-09  
downpour 写道
最佳实践在哪里?

只是简要的写了简要的步骤 比如提取 abstractDao

写的不好,希望大哥见谅。很怀念《忘记李刚》,小弟也是看你的文章学过来的 

相关推荐

    跟我学spring3(1-7)

    【第一章】 Spring概述 ——跟我学Spring3 【第二章】 IoC 之 2.1 IoC基础 ——跟我学Spring3 【第二章】 IoC 之 2.2 IoC 容器基本原理...【第七章】 对JDBC的支持 之 7.5 集成Spring JDBC及最佳实践 ——跟我学spring3

    跟我学Spring3(7.5)对JDBC的支持之集成Spr

    跟我学Spring3(7.5)对JDBC的支持之集成SpringJDBC及最佳实践Java开发Java经验技巧共5页.pdf.zip

    跟开涛学Spring

    1.34 【第七章】 对JDBC的支持 之 7.5 集成Spring JDBC及最佳实践 ——跟我学spring3 . . . . . . . . .344 1.35 【第八章】 对ORM的支持 之 8.1 概述 ——跟我学spring3 . . . . . . . . . . . . . . . . . . . . ...

    跟我学spring3(8-13).pdf

    spring3基础知识 IoC DI Spring表达式 SpEL Spring JDBC支持 Spring ORM集成 Spring与其他web框架集成 Spring注解零配置 Spring单元测试与集成测试

    跟我学spring3 .pdf

    详细讲解了 IOC DI AOP JDBC MVC 等等spring知识,有很高的学习价值

    跟我学Java_Web源代码

    《跟我学Java Web》内容包括搭建Web开发环境、HTML相关技术基础知识、JavaScript相关技术基础知识、JSP技术基础知识、Servlet技术基础知识、搭建MySQL数据库开发环境、JDBC技术、JavaBean技术基础知识、Ajax技术基础...

    跟我学javaweb全套ppt

    《跟我学Java Web》内容包括搭建Web开发环境、HTML相关技术基础知识、JavaScript相关技术基础知识、JSP技术基础知识、Servlet技术基础知识、搭建MySQL数据库开发环境、JDBC技术、JavaBean技术基础知识、Ajax技术基础...

    Struts2+Spring3+Hibernate3 用户管理系统实例源码

    本例主要是实现了struts2+spring3+hibernate3的 基本框架搭建的注册登录,以及用户增删改查,适于初学者学习。 包括:注册 登录功能 分页的实现 前端校验 验证码的实现 注册时有ajax 校验,登录时 后台从数据库...

    单点登录源码

    Spring+SpringMVC+Mybatis框架集成公共模块,包括公共配置、MybatisGenerator扩展插件、通用BaseService、工具类等。 &gt; zheng-admin 基于bootstrap实现的响应式Material Design风格的通用后台管理系统,`zheng`...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    我们掌握了数据库及其应用技术、数据库原理、计算机网络技术等课程,对数据库的设计、应用、维护及局域网的组成有了深刻的认识与一定的动手实践能力,考取了信息处理、程序设计、数据库技术等国家IT认证。...

    xmljava系统源码-shiro:shirow3school+自编教程

    文档尽量原文抄录,类名、包名未做任何修改,资源文件加上了代表章节的目录,如第三章的资源文件放在resources/ch3下; 为了方便读者拷贝源码,文中源码片段可能增加import语句; 为了显示语法高亮,文中源码片段...

    JAVA自学之路

    这里只是讲了路线图,关于路线中的各个阶段,学到什么程度,如何学习等,可以参考后面的JAVA自学之路 七:《路线图明细》。 首先要学JavaSE,这是无庸置疑的。 与此同时,是的,与此同时,和JavaSE的学习同步,...

    nacos-server-1.2.0.zip

    压缩包提供了已经修改好的启动文件 startup.cmd, 并支持启动时可附带ip和端口的设置, 支持跨网段集群 下载学习的同学可以对照一下改动位置 linux环境对应修改startup.sh文件, 这个包本身是windows版, 所以我...

Global site tag (gtag.js) - Google Analytics