tbwshc

主题: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包的核心类。它替我们完成了资源的创建以及释放工作,tb从而简化了对JDBC的使用。它还可以帮助我们避免一些常见的错误,比如忘记关闭数据库连接。
定义接口如下:

java代码:
  1. public interface Api {  
  2. public boolean create(UserModel um);     
  3. }  
定义实现类如下:

java代码:
  1. public class Impl implements Api{  
  2. private DataSource ds = null;  
  3. public void setDs(DataSource ds){  
  4. this.ds = ds;  
  5. }  
  6. public boolean create(UserModel um) {  
  7. JdbcTemplate jt = new JdbcTemplate(ds);  
  8. jt.execute("insert into tbl_user (uuid,name) values('"+um.getUuid()+"','"+um.getName()+"')");  
  9. return false;  
  10. }  
  11. }  
配置文件

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

java代码:
  1. public static void main(String[] args)throws Exception {  
  2. ApplicationContext context = new ClassPathXmlApplicationContext(  
  3.         new String[] {"applicationContext-jdbc.xml"});  
  4. Api api = (Api)context.getBean("api");  
  5. UserModel um = new UserModel();  
  6. um.setUuid("test1");  
  7. um.setName("test1");  
  8. api.create(um);  
  9. }  
如果是需要向里面传递参数的,就需要回调接口,如下:

java代码:
  1. public boolean create(UserModel um1){  
  2. JdbcTemplate jt = new JdbcTemplate(ds);  
  3. final UserModel um = um1;  
  4. class myCallBack implements PreparedStatementCallback{  
  5. public Object doInPreparedStatement(PreparedStatement pstmt)  
  6. throws SQLException, DataAccessException {  
  7. pstmt.setString(1,um.getUuid());  
  8. pstmt.setString(2,um.getName());  
  9. System.out.println("dddddddd");  
  10. return pstmt.executeUpdate();  
  11. }  
  12. }  
  13. jt.execute("insert into tbl_user (uuid,name) values(?,?)",new myCallBack());  
  14. return false;  
  15. }  
 
NamedParameterJdbcTemplate类在SQL语句中支持使用命名参数,比较适合做查询,如果做更新,同样需要使用回调方法,如下:

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

posted on 2012-08-06 13:41 chen11-1 阅读(1228) 评论(0)  编辑  收藏