spring对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代码:

public interface Api {
public boolean create(UserModel um);
} 

定义实现类如下:

java代码:

public class Impl implements Api{
private DataSource ds = null;
public void setDs(DataSource ds){
this.ds = ds;
}
public boolean create(UserModel um) {
JdbcTemplate jt = new JdbcTemplate(ds);
jt.execute("insert into tbl_user (uuid,name) values('"+um.getUuid()+"','"+um.getName()+"')");
return false;
}
} 

配置文件

java代码:

<bean name="api" class="com.bjpowernode.Spring3.jdbc.Impl">
<property name="ds" ref="dataSource"></property>
</bean>
<bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:@localhost:1521:orcl</value></property>
<property name="username"> <value>test</value> </property>
<property name="password" value="test"/>
</bean> 

客户端

java代码:

public static void main(String[] args)throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext(
  new String[] {"applicationContext-jdbc.xml"});
Api api = (Api)context.getBean("api");
UserModel um = new UserModel();
um.setUuid("test1");
um.setName("test1");
api.create(um);
} 

如果是需要向里面传递参数的,就需要回调接口,如下:

java代码:

public boolean create(UserModel um1){
JdbcTemplate jt = new JdbcTemplate(ds);
final UserModel um = um1;
class myCallBack implements PreparedStatementCallback{
public Object doInPreparedStatement(PreparedStatement pstmt)
throws SQLException, DataAccessException {
pstmt.setString(1,um.getUuid());
pstmt.setString(2,um.getName());
System.out.println("dddddddd");
return pstmt.executeUpdate();
}
}
jt.execute("insert into tbl_user (uuid,name) values(?,?)",new myCallBack());
return false;
} 

NamedParameterJdbcTemplate类在SQL语句中支持使用命名参数,比较适合做查询,如果做更新,同样需要使用回调方法,如下:

java代码:

NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(ds);
Map paramMap = new HashMap();
paramMap.put("uuid",um.getUuid());
List list = jt.queryForList("select * from tbl_user where uuid=:uuid",paramMap);
Iterator it = list.iterator();
while(it.hasNext()){
Map map = (Map)it.next();
System.out.println("uuid="+map.get("uuid")+",name="+map.get("name"));
} 

NamedParameterJdbcTemplate类是线程安全的,该类的最佳使用方式不是每次操作的时候实例化一个新的

NamedParameterJdbcTemplate,而是针对每个DataSource只配置一个NamedParameterJdbcTemplate实例

NamedParameterJdbcTemplate也可以自己做mapper,如下:

java代码:

NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(ds);
Map paramMap = new HashMap();
paramMap.put("uuid",um1.getUuid());
RowMapper mapper = new RowMapper() {
  public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
   UserModel um = new UserModel();
   um.setName(rs.getString("name"));
   um.setUuid(rs.getString("uuid"));
   return um;
  }
 };
List list = jt.query("select * from tbl_user where uuid=:uuid",paramMap,mapper);
Iterator it = list.iterator();
while(it.hasNext()){
UserModel tempUm = (UserModel)it.next();
System.out.println("uuid="+tempUm.getUuid()+",name="+tempUm.getName());
} 

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代码:

<bean id="hbConfig"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<value>com/lx/Parent.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle9Dialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean> 

定义接口如下:

java代码:

public interface Api {
public boolean create(UserModel um);
} 

实现类如下:

java代码:

public class Impl implements Api{
private SessionFactory sf = null;
public void setSf(SessionFactory sf){
this.sf = sf;
}
public boolean create(UserModel um){
HibernateTemplate ht = new HibernateTemplate(sf);
ht.save(um);
return false;
}
} 

配置文件如下:

java代码:

<bean name="api" class="com.bjpowernode.Spring3.h3.Impl">
<property name="sf" ref="hbConfig"></property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@localhost:1521:orcl</value>
</property>
<property name="username"> <value>test</value> </property>
<property name="password" value="test"/>
</bean> 

配置文件如下:

java代码:

<bean id="hbConfig" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list> <value>cn/bjpowernode/Spring3/h3/UserModel.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle8iDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>

客户端文件如下:

java代码:

public static void main(String[] args)throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext(
  new String[] {"applicationContext-h3.xml"});
Api api = (Api)context.getBean("api");
UserModel um = new UserModel();
um.setUuid("test1");
um.setName("test1");
api.create(um);
} 

前面的演示是更新操作,那么查询怎么做呢?如下:

java代码:

List<UserModel> list = ht.find("select o from UserModel o"); 

要传入参数怎么做呢?如下:

java代码:

Object params[] = new Object[1];
params[0] = "test1";
List<UserModel> list = ht.find("select o from UserModel o where o.uuid=?",params); 

要传入命名参数怎么做呢?如下:

java代码:

Object params[] = new Object[1];
params[0] = "test1";
String names[] = new String[1];
names[0] = "uuid";
List<UserModel> list = ht.findByNamedParam("select o from UserModel o where o.uuid=:uuid",names,params); 

如果需要使用Hibernate的Query接口,该怎么做呢?如下:

java代码:

HibernateCallback hcb =new HibernateCallback(){
public Object doInHibernate(Session session)throws HibernateException, SQLException {
Query q = session.createQuery("select o from UserModel o where o.uuid=:uuid");
q.setString("uuid", um.getUuid());
return q.list();
}
};
Collection<UserModel> list = (Collection<UserModel>)ht.execute(hcb); 

一个回调实现能够有效地在任何Hibernate数据访问中使用。HibernateTemplate 会确保当前Hibernate的 Session 对象的正确打开和关闭,并直接参与到事务管理中去。 Template实例不仅是线程安全的,同时它也是可重用的。因而他们可以作为外部对象的实例变量而被持有。
实现类改成如下:

java代码:

public class Impl extends HibernateDaoSupport implements Api{
public Collection testQuery(){
List<UserModel> list = this.getHibernateTemplate().find("select o from UserModel o");
for(UserModel tempUm : list){
System.out.println("uuid=="+tempUm.getUuid()+",name="+tempUm.getName());
}
return list;
}
} 

配置文件改成如下:

java代码:

<bean name="api" class="com.bjpowernode.Spring3.h3.Impl">
<property name="sessionFactory" ref="hbConfig"></property>
</bean> 

要想使用Session怎么办?如下:

java代码:

Session session = getSession(getSessionFactory(), false); 

通常将一个false作为参数(表示是否允许创建)传递到 getSession(..) 方法中进行调用。 此时,整个调用将在同一个事务内完成(它的整个生命周期由事务控制,避免了关闭返回的 Session 的需要)。

总结

以上所述是小编给大家介绍的spring对JDBC和orm的支持实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • JDBC常用接口总结

    本文主要向大家介绍JDBC常用的接口都有哪些,下面来看看具体内容. 1.Driver接口 对于每一个数据库驱动程序都必须实现Driver接口,在编写程序时,当需要连接数据库的时候就需要装载由数据库厂商提供的数据库驱动程序,装载的方式如下: Class.forname("jdbc.driver_class_name"); 同时要注意的就是在使用Class.forname时首先需要引入java.sql包.下面这段代码就是装载SQL Server数据库驱动程序的一段代码: import ja

  • java使用JDBC动态创建数据表及SQL预处理的方法

    本文实例讲述了java使用JDBC动态创建数据表及SQL预处理的方法.分享给大家供大家参考,具体如下: 这两天由于公司的需求,客户需要自定义数据表的字段,导致每张表的字段都不是固定的而且很难有一个通用的模板去维护,所以就使用JDBC动态去创建数据表,然后通过表的字段动态添加数据,数据的来源主要是用户提供的Excel直接导入到数据库中. 如果考虑到字段的类型,可以通过反射的机制去获取,现在主要用户需求就是将数据导入到数据库提供查询功能,不能修改,所以就直接都使用String类型来处理数据更加便捷.

  • BaseJDBC和CRUDDAO的写法实例代码

    我们首先看下BASEJDBC的写法实例: package com.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import com.mysql.jdbc.Driver; public class BaseJDBC { // 表示你要操作的是哪种类型

  • JDBC中resutset接口操作实例详解

    本文主要向大家展示JDBC接口中resutset接口的用法实例,下面我们看看具体内容. 1. ResultSet细节1 功能:封锁结果集数据 操作:如何获得(取出)结果 package com.sjx.a; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import org.junit.Test; //1. next方

  • Java使用JDBC实现Oracle用户认证的方法详解

    本文实例讲述了Java使用JDBC实现Oracle用户认证的方法.分享给大家供大家参考,具体如下: 两天时间写的小品,以前的J2EE环境基本使用框架.现在使用JDBC配合Oracle存储过程模拟了一下用户注册和用户认证. 一.添加必须的jar包 需要JDBC连接Oracle的包和shiro-core依赖,添加shiro-core主要为了方便使用SHA-256散列算法. 二.编写JDBC连接 import java.sql.Connection; import java.sql.DriverMan

  • spring对JDBC和orm的支持实例详解

    简介 Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术,如JDBC,Hibernate或者JDO等.它不仅可以让你方便地在这些持久化技术间切换, 而且让你在编码的时候不用考虑处理各种技术中特定的异常. 一致的异常层次 Spring提供了一种方便的方法,把特定于某种技术的异常,如SQLException, 转化为自己的异常,这种异常属于以 DataAccessException 为根的异常层次.这些异常封装了原始异常对象,这样就不会有丢失任何错误信息的

  • Spring + Mybatis 项目实现动态切换数据源实例详解

    项目背景:项目开发中数据库使用了读写分离,所有查询语句走从库,除此之外走主库. 最简单的办法其实就是建两个包,把之前数据源那一套配置copy一份,指向另外的包,但是这样扩展很有限,所有采用下面的办法. 参考了两篇文章如下: http://www.jb51.net/article/111840.htm http://www.jb51.net/article/111842.htm 这两篇文章都对原理进行了分析,下面只写自己的实现过程其他不再叙述. 实现思路是: 第一步,实现动态切换数据源:配置两个D

  • Spring 整合 Hibernate 时启用二级缓存实例详解

    Spring 整合 Hibernate 时启用二级缓存实例详解 写在前面: 1. 本例使用 Hibernate3 + Spring3: 2. 本例的查询使用了 HibernateTemplate: 1. 导入 ehcache-x.x.x.jar 包: 2. 在 applicationContext.xml 文件中找到 sessionFactory 相应的配置信息并在设置 hibernateProperties 中添加如下代码: <!-- 配置使用查询缓存 --> <prop key=&q

  • Spring AOP切面解决数据库读写分离实例详解

    Spring AOP切面解决数据库读写分离实例详解 为了减轻数据库的压力,一般会使用数据库主从(master/slave)的方式,但是这种方式会给应用程序带来一定的麻烦,比如说,应用程序如何做到把数据写到master库,而读取数据的时候,从slave库读取.如果应用程序判断失误,把数据写入到slave库,会给系统造成致命的打击. 解决读写分离的方案很多,常用的有SQL解析.动态设置数据源.SQL解析主要是通过分析sql语句是insert/select/update/delete中的哪一种,从而对

  • spring boot 图片上传与显示功能实例详解

    首先描述一下问题,spring boot 使用的是内嵌的tomcat, 所以不清楚文件上传到哪里去了, 而且spring boot 把静态的文件全部在启动的时候都会加载到classpath的目录下的,所以上传的文件不知相对于应用目录在哪,也不知怎么写访问路径合适,对于新手的自己真的一头雾水. 后面想起了官方的例子,没想到一开始被自己找到的官方例子,后面太依赖百度谷歌了,结果发现只有官方的例子能帮上忙,而且帮上大忙,直接上密码的代码 package hello; import static org

  • Spring Boot的listener(监听器)简单使用实例详解

    监听器(Listener)的注册方法和 Servlet 一样,有两种方式:代码注册或者注解注册 1.代码注册方式 通过代码方式注入过滤器 @Bean public ServletListenerRegistrationBean servletListenerRegistrationBean(){ ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean

  • Java中JDBC实现动态查询的实例详解

    一 概述 1.什么是动态查询? 从多个查询条件中随机选择若干个组合成一个DQL语句进行查询,这一过程叫做动态查询. 2.动态查询的难点 可供选择的查询条件多,组合情况多,难以一一列举. 3.最终查询语句的构成 一旦用户向查询条件中输入数据,该查询条件就成为最终条件的一部分. 二 基本原理 1.SQL基本框架 无论查询条件如何,查询字段与数据库是固定不变的,这些固定不变的内容构成SQL语句的基本框架,如 select column... from table. 2.StringBuilder形成D

  • Spring boot进行参数校验的方法实例详解

    Spring boot开发web项目有时候我们需要对controller层传过来的参数进行一些基本的校验,比如非空.整数值的范围.字符串的长度.日期.邮箱等等.Spring支持JSR-303 Bean Validation API,可以方便的进行校验. 使用注解进行校验 先定义一个form的封装对象 class RequestForm { @Size(min = 1, max = 5) private String name; public String getName() { return n

  • Spring IOC和aop的原理及实例详解

    这篇文章主要介绍了Spring IOC和aop的原理及实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架.特点是面向接口编程,松耦合. 1:IOC(控制反转) 别名(DI:依赖注入) 首先来一段ioc的实现原来代码: public class ClassPathXmlApplicationContext implements BeanFactory { privat

随机推荐