Spring整合JDBC及事务处理

 1.Spring整合JDBC

  DAO是数据访问对象(data access object)的简写。接口是实现松耦合的关键,Spring也鼓励使用接口,但不是强制的。

 

  捕获异常时希望能尝试从异常状态中恢复,JDBCSQLException是编译时异常,捕获了之后大部分情况下我们也是无能为力,无法恢复。

  Spring的异常体系提供的异常是运行时异常,不要求强制捕获并处理。使用Spring模板时我们甚至可以不用去关心这些异常,手动地捕获也是可以的。

      

       Spring中支持的模板类型如下:

   

  

  SpringJDBC提供了3个模板类:

  

  从Spring 3.1开始,JdbcTemplate和NamedParameterJdbcTemplate提供了SimpleJdbcTemplate的功能。SimpleJdbcTemplate被标注为过时,使用JdbcTemplate和NamedParameterJdbcTemplate即可。

  Spring 3.1之前的可以使用的是SimpleJdbcTemplate,支持泛型和可变长度参数JdbcTemplate将会去捕获并抛出可能出现的Spring数据库操作异常,代码中不需要关心。

  //这里用的不是占位符,要注意

  String sql2 = "select id,tname,tpwd from tadd where tname = :tname";

  RowMapper<UserBean> rw = new RowMapper<UserBean>(){

  @Override

    public UserBean mapRow(ResultSet paramResultSet, int paramInt)

     throws SQLException {

      UserBean ub = new UserBean();        

                  ub.setId(paramResultSet.getObject("id") + "");

      ub.setName(paramResultSet.getObject("tname") + "");

      ub.setPassword(paramResultSet.getObject("tpwd") + "");

      return ub;

    }    

  };

  Map<String, String> map = new HashMap<String, String>();

  map.put("tname", "p");

    UserBean ub = jdbctemplate.queryForObject(sql2, map, rw);    //UserBean ub = jdbctemplate.queryForObject(sql2, map, new BeanPropertyRowMapper(UserBean.class)); 

    System.out.println(ub.getName() + "," + ub.getPassword());

 

   queryForObject只返回一条记录,如果是多条记录应该用query方法。queryForString(String sql,String.class)将返回字符串型的结果。如果没有对应的javabean,可以用queryForMap和queryForList方法。queryForMap返回一条记录,queryForList返回多条记录。

   

     如果希望能够取得插入记录的主键值,可以调用回调函数,也可以在回调函数中对connection做更多的处理。

static Integer id=0;

public static int getId(final Person person) {
    JdbcTemplate jdbcTemplate=new JdbcTemplate(JDBCUtils.getDataSource());
        
    jdbcTemplate.execute(new ConnectionCallback(){
    //传递的参数为Connection conn,自己可以在conn内写希望完成的功能
   public Object doInConnection(Connection conn) throws SQLException,DataAccessException{
              String sql="insert into person(name) values (?)";
              PreparedStatement ps=conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);//返回所插入数据的主键
              for(int i=0;i<10;i++){
                   ps.setString(1, person.getName());
                   ps.addBatch();     //批处理,将SQL语句进行打包
           }
              //ps.executeUpdate();
             ps.executeBatch();    //没有这一行是不会插入数据的
             ResultSet rs=ps.getGeneratedKeys();
             while(rs.next())
                       id=rs.getInt(1);
              return id;
          }    
    });
    return id;     
 }

 

  Hibernateibatis等持久层框架可以提供比JDBC更为强大的特性,如下所列:

   

       

 2.事务的定义及处理

  

  

  

  

        上图是Spring所支持的事务传播行为所支持的规则。

  事务的隔离级别如下图所示:

      

       不是所有的数据库都完整的支持上面所列的隔离级别,数据库不支持时即使进行了设置也不会起作用。

  

  

  

       tx:method  name =*将匹配除了save*之外的其他方法。

  使用Druid数据库连接池。

       先在配置文件引入tx命名空间,再引入TranstactionManager的bean,还需要打开如下开关:

  <tx:annotation-driven transaction-manager = "txManager">  

     

     在数据库操作bean上加上@Transactional注解开启事务,方法中的多条语句将在一个事务中完成,否则每条语句在一个事务中完成。

     @Transactional

     public class PersonServiceBean implements PersonService

 

     运行期例外(unckecked exception),事务的操作将被回滚。预知的例外(checked  exception),事务的操作将不会回滚。

     可以在方法上加上@Transactional注解来改变上述的默认行为

     @Transactional(rollbackFor = Exception.class)

     public void delete(Integer id) throws Exception{

 

    }

    希望运行期例外不进行事务回滚,加上的是

   @Transactional(noRollbackFor = RuntimeException.class)

   public void delete(Integer id) {

     int i = 3/0;

   }

 

    如果一些操作不需要开启事务,例如查询操作,可以向下面这样操作:

    @Transactional(propagation = Propagation.NOT_SUPPORTED)

    public Person getPerson(Integer id)

 

    bean上开启了事务功能,上面所有的方法默认都是要进行事务操作的,默认的不需要加任何注解,等同于下面的形式:

  @Transactional(propagation = Propagation.REQUIRED)

    public Person savePerson(Person person)

 

    从属性文件中读取数据库连接池参数信息。

 

posted on 2014-10-16 23:20  lnlvinso  阅读(771)  评论(0编辑  收藏  举报