posts - 66,  comments - 11,  trackbacks - 0

    Spring的一个目标就是让你遵循对接口编程的面向对象原则。DAO的存在提供了读写数据库中数据的一种方

法。只要把这个功能通过接口暴露,应用的其他部分就可以通过这些接口访问数据库了。
    在Spring的DAO框架里,Connection对象是通过DataSource获得的。
    从JNDI得到DataSource,代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans
    
xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
<!-- Spring应用经常运行在J2EE应用服务器上,或者是诸如Tomcat的Web服务器上。这些服务器都能提供的一件事:通过
    JNDI获得DataSource.现在我们已经和服务器上的DataSource以及它的连接池功能连接上了。
     
-->
    
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        
<property name="jndiName">
            
<value>java:comp/env/jdbc/myDatasource</value>
        
</property>
    
</bean>
    
<!-- 加入Spring容器运行在一个不提供DataSource的环境中,但我们还希望拥有连接池的好处,我们要实现一个DataSource
    的连接池Bean,我们有了一个带连接池的DataSource,它不依赖于任何应用服务器,代码如下: 
-->
    
<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource">
        
<property name="driverClassName">
            
<value>${db.driver}</value>
        
</property>
        
<property name="url">
            
<value>${db.url}</value>
        
</property>
        
<property name="username">
            
<value>${db.username}</value>
        
</property>
        
<property name="password">
            
<value>${db.password}</value>
        
</property>
    
</bean>
</beans>


    一个模版方法定义一个流程的骨架。在我们的例子中,这个流程就是把行李从出发地运送到目的地。流程本身是固定的,不会改变。处理行李的事件顺序每一次都是一样的:检查行李、放到飞机上等等。当飞机到达目的地时,行李都被一件件的卸下来,放到传送带上,再运到行李提取处。流程是固定的,但是流程中的具体实现有些是可变的。一个模版方法将这部分可变流程的具体实现委托给一个接口,这个接口的不同实现定义了这部分流程的具体实现。
    Spring把这个模式应用到数据访问上。不管我们采用什么技术,某些数据访问步骤是必须的。例如:我们总是需要和数据库建立连接,在操作完后释放资源。这就是数据访问流程中的固定步骤。但我们写的每个数据访问的实现都有略微不同,我们用不同的方式查询不同的对象、更新数据。这些就是数据访问流程中的可变步骤。
    Spring把数据访问流程中的固定部分和可变部分分开,分别映射成2个截然不同的类:模版和回调。模版管理流程的固定部分,而在回调处填写你的实现细节。
    在模版和回调的设计之上,每个框架都提供一个支撑类,以便让你自己的数据访问类来继承它们。这些支撑类早已拥有一个指向模版类的属性,所以不需要为每个DAO类创建这个属性。另外,每个支撑类都允许你直接得到用于跟数据库打交道的类。
    模版代码使用如下:

package com.testproject.spring.datasource;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;

import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
/*
 * 为了让JdbcTemplate工作,它所需要的,只是一个DataSource实例。
 
*/

public class StudentDaoJdbc implements StudentDao {
    
private JdbcTemplate jdbcTemplate;
    
    
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        
this.jdbcTemplate = jdbcTemplate;
    }

    
/*
     * 先从SQL语句创建一个PreparedStatement,然后绑定参数。在幕后,JdbcTemplate
     * 类创建了PreparedStatementCreator和PreparedStatementSetter.这些我们都
     * 不用关心,我们只管提供SQL语句和参数。还可以提供类型支持。
     
*/

    
public int insertPerson(Person person){
        String sql 
= "insert into person(id,firstName,lastName) values(?,?,?)";
        Object[] params 
= new Object[]{person.getId(),person.getFirstName(),person.getLastName()};
        
return jdbcTemplate.update(sql,params);
    }

    
public int insertPerson2(Person person){
        String sql 
= "insert into person(id,firstName,lastName) values(?,?,?)";
        Object[] params 
= new Object[]{person.getId(),person.getFirstName(),person.getLastName()};
        
int[] types = new int[]{Types.INTEGER,Types.VARBINARY,Types.VARBINARY};
        
return jdbcTemplate.update(sql, params, types);
    }

    
/*
     * 批量更新,我们讲使用BatchPreparedStatementSetter,这个接口的2个方法
     * 1、getBatchSize()告诉JdbcTemplate类有多少个语句要创建,同时也决定了要调用多少次setValues()
     * 2、setValues负责创建参数
     * 所以你的JDBC驱动支持批量操作,这些更新讲被批量执行,是的数据访问更高效。
     
*/

    
public int[] updatePersons(final List persons){
        String sql 
= "insert into person(id,firstName,lastName) values(?,?,?)";
        BatchPreparedStatementSetter setter 
= null;
        setter 
= new BatchPreparedStatementSetter(){
            
public int getBatchSize(){
                
return persons.size();
            }

            
public void setValues(PreparedStatement ps,int index)throws SQLException{
                Person person 
= (Person)persons.get(index);
                ps.setInt(
0,person.getId().intValue());
                ps.setString(
1,person.getFirstName());
                ps.setString(
2,person.getLastName());
            }

        }
;
        
return jdbcTemplate.batchUpdate(sql, setter);
    }

    
/*
     * 当查询数据库时,我们需要通过ResultSet取得结果,Spring认识到这一步是任何查询都需要的,所以它帮助
     * 我们处理了这些。取而代之,我们只需要简单的告诉Spring要怎么处理ResultSet中的每一行记录。我们通过
     * 实现RowCallbackHandler接口中仅有的一个方法来完成上述功能。
     * void processRow(java.sql.ResultSet rs)该方法将为ResultSet中的每条记录调用一次
     * 这个方法只支持单对象的查询
     
*/

    
public Person getPerson(final Integer id){
        String sql 
= "select id,first_Name,last_Name from person where id=?";
        
final Person person = new Person();//创建查询结果对象
        final Object[] params = new Object[]{id};//创建查询参数
        
        jdbcTemplate.query(sql,params,
new RowCallbackHandler(){//处理查询结果
            public void processRow(ResultSet rs)throws SQLException{
                person.setId(
new Integer(rs.getInt("id")));
                person.setFirstName(rs.getString(
"first_name"));
                person.setLastName(rs.getString(
"last_name"));
            }

        }
);
        
return person;//返回查询结果对象
    }

    
/*
     * 查询所有记录
     * RowMapper接口对从一个查询结果中提取多个对象非常游泳。
     
*/

    
public List getAllPersons(){
        String sql 
= "select id,first_name,last_name from person";
        
return jdbcTemplate.query(sql,new PersonRowMapper());
    }

    
/*
     * 查找基本类型
     
*/

    
public int getNumberOfPerson(){
        
return jdbcTemplate.queryForInt("select count(*) from person");
    }

    
public String getLastNameForId(Integer id){
        String sql 
= "select last_name from person where id=?";
        
return (String)jdbcTemplate.queryForObject(sql,new Object[]{id},String.class);
    }

    
}

package com.testproject.spring.datasource;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

public class PersonRowMapper implements RowMapper {

    
public Object mapRow(ResultSet rs, int index) throws SQLException {
        Person person 
= new Person();
        person.setId(
new Integer(rs.getInt("id")));
        person.setFirstName(rs.getString(
"first_name"));
        person.setLastName(rs.getString(
"last_name"));
        
return person;
    }


}

posted on 2009-11-12 19:46 王永庆 阅读(171) 评论(0)  编辑  收藏 所属分类: SPRING

只有注册用户登录后才能发表评论。


网站导航:
 
<2009年11月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用链接

留言簿(1)

随笔分类

随笔档案

关注blogs

搜索

  •  

最新评论

阅读排行榜

评论排行榜