1. 程式人生 > >8.spring:事務管理(上):Spring的資料庫程式設計、程式設計式事務管理

8.spring:事務管理(上):Spring的資料庫程式設計、程式設計式事務管理

Spring的資料庫程式設計

 Spring框架提供了JDBC模板模式------>JdbcTemplate

簡化了開發,在開發中並不經常是使用

實際開發更多使用的是Hibernate和MyBatis

1).Spring JDBCp配置

如果使用Spring JDBC操作資料庫,要有如下的配置:

在xml配置檔案

<!-- 配置資料來源:可以使用各種資料來源如c3p0.... -->
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource
" > <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://127.0.0.1:3306/tx" /> <property name="username" value="root" /> <property name="password" value="1234" /> </bean> <!-- 配置jdbc模組 --> <bean id="
jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>

配置JDBC模板需要將dataSource注入到jdbcTemplate

 

 有時候也需要將JdbcTemplate注入到相應的Bean中可以使用:

@Autowired
private JdbcTemplate jdbcTemplate ;

 

2).JdbcTemplate  常用方法

--->public int update(String sql,Object args []):l=可以對資料庫進行增加、修改、刪除等操作...

--->public List<T> query (String sql,RowMapper<T> rowMapper,Object args[]):該方法執行對資料庫的查詢...

 

 相關jar:

-logging

-mysql-connector-java-

-aop

-beans

-context

-core

-expression

-jdbc

tx

 

注:在dao方法中的操作可以使用@Componment、@Respository、@Service、@controller進行對包掃描,使用@Autowire進行自動注入!

 

 3).測試:

 新建資料庫

資料庫對應的實體類:

User.java

public class User {
    private Integer id;
    private String name;
    private String pw;
        //....
}

 tx.xml

<!-- 配置資料來源 -->
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
     <property name="driverClassName"  value="com.mysql.jdbc.Driver" />
     <property name="url" value="jdbc:mysql://127.0.0.1:3306/tx" />
     <property name="username" value="root" />
     <property name="password" value="1234" />
</bean> 

<!-- 配置jdbc模組 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property>
</bean>

 測試:

 public ApplicationContext getapp(){
         return new 
                 ClassPathXmlApplicationContext("tx.xml");
     }

    //增刪改....
    @Test
    public void test1(){
        JdbcTemplate jdbcTemplate = (JdbcTemplate) getapp().getBean("jdbcTemplate");
        System.out.println(jdbcTemplate);
               Object a [] = {4,"user4","pwd4"};
        Object b [] = {5,"user5","pwd5"};
        
        String sql = "insert into user values(?,?,?)";
        
        //新增使用者
        jdbcTemplate.update(sql, a);
        jdbcTemplate.update(sql, b);
        
        //查詢
        sql = "select * from user";
        
        RowMapper<User> rowMapper = new BeanPropertyRowMapper<User>(User.class);
        List<User> users =  jdbcTemplate.query(sql, rowMapper, null);
        for(User user : users){
            System.out.println(user);
        }    
    }

 

 

程式設計式事務管理

 1).基於底層API的程式設計式事務管理

基於底層API的程式設計式事務管理就是根據PlatformTransactionManager、TransactionDefinition和

TransactionStatus幾個核心介面,通過程式設計的方式解決來進行事務處理。

 

需要在spring的配置檔案中:

<!-- 配置資料來源 -->
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
     <property name="driverClassName"  value="com.mysql.jdbc.Driver" />
     <property name="url" value="jdbc:mysql://127.0.0.1:3306/tx" />
     <property name="username" value="root" />
     <property name="password" value="1234" />
</bean> 

<!-- 配置jdbc模組 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 為資料來源新增事物管理 -->
<bean id="dataSourceTransactionManager" 
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

 

 test

    //事務管理...
    @Test
    public void test2(){
        JdbcTemplate jdbcTemplate = (JdbcTemplate) getapp().getBean("jdbcTemplate");
        //事物管理器
        DataSourceTransactionManager tx = (DataSourceTransactionManager) getapp().getBean("dataSourceTransactionManager"); 
        //預設事物定義,隔離級別、傳播行為....
        TransactionDefinition tf = new DefaultTransactionDefinition();
        //開啟事物
        TransactionStatus ts = tx.getTransaction(tf);    
        
     String res
= tx(jdbcTemplate, tx, tf, ts); System.out.println(res); } public String tx(JdbcTemplate jdbcTemplate,DataSourceTransactionManager tx, TransactionDefinition tf,TransactionStatus ts){ String msg = "執行成功,沒有事物回滾!"; try{ Object a [] = {2,"user2","pwd2"}; String sql = "insert into user values(?,?,?)"; //新增使用者 //主鍵重複 jdbcTemplate.update(sql, a); //提交事務 tx.commit(ts); }catch(Exception e){ //出現異常,事物回滾 tx.rollback(ts); msg= "主鍵重複!!!"; e.printStackTrace(); } return msg; }

 

 

 

以上的這種操作會讓事物處理的程式碼散落在業務邏輯程式碼中,破壞了原有程式碼的條理性,並且讓每一個業務方法都包含了

類似啟動事物、提交以及回滾事務的樣板式程式碼。

 

TransactionTemplate的execute方法有一個TransactionCallback介面型別的引數,該介面定義了doInTransaction方法、通常

以匿名內部類的方式實現TransactionCallback介面,在doInTransaction方法中寫業務邏輯程式碼

 public T doInTransaction(TransactionStatus arg0)

 TransactionStatus型別引數、可以在方法的任何位置呼叫該引數方法的setRollbackOnly方法將事務標識為回滾、以執行事務回滾

 

根據預設規則:

如果在執行回撥方法過程中如果丟擲未檢查異常或者顯示呼叫setRollbackOnly方法,則回滾事物

如果事務執行完成或丟擲了checked型別的異常,則提交事務

 

程式碼待完成......