SSH框架之Spring進階持久層模板(四)

第一節(jié):

Spring提供了很多持久層技術的模板類簡化編程


1.1 JDBC模板使用入門

  • 創(chuàng)建項目引入jar包


  • 創(chuàng)建數(shù)據(jù)庫
CREATE DATABASE spring;
USE spring;
CREATE TABLE account(id int PRIMARY KEY auto_increment,
                name VARCHAR(20),
                money DOUBLE);
//修改數(shù)據(jù)庫字符集
ALTER DATABASE spring CHARACTER SET utf8;
//修改表的字符集
ALTER TABLE account DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
//修改表中某個字段的字符集
ALTER TABLE account CHANGE name name VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci;
  • JDBC模板的簡單使用
public class JdbcTest {

    @Test
    public void jdbc(){
        //創(chuàng)建連接池
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://*.*.*.*:3306/spring?characterEncoding=utf-8");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        //創(chuàng)建JDBC模板
        JdbcTemplate template = new JdbcTemplate(dataSource);
        //執(zhí)行插入操作
        template.update("insert into account value (null ,?,?)","周四",3000d);

        //執(zhí)行更新操作
        template.update("update account set name = ? WHERE id = ?","周日",2);

        //執(zhí)行刪除操作
        template.update("delete FROM account WHERE id = ?",1);

        //執(zhí)行查詢操作
        Long aLong = template.queryForObject("SELECT COUNT(*) FROM account", Long.class);
        System.out.println(aLong);
    }
}

1.2 JDBC模板結合Spring的使用

  • 在Spring配置文件中,通過屬性注入的方式配置JdbcTemplate
<!--配置Spring的內(nèi)置連接池-->
    <bean id="dataSorce" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--通過屬性注入的方式,鍵入相關參數(shù)-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://*.*.*.*:3306/spring?characterEncoding=utf-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--配置JDBC模板-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--通過屬性注入的方式,設置數(shù)據(jù)源-->
        <property name="dataSource" ref="dataSorce" />
    </bean>
  • 對應測試類如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTest02 {

    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;

    @Test
    /**
     * 添加數(shù)據(jù)
     */
    public void add(){
        jdbcTemplate.update("INSERT INTO account VALUE (null,?,?)","王者",10000d);
    }

    /**
     * 更新數(shù)據(jù)
     */
    @Test
    public void update(){
        jdbcTemplate.update("UPDATE account SET name = ? WHERE id = ? ","路飛",2);

    }

    /**
     * 數(shù)據(jù)查找
     */
    @Test
    public void find(){
        Long aLong = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM account", Long.class);
        System.out.println(aLong);
    }

    /**
     * 刪除數(shù)據(jù)
     */
    @Test
    public void del(){
        jdbcTemplate.update("DELETE FROM account WHERE id = ?",2);
    }
}

1.3 DBCP以及C3p0的使用

  • 通過Spirng配置文件,配置由DBCP生成的數(shù)據(jù)源(需引入對應的jar包)


<!--配置由DBCP生成的數(shù)據(jù)連接池-->
    <bean id="dateSourceDbcp" class="org.apache.commons.dbcp.BasicDataSource">
        <!--通過屬性注入的方式,設置連接參數(shù)-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://*.*.*.*:3306/spring?characterEncoding=utf-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
  • 通過Spirng配置文件,配置由C3p0生成的數(shù)據(jù)源連接池,引入對應jar包


<!--配置由C3p0生成的數(shù)據(jù)連接池-->
    <bean id="dateSourceC3p0" class="org.apache.commons.dbcp.BasicDataSource">
        <!--通過屬性注入的方式,設置連接參數(shù)-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://*.*.*.*:3306/spring?characterEncoding=utf-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

1.4 關聯(lián)參數(shù)由引入外部屬性文件來配置

  • 新建jdbc.properties 配置屬性文件
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://*.*.*.*:3306/spring?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
  • 在Spring的applicationContext.xml配置文件中引入屬性文件
<!--引入外部配置的屬性文件-->
    <!--方式一:-->
    <!--
        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
          <property name="location" value="classpath:jdbc.properties"/>
        </bean>
        -->
    <!--方式二:通常使用該方法引入配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--通過外部屬性來設置對應值-->
    <bean id="dateSourceC3p0" class="org.apache.commons.dbcp.BasicDataSource">
        <!--通過屬性注入的方式,設置連接參數(shù)-->
        <property name="driverClassName" value="${jdbc.driverClass}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

第二節(jié):Spring進行事務管理

2.1 PlatformTransactionManager:平臺事務管理器

org.springframework.jdbc.datasource.DataSourceTransactionManager:使用Spring JDBC或iBatis進行持久化數(shù)據(jù)時使用。
org.springframework.orm.hibernate3.HibernateTransactionManager:使用Hibernate版本進行持久化數(shù)據(jù)時使用

2.2 TransactionDefinition:事務定義信息

  • 隔離級別
  • 傳播行為
  • 超時信息
  • 是否只讀

2.3 TransactionStatus:事務的狀態(tài)

  • 記錄事務狀態(tài)。

2.4 小結:

Spring進行事務管理的時候,首先平臺事務管理器根據(jù)事務定義信息進行事務的管理,在事務管理過程中,產(chǎn)生各種狀態(tài),將這些狀態(tài)的信息記錄到事務狀態(tài)的對象中。

第三節(jié):Spring事務的傳播行為

Spring中提供了七種事務的傳播行為:

  • 保證多個操作在同一個事務中

PROPAGATION_REQUIRED:默認值,如果A中有事務,使用A中的事務,如果A沒有,創(chuàng)建一個新的事務,將操作包含進來

PROPAGATION_SUPPORTS:支持事務,如果A中有事務,使用A中的事務。如果A沒有事務,不使用事務。

PROPAGATION_MANDATORY:如果A中有事務,使用A中的事務。如果A沒有事務,拋出異常。

  • 保證多個操作不在同一個事務中

PROPAGATION_REQUIRES_NEW:如果A中有事務,將A的事務掛起(暫停),創(chuàng)建新事務,只包含自身操作。如果A中沒有事務,創(chuàng)建一個新事務,包含自身操作。

PROPAGATION_NOT_SUPPORTED:如果A中有事務,將A的事務掛起。不使用事務管理。

PROPAGATION_NEVER:如果A中有事務,報異常。

  • 嵌套式事務

PROPAGATION_NESTED:嵌套事務,如果A中有事務,按照A的事務執(zhí)行,執(zhí)行完成后,設置一個保存點,執(zhí)行B中的操作,如果沒有異常,執(zhí)行通過,如果有異常,可以選擇回滾到最初始位置,也可以回滾到保存點。

第四節(jié):Spring事務管理實踐

4.1 聲明式事務(以xml方式實現(xiàn))

  • 定義基礎類,實現(xiàn)測試環(huán)境的搭建
//Service
public interface AccountService {

    void transfer(String fromName,String toName,double money);

}

public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public void transfer(String fromName, String toName, double money) {
        accountDao.fromTransfer(fromName,money);
//模擬異常,測試事務的執(zhí)行。
//        int i = 10/0;
        accountDao.toTransfer(toName,money);
    }
}

//DAO層
public interface AccountDao {
    
    void fromTransfer(String fromName,double money);
    void toTransfer(String toName,double money);

}
public class AccountDaoImpl implements AccountDao {


    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void fromTransfer(String fromName, double money) {
        jdbcTemplate.update("UPDATE account SET money = money - ? WHERE name = ?"
                ,money,fromName);
    }

    @Override
    public void toTransfer(String toName, double money) {
        jdbcTemplate.update("UPDATE account set money = money + ? WHERE name = ?"
                ,money,toName);
    }
}
  • Spring的applicationContext.xml配置文件中,實現(xiàn)對Service層以及Dao層的托管,并實現(xiàn)屬性注入。
<bean id="accountService" class="com.seapp.spring.template.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>
    </bean>

    <bean id="accountDao" class="com.seapp.spring.template.impl.AccountDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
  • AOP理論,實現(xiàn)事務增強
<!--聲明式事務,以xml方式實現(xiàn)-->
    <!--配置事務管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dateSourceC3p0"/>
    </bean>

    <!--配置事務的通知,配置增強-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager" >
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!--aop的配置-->
    <aop:config>
        <aop:pointcut expression="execution(* com.seapp.spring.template.impl.AccountServiceImpl.transfer(..))" id="pointcut"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>

  • 測試類:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TemplateTest {


    @Resource(name = "accountService")
    private AccountService accountService;

    @Test
    public void demo01(){
        accountService.transfer("王者","喬巴",2000d);
    }
}

4.2 聲明式事務(以注解方式實現(xiàn):)

  • applicationContext.xml對于注解式事務的配置
<!--聲明式事務,以注解方式實現(xiàn)-->
    <!--配置事務管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dateSourceC3p0"/>
    </bean>
    <!--開啟事務管理注解-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
  • 在需要開啟事務的實現(xiàn)類上,添加注解
@Transactional//注解式事務所添加的注解
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public void transfer(String fromName, String toName, double money) {
        accountDao.fromTransfer(fromName,money);
//        int i = 10/0;
        accountDao.toTransfer(toName,money);
    }
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容