简介
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
2
3
|
public interface Api {
public boolean create(UserModel um);
}
|
定义实现类如下:
java代码:
1
2
3
4
5
6
7
8
9
10
11
|
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代码:
1
2
3
4
5
6
7
8
9
|
<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代码:
1
2
3
4
5
6
7
8
9
|
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代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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代码:
1
2
3
4
5
6
7
8
9
|
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代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<bean id= "hbConfig"
<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代码:
1
2
3
|
public interface Api {
public boolean create(UserModel um);
}
|
实现类如下:
java代码:
1
2
3
4
5
6
7
8
9
10
11
|
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代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<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代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<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代码:
1
2
3
4
5
6
7
8
9
|
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代码:
1
|
List<UserModel> list = ht.find( "select o from UserModel o" );
|
要传入参数怎么做呢?如下:
java代码:
1
2
3
|
Object params[] = new Object[ 1 ];
params[ 0 ] = "test1" ;
List<UserModel> list = ht.find( "select o from UserModel o where o.uuid=?" ,params);
|
要传入命名参数怎么做呢?如下:
java代码:
1
2
3
4
5
|
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代码:
1
2
3
4
5
6
7
8
|
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代码:
1
2
3
4
5
6
7
8
9
|
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代码:
1
2
3
|
<bean name= "api" class = "com.bjpowernode.Spring3.h3.Impl" >
<property name= "sessionFactory" ref= "hbConfig" ></property>
</bean>
|
要想使用Session怎么办?如下:
java代码:
1
|
Session session = getSession(getSessionFactory(), false );
|
通常将一个false作为参数(表示是否允许创建)传递到 getSession(..) 方法中进行调用。 此时,整个调用将在同一个事务内完成(它的整个生命周期由事务控制,避免了关闭返回的 Session 的需要)。
总结
以上所述是小编给大家介绍的spring对JDBC和orm的支持实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:http://blog.sina.com.cn/s/blog_9c6852670102wvy5.html