Dashboard > OpenSource Project > ... > Spring > 入門 28 - 從實例入門Spring持久層
OpenSource Project Log In   View a printable version of the current page.
入門 28 - 從實例入門Spring持久層
Added by cheetah, last edited by cheetah on Mar 26, 2005
Labels: 
(None)

  在持久層的封裝與整合上,Spring作了許多的努力,這邊以一個簡單的實際例子來小小體會一下使用Spring所提供的持久層所帶來的優點之一(只是其中之一的優點,之後還會看到更多的實例,我一向喜歡從實例中體會框架的功能)。

  首先請您先複習一下在Spring中如何進行DataSource的設定:

  這邊我們設計一個簡單的UserDAO物件,我們直接使用JDBC,首先來看看Spring提供什麼樣的物件來簡化JDBC程式的撰寫:

代碼:

UserDAO.java
package onlyfun.caterpillar; 

import javax.sql.DataSource; 
import java.sql.*; 
import org.springframework.jdbc.core.JdbcTemplate; 

public class UserDAO { 
    private DataSource dataSource; 

    public void setDataSource(DataSource dataSource) { 
        this.dataSource = dataSource; 
    } 
    
    public void insertUser(User user) { 
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 
        jdbcTemplate.update("INSERT INTO USER VALUES('"+ user.getId() + "', '" 
                + user.getName() + "', '" 
                + user.getSex() + "', '" 
                + user.getAge() + "')"); 
    } 
    
    public User queryUser(String id) { 
        .... 
    } 

    ... 
}

  這個DAO物件實現了手動的O/R Mapping,如您所見的,真正的儲存動作只要兩行程式,如果是使用傳統的JDBC程式撰寫,您的insertUser()可能像是這樣撰寫:

代碼:

UserDAO.java
package onlyfun.caterpillar; 

import javax.sql.DataSource; 
import java.sql.*; 
import org.springframework.jdbc.core.JdbcTemplate; 

public class UserDAO { 
    private DataSource dataSource; 

    public void setDataSource(DataSource dataSource) { 
        this.dataSource = dataSource; 
    } 
    
    public void insertUser(User user) { 
        Connection conn = null; 
        Statement stmt = null; 
        try { 
            conn = dataSource.getConnection(); 
            stmt = conn.createStatement(); 
            stmt.executeUpdate("INSERT INTO USER VALUES('"+ user.getId() + "', '" 
                                                          + user.getName() + "', '" 
                                                          + user.getSex() + "', '" 
                                                          + user.getAge() + "')");            
        } 
        catch(SQLException e) { 
            e.printStackTrace(); 
        } 
        finally { 
            if(stmt != null) { 
                try { 
                    stmt.close(); 
                }    
                catch(SQLException e) { 
                    e.printStackTrace(); 
                } 
            } 
            
            if(conn != null) { 
                try { 
                    conn.close(); 
                } 
                catch(SQLException e) { 
                    e.printStackTrace(); 
                } 
            } 
        } 
    } 
    
    public User queryUser(String id) { 
        .... 
    } 

    .... 
}

  您必須自行取得Connection與Statement物件、執行SQL、捕捉例外、關閉相關資源,當您使用Spring的JdbcTemplate時,卻只要兩行,Spring的JdbcTemplate封裝了傳統的JDBC程式執行流程,並為您作了例外處理與資源管理等動作,您所需要的只是一個給它一個DataSource,而這只要在bean定義檔中完成依賴注入:

代碼:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 
<beans> 
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
        <property name="driverClassName"> 
            <value>com.mysql.jdbc.Driver</value> 
        </property> 
        <property name="url"> 
            <value>jdbc:mysql://localhost:3306/TestDB</value> 
        </property> 
        <property name="username"> 
            <value>caterpillar</value> 
        </property> 
        <property name="password"> 
            <value>123456</value> 
        </property> 
    </bean> 
                                    
    <bean id="userDAO" class="onlyfun.caterpillar.UserDAO"> 
        <property name="dataSource"> 
            <ref bean="dataSource"/> 
        </property> 
    </bean> 
</beans>

  Spring的JdbcTemplate一如其名稱所示的,主要是藉由Template Method模式來實現封裝,視您的需求而定,JdbcTemplate也可以在bean定義檔中生成,當作一個bean來源注入DAO中,例如我們的UserDAO可以修改如下:

代碼:

UserDAO.java
package onlyfun.caterpillar; 

import javax.sql.DataSource; 
import java.sql.*; 
import org.springframework.jdbc.core.JdbcTemplate; 

public class UserDAO { 
    private JdbcTemplate jdbcTemplate; 

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { 
        this.jdbcTemplate = jdbcTemplate; 
    }    
    
    
    public void insertUser(User user) { 
        jdbcTemplate.update("INSERT INTO USER VALUES('"+ user.getId() + "', '" 
                + user.getName() + "', '" 
                + user.getSex() + "', '" 
                + user.getAge() + "')"); 
    } 
    
    public User queryUser(String id) { 
        .... 
    } 
    .... 
}

  而bean定義檔修改如下即可完成依賴注入:

代碼:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 
<beans> 
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
        <property name="driverClassName"> 
            <value>com.mysql.jdbc.Driver</value> 
        </property> 
        <property name="url"> 
            <value>jdbc:mysql://localhost:3306/TestDB</value> 
        </property> 
        <property name="username"> 
            <value>caterpillar</value> 
        </property> 
        <property name="password"> 
            <value>123456</value> 
        </property> 
    </bean> 
                                    
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 
        <property name="dataSource"> 
            <ref bean="dataSource"/> 
        </property> 
    </bean> 
                                                                                
    <bean id="userDAO" class="onlyfun.caterpillar.UserDAO"> 
        <property name="jdbcTemplate"> 
            <ref bean="jdbcTemplate"/> 
        </property> 
    </bean> 
</beans>

  更進一步的,我們還可以利用Spring IoC容器的功能,將SQL語句以依賴注入的方式設定給DAO,而不用像上例中直接寫死在DAO類別中。

  Spring的Jdbc封裝等功能基本上可以獨立於Spring來使用,如您所看到的,JdbcTemplate所需要的就是一個DataSource物件,在不使用Spring IoC容器下,您可以單獨使用spring-dao.jar中的東西。

  除了JdbcTemplate之外,Spring還提供了其它的Template類別,像是對Hibernate、JDO、ibatis等的Template實現,另外,在事務處理方面,Spring提供了編程式與宣告式的事務管理功能,大大的簡化了持久層程式的複雜度,並提供了更好的維護性,在之後的主題中將會一一介紹Spring在這些議題上所提供的功能。

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.1.5a Build:#411 Mar 16, 2006) - Bug/feature request - Contact Administrators