:: 首页 ::  :: 联系 :: 聚合  :: 管理

五、Spring 持久层

对于不同的数据库技术,某些步骤是固定的,只有少部分不同。Spring运用Template Method模式,将固定的流程编写与Temp类(JdbcTemplateHibernateTemplate)之中,对不同的一些细节步骤,依托特定DAO支持对象来处理。

SpringDAO框架并不抛出与数据库技术相关的异常,Spring所有异常都是DataAccessException的子类,一个与数据库技术无关的通用异常类,该类继承至RuntimeException

对于Jdbc存取,SpringSQLException等转化为自己的DAO异常对象。

DataSource注入

对于不同的数据库链接来源需求,Spring提供了javax.sql.DataSource注入,更换数据来源只需在Bean定义文件中修改配置,不需修改程序代码。
例如可以在Bean文件中编写如下:

 1<!-- 带连接池的DataSource -->
 2<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
 3    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
 4    <property name="url" value="jdbc:mysql://localhost:3306/test" />
 5    <property name="username" value="root" />
 6    <property name="password" value="root" />
 7</bean>
 8    
 9<bean id="peopleDao" class="SpringPersistence.PeopleDaoMySQLImpl">
10    <property name="dataSource" ref="dataSource" />
11</bean>

要建立JdbcTemplate的实例,

 1public class PeopleDaoMySQLImpl implements PeopleDao {
 2    
 3    private DataSource dataSource;
 4    
 5    public void setDataSource(DataSource dataSource){
 6        this.dataSource = dataSource;
 7    }

 8
 9    public void save(People people) {
10        Connection conn = null;
11        Statement stmt = null;
12        try {
13            conn = dataSource.getConnection();
14            stmt = conn.createStatement();
15            stmt.execute("INSERT INTO people VALUES (" + people.getId()
16                    + ",'" + people.getName() + "'," + people.getAge() + ")");
17            stmt.execute("");
18        }
 catch (SQLException e) {
19            e.printStackTrace();
20        }
 finally {
21            if(stmt != null){
22                try {
23                    stmt.close();
24                }
 catch (SQLException e) {
25                    e.printStackTrace();
26                }

27            }
    
28            if(conn != null){
29                try {
30                    conn.close();
31                }
 catch (SQLException e) {
32                    e.printStackTrace();
33                }

34            }

35        }

36    }

37}


    使用JdbcTemplate

JdbcTemplate封装了Connection的取得,Statement的建立,异常的处理,Statement的关闭,Connection的关闭等。它被设计为线程安全的。

要建立JdbcTemplate的实例,必须要有一个DataSource对象作为构造对象。

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

Spring事务管理

Spring提供编程式事务管理与声明式事务管理。

编程式事务管理

Spring提供了两种方式实现编程式事务管理:使用PlatformTransactionManager实现;使用org.springframework.transaction.support.TransactionTemplate

    PlatformTransactionManager接口定义如下:

1public class interface PlatformTransactionManager {
2    public void commit(TransactionStatus status) throws TransactionException;
3    public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
4    public void rollback(TransactionStatus arg0) throws TransactionException;
5}

DataSourceTransactionManager是其一个实现类。

修改添加新用户的代码段作为示例:

 1public class PeopleDaoMySQLImpl2 implements PeopleDao {
 2
 3    private DataSource dataSource;
 4    private DataSourceTransactionManager transactionManager;
 5    private DefaultTransactionDefinition def;
 6    private JdbcTemplate jdbcTemplate;
 7
 8    public void setDataSource(DataSource dataSource) {
 9        this.dataSource = dataSource;
10        jdbcTemplate = new JdbcTemplate(dataSource);
11        transactionManager = new DataSourceTransactionManager(dataSource);
12        def = new DefaultTransactionDefinition();
13        def.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
14    }

15
16    public void save(People people) {
17        TransactionStatus status = transactionManager.getTransaction(def);
18        try {
19            jdbcTemplate.execute("INSERT INTO people VALUES (" + people.getId()
20                        + ",'" + people.getName() + "'," + people.getAge() + ")");
21            //jdbcTemplate.execute("");
22        }
 catch (DataAccessException e) {
23            transactionManager.rollback(status);
24            throw e;
25        }

26        transactionManager.commit(status);
27    }

28}

另一个编程式事务管理方法是使用TransactionTemplate,它需要一个TransactionManager实例,如下:

 1public class PeopleDaoMySQLImpl3 implements PeopleDao {
 2
 3    private DataSource dataSource;
 4    private DataSourceTransactionManager transactionManager;
 5    private JdbcTemplate jdbcTemplate;
 6
 7    public void setDataSource(DataSource dataSource) {
 8        this.dataSource = dataSource;
 9        jdbcTemplate = new JdbcTemplate(dataSource);
10        transactionManager = new DataSourceTransactionManager(dataSource);
11    }

12
13    public void save(People people) {
14        final int id = people.getId();
15        final String name = people.getName();
16        final int age = people.getAge();
17        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
18        transactionTemplate.execute(new TransactionCallbackWithoutResult(){
19            public void doInTransactionWithoutResult(TransactionStatus status){
20                try {
21                    jdbcTemplate.execute("INSERT INTO people VALUES (" + id
22                            + ",'" + name + "'," + age + ")");
23                    //jdbcTemplate.execute("");
24                }
 catch (DataAccessException e) {
25                    status.setRollbackOnly();
26                }

27            }

28        }
);
29    }

30}

声明式事务管理

Spring的声明式事务管理依赖于它的AOP框架来完成,使用声明式的事务管理的好处是,事务管理不侵入开发的组件。

定义文件如下:

 1<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 2    <property name="dataSource" ref="dataSource" />
 3</bean>
 4
 5<bean id="peopleDaoProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
 6    <property name="proxyInterfaces">
 7        <list>
 8            <value>SpringPersistence.PeopleDao</value>
 9        </list>
10    </property>
11    <property name="target" ref="peopleDao"/>
12    <property name="transactionManager" ref="transactionManager" />
13    <property name="transactionAttributes">
14        <props>
15            <prop key="sa*">PROPAGATION_REQUIRED</prop>
16        </props>
17    </property>
18</bean>



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


网站导航: