欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-02-28 17:48:16
简介 spring提供的dao(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术,如jdbc,hibernate或者jdo等。它不仅可以让你方便地在这...

简介

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; 
} 

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

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的支持实例详解,希望对大家有所帮助