`
isiqi
  • 浏览: 16041315 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Spring3开发实战 之 第四章:对JDBC和ORM的支持

 
阅读更多
简介
Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术,如JDBC,Hibernate或者JDO等。它不仅可以让你方便地在这些持久化技术间切换, 而且让你在编码的时候不用考虑处理各种技术中特定的异常。
一致的异常层次
Spring提供了一种方便的方法,把特定于某种技术的异常,如SQLException, 转化为自己的异常,这种异常属于以DataAccessException为根的异常层次。这些异常封装了原始异常对象,这样就不会有丢失任何错误信息的风险。
如果使用拦截器方式,你在应用中 就得自己小心处理HibernateException、 JDOException等,最好是委托给 SessionFactoryUtils的 convertHibernateAccessException、 convertJdoAccessException等方法。这些方法可以把相应的异常转 化为与org.springframework.dao中定义的异常层次相兼容的异常。
一致的DAO支持抽象类
为了便于以一种一致的方式使用各种数据访问技术,如JDBC、JDO和Hibernate, Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,通过它们你可以 获得与你当前使用的数据访问技术相关的数据源和其他配置信息。
1:JdbcDaoSupport- JDBC数据访问对象的基类。 需要一个DataSource,同时为子类提供 JdbcTemplate。
2:HibernateDaoSupport- Hibernate数据访问对象的基类。 需要一个SessionFactory,同时为子类提供 HibernateTemplate。也可以选择直接通过 提供一个HibernateTemplate来初始化。
3:JdoDaoSupport- JDO数据访问对象的基类。 需要设置一个PersistenceManagerFactory, 同时为子类提供JdoTemplate。
4:JpaDaoSupport- JPA数据访问对象的基类。 需要一个EntityManagerFactory,同时 为子类提供JpaTemplate。
简介
Spring JDBC抽象框架所带来的价值将在以下几个方面得以体现:(注:使用了Spring JDBC抽象框架之后,应用开发人员只需要完成斜体加粗字部分的编码工作。)
1:指定数据库连接参数
2:打开数据库连接
3:声明SQL语句
4:预编译并执行SQL语句
5:遍历查询结果(如果需要的话)
6:处理每一次遍历操作
7:处理抛出的任何异常
8:处理事务
9:关闭数据库连接
Spring将替我们完成所有单调乏味的JDBC底层细节处理工作
Spring JDBC抽象框架由四个包构成:core、 dataSource、object以及support
1:core包由JdbcTemplate类以及相关的回调接口和类组成。
2:datasource包由一些用来简化DataSource访问的工具类,以及各种DataSource接口的简单实现(主要用于单元测试以及在J2EE容器之外使用JDBC)组成。
3:object包由封装了查询、更新以及存储过程的类组成,这些类的对象都是线程安全并且可重复使用的。它们类似于JDO,与JDO的不同之处在于查询结果与数据库是“断开连接”的。它们是在core包的基础上对JDBC更高层次的抽象。
4:support包提供了一些SQLException的转换类以及相关的工具类。
在JDBC处理过程中抛出的异常将被转换成org.springframework.dao包中定义的异常。因此使用Spring JDBC进行开发将不需要处理JDBC或者特定的RDBMS才会抛出的异常。所有的异常都是unchecked exception,这样我们就可以对传递到调用者的异常进行有选择的捕获。
JdbcTemplate是core包的核心类。它替我们完成了资源的创建以及释放工作,从而简化了对JDBC的使用。它还可以帮助我们避免一些常见的错误,比如忘记关闭数据库连接。
定义接口如下:

java代码:
  1. publicinterfaceApi{
  2. publicbooleancreate(UserModelum);
  3. }
定义实现类如下:

java代码:
  1. publicclassImplimplementsApi{
  2. privateDataSourceds=null;
  3. publicvoidsetDs(DataSourceds){
  4. this.ds=ds;
  5. }
  6. publicbooleancreate(UserModelum){
  7. JdbcTemplatejt=newJdbcTemplate(ds);
  8. jt.execute("insertintotbl_user(uuid,name)values('"+um.getUuid()+"','"+um.getName()+"')");
  9. returnfalse;
  10. }
  11. }
配置文件

java代码:
  1. <beanname="api"class="cn.javass.Spring3.jdbc.Impl">
  2. <propertyname="ds"ref="dataSource"></property>
  3. </bean>
  4. <beanname="dataSource"class="org.apache.commons.dbcp.BasicDataSource">
  5. <propertyname="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
  6. <propertyname="url"><value>jdbc:oracle:thin:@localhost:1521:orcl</value></property>
  7. <propertyname="username"><value>test</value></property>
  8. <propertyname="password"value="test"/>
  9. </bean>
客户端

java代码:
  1. publicstaticvoidmain(String[]args)throwsException{
  2. ApplicationContextcontext=newClassPathXmlApplicationContext(
  3. newString[]{"applicationContext-jdbc.xml"});
  4. Apiapi=(Api)context.getBean("api");
  5. UserModelum=newUserModel();
  6. um.setUuid("test1");
  7. um.setName("test1");
  8. api.create(um);
  9. }
如果是需要向里面传递参数的,就需要回调接口,如下:

java代码:
  1. publicbooleancreate(UserModelum1){
  2. JdbcTemplatejt=newJdbcTemplate(ds);
  3. finalUserModelum=um1;
  4. classmyCallBackimplementsPreparedStatementCallback{
  5. publicObjectdoInPreparedStatement(PreparedStatementpstmt)
  6. throwsSQLException,DataAccessException{
  7. pstmt.setString(1,um.getUuid());
  8. pstmt.setString(2,um.getName());
  9. System.out.println("dddddddd");
  10. returnpstmt.executeUpdate();
  11. }
  12. }
  13. jt.execute("insertintotbl_user(uuid,name)values(?,?)",newmyCallBack());
  14. returnfalse;
  15. }
NamedParameterJdbcTemplate类在SQL语句中支持使用命名参数,比较适合做查询,如果做更新,同样需要使用回调方法,如下:

java代码:
  1. NamedParameterJdbcTemplatejt=newNamedParameterJdbcTemplate(ds);
  2. MapparamMap=newHashMap();
  3. paramMap.put("uuid",um.getUuid());
  4. Listlist=jt.queryForList("select*fromtbl_userwhereuuid=:uuid",paramMap);
  5. Iteratorit=list.iterator();
  6. while(it.hasNext()){
  7. Mapmap=(Map)it.next();
  8. System.out.println("uuid="+map.get("uuid")+",name="+map.get("name"));
  9. }
NamedParameterJdbcTemplate类是线程安全的,该类的最佳使用方式不是每次操作的时候实例化一个新的NamedParameterJdbcTemplate,而是针对每个DataSource只配置一个NamedParameterJdbcTemplate实例
NamedParameterJdbcTemplate也可以自己做mapper,如下:

java代码:
  1. NamedParameterJdbcTemplatejt=newNamedParameterJdbcTemplate(ds);
  2. MapparamMap=newHashMap();
  3. paramMap.put("uuid",um1.getUuid());
  4. RowMappermapper=newRowMapper(){
  5. publicObjectmapRow(ResultSetrs,introwNum)throwsSQLException{
  6. UserModelum=newUserModel();
  7. um.setName(rs.getString("name"));
  8. um.setUuid(rs.getString("uuid"));
  9. returnum;
  10. }
  11. };
  12. Listlist=jt.query("select*fromtbl_userwhereuuid=:uuid",paramMap,mapper);
  13. Iteratorit=list.iterator();
  14. while(it.hasNext()){
  15. UserModeltempUm=(UserModel)it.next();
  16. System.out.println("uuid="+tempUm.getUuid()+",name="+tempUm.getName());
  17. }
SimpleJdbcTemplate类
SimpleJdbcTemplate类是JdbcTemplate类的一个包装器(wrapper),它利用了Java 5的一些语言特性,比如Varargs和Autoboxing。
SQLExceptionTranslator接口
SQLExceptionTranslator是一个接口,如果你需要在 SQLException和org.springframework.dao.DataAccessException之间作转换,那么必须实现该接口。
转换器类的实现可以采用一般通用的做法(比如使用JDBC的SQLState code),如果为了使转换更准确,也可以进行定制(比如使用Oracle的error code)。
SQLErrorCodeSQLExceptionTranslator是SQLExceptionTranslator的默认实现。 该实现使用指定数据库厂商的error code,比采用SQLState更精确。
DataSourceUtils类
DataSourceUtils是一个帮助类提供易用且强大的数据库访问能力,们可以使用该类提供的静态方法从JNDI获取数据库连接以及在必要的时候关闭之。
尤其在使用标准JDBC,但是又想要使用Spring的事务的时候,最好从DataSourceUtils类来获取JDBC的连接。
SmartDataSource接口
SmartDataSource是DataSource 接口的一个扩展,用来提供数据库连接。使用该接口的类在指定的操作之后可以检查是否需要关闭连接。
AbstractDataSource类
它实现了DataSource接口的 一些无关痛痒的方法,如果你需要实现自己的DataSource,那么继承 该类是个好主意 。
SingleConnectionDataSource类
是SmartDataSource接口 的一个实现,其内部包装了一个单连接。该连接在使用之后将不会关闭,很显然它不能在多线程 的环境下使用
简介
Spring在资源管理,DAO实现支持以及事务策略等方面提供了与 JDO、JPA、Hibernate、TopLink及iBATIS的集成。以Hibernate为例,Spring通过使用许多IoC的便捷特性对它提供了一流的支持,帮助你处理很多典型的Hibernate整合的问题。所有的这些支持,都遵循Spring通用的事务和DAO异常体系。通常来说有两种不同的整合风格:你可以使用Spring提供的DAO模板,或者直接使用Hibernate/JDO/TopLink等工具的原生API编写DAO。无论采取哪种风格,这些DAO都可以通过IoC进行配置,并参与到Spring的资源和事务管理中去。
使用Spring构建你的O/R Mapping DAO的好处包括:
1:测试简单
2:异常封装
3:通用的资源管理
4:综合的事务管理
5:避免绑定特定技术允许mix-and-match的实现策略
在Spring的application context中创建 SessionFactory ,如下:

java代码:
  1. <beanid="hbConfig"
  2. class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  3. <propertyname="dataSource"><reflocal="dataSource"/></property>
  4. <propertyname="mappingResources">
  5. <list>
  6. <value>com/lx/Parent.hbm.xml</value>
  7. </list>
  8. </property>
  9. <propertyname="hibernateProperties">
  10. <props>
  11. <propkey="hibernate.dialect">
  12. org.hibernate.dialect.Oracle9Dialect
  13. </prop>
  14. <propkey="hibernate.show_sql">true</prop>
  15. </props>
  16. </property>
  17. </bean>
定义接口如下:

java代码:
  1. publicinterfaceApi{
  2. publicbooleancreate(UserModelum);
  3. }
实现类如下:

java代码:
  1. publicclassImplimplementsApi{
  2. privateSessionFactorysf=null;
  3. publicvoidsetSf(SessionFactorysf){
  4. this.sf=sf;
  5. }
  6. publicbooleancreate(UserModelum){
  7. HibernateTemplateht=newHibernateTemplate(sf);
  8. ht.save(um);
  9. returnfalse;
  10. }
  11. }
配置文件如下:

java代码:
  1. <beanname="api"class="cn.javass.Spring3.h3.Impl">
  2. <propertyname="sf"ref="hbConfig"></property>
  3. </bean>
  4. <beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource">
  5. <propertyname="driverClassName">
  6. <value>oracle.jdbc.driver.OracleDriver</value>
  7. </property>
  8. <propertyname="url">
  9. <value>jdbc:oracle:thin:@localhost:1521:orcl</value>
  10. </property>
  11. <propertyname="username"><value>test</value></property>
  12. <propertyname="password"value="test"/>
  13. </bean>
配置文件如下:

java代码:
  1. <beanid="hbConfig"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  2. <propertyname="dataSource"><reflocal="dataSource"/></property>
  3. <propertyname="mappingResources">
  4. <list><value>cn/javass/Spring3/h3/UserModel.hbm.xml</value>
  5. </list>
  6. </property>
  7. <propertyname="hibernateProperties">
  8. <props>
  9. <propkey="hibernate.dialect">
  10. org.hibernate.dialect.Oracle8iDialect
  11. </prop>
  12. <propkey="hibernate.show_sql">true</prop>
  13. </props>
  14. </property>
  15. </bean>
客户端文件如下:

java代码:
  1. publicstaticvoidmain(String[]args)throwsException{
  2. ApplicationContextcontext=newClassPathXmlApplicationContext(
  3. newString[]{"applicationContext-h3.xml"});
  4. Apiapi=(Api)context.getBean("api");
  5. UserModelum=newUserModel();
  6. um.setUuid("test1");
  7. um.setName("test1");
  8. api.create(um);
  9. }
前面的演示是更新操作,那么查询怎么做呢?如下:

java代码:
  1. List<UserModel>list=ht.find("selectofromUserModelo");
要传入参数怎么做呢?如下:

java代码:
  1. Objectparams[]=newObject[1];
  2. params[0]="test1";
  3. List<UserModel>list=ht.find("selectofromUserModelowhereo.uuid=?",params);
要传入命名参数怎么做呢?如下:

java代码:
  1. Objectparams[]=newObject[1];
  2. params[0]="test1";
  3. Stringnames[]=newString[1];
  4. names[0]="uuid";
  5. List<UserModel>list=ht.findByNamedParam("selectofromUserModelowhereo.uuid=:uuid",names,params);
如果需要使用Hibernate的Query接口,该怎么做呢?如下:

java代码:
  1. HibernateCallbackhcb=newHibernateCallback(){
  2. publicObjectdoInHibernate(Sessionsession)throwsHibernateException,SQLException{
  3. Queryq=session.createQuery("selectofromUserModelowhereo.uuid=:uuid");
  4. q.setString("uuid",um.getUuid());
  5. returnq.list();
  6. }
  7. };
  8. Collection<UserModel>list=(Collection<UserModel>)ht.execute(hcb);
一个回调实现能够有效地在任何Hibernate数据访问中使用。HibernateTemplate 会确保当前Hibernate的 Session 对象的正确打开和关闭,并直接参与到事务管理中去。 Template实例不仅是线程安全的,同时它也是可重用的。因而他们可以作为外部对象的实例变量而被持有。
实现类改成如下:

java代码:
  1. publicclassImplextendsHibernateDaoSupportimplementsApi{
  2. publicCollectiontestQuery(){
  3. List<UserModel>list=this.getHibernateTemplate().find("selectofromUserModelo");
  4. for(UserModeltempUm:list){
  5. System.out.println("uuid=="+tempUm.getUuid()+",name="+tempUm.getName());
  6. }
  7. returnlist;
  8. }
  9. }
配置文件改成如下:

java代码:
  1. <beanname="api"class="cn.javass.Spring3.h3.Impl">
  2. <propertyname="sessionFactory"ref="hbConfig"></property>
  3. </bean>
要想使用Session怎么办?如下:

java代码:
  1. Sessionsession=getSession(getSessionFactory(),false);
通常将一个false作为参数(表示是否允许创建)传递到 getSession(..) 方法中进行调用。 此时,整个调用将在同一个事务内完成(它的整个生命周期由事务控制,避免了关闭返回的 Session 的需要)。
视频配套PPT,视频地址【Spring3开发实战-独家视频课程
分享到:
评论

相关推荐

    Spring+3.x企业应用开发实战光盘源码(全)

     第4章:讲解如何在Spring配置文件中使用Spring 3.0的Schema格式配置Bean的内容,并对各个配置项的意义进行了深入的说明。  第5章:对Spring容器进行解构,从内部探究Spring容器的体系结构和运行流程。此外,我们...

    陈开雄 Spring+3.x企业应用开发实战光盘源码.zip

     第4章:讲解如何在Spring配置文件中使用Spring 3.0的Schema格式配置Bean的内容,并对各个配置项的意义进行了深入的说明。  第5章:对Spring容器进行解构,从内部探究Spring容器的体系结构和运行流程。此外,我们...

    Spring.3.x企业应用开发实战(完整版).part2

     《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...

    Spring3.x企业应用开发实战(完整版) part1

     《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    第4章 利用JDBC和JTA访问 数据库和管理全局事务 178 4.1 JDBC和容器管理的数据源 179 4.1.1 JDBC概述 179 4.1.2 使用JDBC执行数据库访问 180 4.1.3 使用WebLogic服务器管理的 数据源 182 4.1.4 使用JBoss服务器管理...

    springmybatis

    mybatis实战教程mybatis in action之五与spring3集成附源码 mybatis实战教程mybatis in action之六与Spring MVC 的集成 mybatis实战教程mybatis in action之七实现mybatis分页源码下载 mybatis实战教程mybatis in ...

    Java Web程序设计教程

    第4章sql与jdbc 64 4.1sql 64 4.1.1sql概述 64 4.1.2ddl与dml简介 64 4.1.3sql使用方法 65 4.2jdbc 67 4.2.1jdbc概述 67 4.2.2jdbc驱动程序 68 4.2.3使用jdbc读取数据 69 4.3项目实战——存储图书信息 73 ...

    单点登录源码

    服务网关,对外暴露统一规范的接口和包装响应结果,包括各个子系统的交互接口、对外开放接口、开发加密接口、接口文档等服务,可在该模块支持验签、鉴权、路由、限流、监控、容错、日志等功能。示例图: ![API网关]...

    ShardingSphere:SpringBoot2+MybatisPlus读写分离+分表

    它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。他们均提供标准化的数据分片、读写分离、柔性事务和数据治理功能,可适用于如Java同构...

Global site tag (gtag.js) - Google Analytics