1. 程式人生 > >Spring---AOP註解開發&jdbc模板&Spring事務管理

Spring---AOP註解開發&jdbc模板&Spring事務管理

use oca update -m spl pub tex com att

一、AOP註解開發

  此處需要回憶一遍AOP的概念。簡單的來說,AOP就是利用動態代理技術,做到不觸動源代碼但卻擴展了功能。那麽就需要一個被擴展的對象和一個“新的功能”,例如說給某類的saveUser方法增加輸出日誌需求,此時輸出日誌該事件就是一個“新的功能”。舉這個例子的重點只是為了突出,AOP技術需要關註兩個方面,一個是接受者,而另一個是輸出點。要利用AOP,必然需要將這兩個對象做出關聯。而所謂AOP註解開發,就是如何將這兩個對象建立關系。

  當然,以上理解僅僅為個人的話語解讀,不具有嚴謹的用詞,有任何理解錯誤,望不吝賜教。

  在AOP的xml開發中,xml核心配置如下

<aop:config
> <--切入點(接受對象)--> <aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))" id="aa"/> <--切面(新功能)--> <aop:aspect ref="logger"> <aop:before method="log" pointcut-ref="aa"/> </aop:aspect> </aop:config>

  因此,註解只需要做到清楚表達以上兩點內容,再配套一些基本的要求,例如托管類。此外,為了讓程序的復用性更強,我們只需要對“新功能”對象做處理,告訴它要為誰增強方法即可做到關聯,以下為實例:

  • 導入jar包 aop聯盟包、 aspectJ實現包 、 spring-aop-xxx.jar 、 spring-aspect-xxx.jar
  • 導aop約束 ,打開掃描約束開關<aop:aspectj-autoproxy/>
  • 托管兩個類,在類上加註解@Compone
  •  然後再“新的功能”類上配置註解
@Aspect //這個註解,是和aop有關,用於表示該類是一個功能擴展類,專門用來做增強的。
public class Logger {
    @Before("execution(* com.gaga.service.impl.*.*(..))")
    public void
log(){ System.out.println("輸出日誌了~~~!"); }

二、jdbc模板

  所謂jdbc模板,就是Spring對於dao層的技術支持。和DBUtils的功能的目的是一樣的,就是為了操作數據庫。回想以下,如果什麽框架都沒有,只有java原生代碼提供給我們的prepareStatement、createStatement、遍歷resultSet那一套東西。那我們的操作便會過於臃腫。

  雖然操作數據庫有更專業的框架,例如Hibernate\Mybatis等等。但作為一個負責Service層的框架,自然會有向兩邊擴展的思想,因此便有了該部分模板。

  spring其實對dao層的大部分技術有提供模板支持

技術分享圖片

  1. 例子:
public void testDemo(){
        
        //數據源,連數據庫。 連什麽類型的數據, 哪個庫, 賬號 & 密碼
        DriverManagerDataSource dataSource  =new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///stus");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        
        //1. 創建jdbc模板
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
                
        String sql = "insert into t_user values(null , ? , ? )";
        
        //2. 執行添加操作,其實它的用法和以前的queryrunner一樣。
        jdbcTemplate.update(sql , "66666","zhangsan");
    }

  2.配置C3P0連接池(註入寫法)

  為了方便修改數據庫連接信息,通常在src下使用properties文件來記錄他們。主要是方便修改

  •   導入Jar包 c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar
  •   配置xml
    •  在src下新建一個properties文件,內容如下 名:jdbc.properties
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql:///user
user=root
password=root
    •  在xml裏面導入jdbc.properties ,並且在dataSource裏面引用
      <bean id="us" class="com.gaga.service.impl.UserServiceImpl">
              <property name="userDao" ref="userDao"></property>
      </bean>
      
      <bean id="userDao" class="com.gaga.dao.impl.UserDaoImpl">
              <property name="jdbcTemplate" ref="jdbcTemplate"></property>
      </bean>
      
      
      <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
              <property name="dataSource" ref="dataSource"></property>
      </bean>
       
       <context:property-placeholder location="classpath:jdbc.properties"/>
                  <!-- 使用c3p0連接池 -->
                <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                    <property name="driverClass" value="${driverClass}"></property>
                    <property name="jdbcUrl" value="${jdbcUrl}"></property>
                    <property name="user" value="${user}"></property>
                    <property name="password" value="${password}"></property>
                </bean>

  以上配置將service\dao\jdbcTemplate\連接池都用IOC做了托管,並且用了DI註入,也就是說1.例子中的一堆堆代碼可以簡化為如下。只需要聲明模板,然後直接可以使用,創建對象什麽的都交給Spring。核心便是這個

@Repository("ud")
public class UserDaoImp implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        System.out.println("userDao的set方法---");
        this.jdbcTemplate = jdbcTemplate;
    }
    @Override
    public void save() {
        String sql = "insert into bbb values(null,?)";
        jdbcTemplate.update(sql, "66666666");
    }
}

三、Spring事務管理

  正如標題所述,Spring會對事務做管理。但需要註意只是做管理,實際操作還是依據不同的框架的做法(不同的實現)。

  這裏不得不提,Spring其中的偉大之一在於AOP。那麽我們就可以利用它來對某部分功能加入事務的功能。而,當我們要利用Spring來進行事務管理的時候,正所謂人在屋檐下,不得不低頭。你用人家的,那也得遵守別人定下的規矩。

  Spring統一規定,要操作事務,必須使用管理員!

管理事務的規範是 : PlatformTransactionManager
    jdbc | mybatis : DataSourceTransactionManager
    hibernate : HibernateTransactionManager

  Spring對事務的支持,有三種寫法:編程式事務、xml聲明式事務、註解聲明式事務。

  這三種寫法中,最簡介的為註解式事務。以下列出三種寫法的實例,推薦後者。

  • 編程式事務 技術分享圖片
     1   @Test
     2       public void test(){
     3 
     4 
     5           //事務的管理員是用來管理事務的,包含了打開事務、 提交事務、 回滾事務
     6           final DriverManagerDataSource dataSource = new DriverManagerDataSource();
     7           dataSource.setDriverClassName("com.mysql.jdbc.Driver");
     8           dataSource.setUrl("jdbc:mysql:///stus");
     9           dataSource.setUsername("root");
    10           dataSource.setPassword("root");
    11 
    12 
    13           DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
    14           transactionManager.setDataSource(dataSource);
    15 
    16           //1. 創建事務的模板對象。
    17           TransactionTemplate transactionTemplate = new TransactionTemplate();
    18           transactionTemplate.setTransactionManager(transactionManager);
    19 
    20           //事務事務的模板對象
    21           transactionTemplate.execute( new TransactionCallback<Object>() {
    22 
    23               //在事務裏面執行這個方法。
    24               @Override
    25               public Object doInTransaction(TransactionStatus arg0) {
    26 
    27                   //添加操作
    28                   JdbcTemplate jdbcTemplate = new JdbcTemplate();
    29                   jdbcTemplate.setDataSource(dataSource);
    30 
    31                   String sql = "insert into  t_user values ( null , ? , ?)";
    32                   jdbcTemplate.update(sql, "123","王五");
    33 
    34                   int a = 1 / 0 ;
    35 
    36                   jdbcTemplate.update(sql, "6666","趙六");
    37 
    38                   return null;
    39               }
    40           });
    41 
    42       }
    編程式事務
  • xml聲明式事務
技術分享圖片
 1    <!-- 以下屬於事務的配置 如果要用事務了,那麽事務的管理員是誰啊。 -->
 2        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 3            <property name="dataSource" ref="dataSource"></property>
 4        </bean>
 5      
 6        <!-- 
 7            以上配置,到目前為止,只是說明了,如果要開啟事務,管理員是誰。 但是缺少了一個東西。
 8            就是哪一個方法到底要用事務呀? --> 
 9        <aop:config>
10            <aop:pointcut expression="execution(* com.gaga.service.impl.*.*(..))" id="aa"/>     
11            <aop:advisor advice-ref="advice01" pointcut-ref="aa"/>
12        </aop:config>
13 
14        <tx:advice id="advice01" transaction-manager="transactionManager">
15            <tx:attributes>  <!-- 對 id="aa"表達式找到的那一堆方法,進行過濾配置,表示誰才能用事務管理, 如果是* ,表示前面找到的那一堆都用事務管理 -->
16                <tx:method name="save*"/>
17                <tx:method name="update*"/>
18                <tx:method name="delete*"/>
19            </tx:attributes>
20        </tx:advice>
xml聲明式事務
  • 註解聲明式事務

    a)xml中的配置

<context:component-scan base-package="gaga"/>
    <aop:aspectj-autoproxy/>
1. 在xml中 聲明註解事務的管理員

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${driverClass}"/>
        <property name="jdbcUrl" value="${jdbcUrl}"/>
        <property name="user" value="${user}"/>
        <property name="password" value="${password}"/>
    </bean>
   <!-- 以下屬於事務的配置 如果要用事務了,那麽事務的管理員是誰啊。 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
           <property name="dataSource" ref="dataSource"></property>
       </bean>
       
       <!-- 指定註解事務使用的管理員是誰 -->
       <tx:annotation-driven transaction-manager="transactionManager"/>

    b) 代碼配置

2. 在業務邏輯類上或者方法上打註解

        類上的註解,表示類中的所有方法都用事務, 如果在方法上打註解,表示只有這個方法才會用事務
            @Transactional
            public class UserServiceImpl implements UserService {

            }
            public class UserServiceImpl implements UserService {
               // @Transactional
                @Override
                public void save() {
            }

Spring---AOP註解開發&jdbc模板&Spring事務管理