Spring学习笔记(十三)-----Spring in Action

Spring学习笔记(十三)-----Spring in Action

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


}

你可能感兴趣的:(Spring学习笔记(十三)-----Spring in Action)