spring第四章-AOP

spring第四章-AOP

一、目标

1、jdbcTemplate的使用

2、spring的事务控制

3、了解spring5的新特性

二、jdbcTemplate的使用
1、jdbcTemplate的介绍
jdbc --- dbutils -- jdbcTemplate(spring 提供) -- mybatis(主流) -- spring data jpa(趋势)
2、数据源配置
a. c3p0数据源
		<!--c3p0数据源-->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
	 <!--引入外部属性文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--配置c3p0数据源-->
    <bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
b. dbcp 数据源
	<!--dbcp数据源-->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
		<!--dbcp数据源-->
    <bean id="dbcpDataSource"  class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
c. spring jdbc 自带数据源,包含了JdbcTemplate对象
	<!--spring自带数据源-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
 <!--spring自带的数据源-->
    <bean id="springDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
3、jdbcTemplate的CRUD
package com.sgw;

import com.sgw.domain.Account;
import com.sgw.mapper.AccountRowMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

/**
 * 查询使用query
 * 增删改:update
 *
 * queryForList :查询返回一个List集合,Map集合
 * query(sql ,属性与列的映射对象,参数):返回值:List<pojo>
 * queryForObject :针对于返回一个对象
 * update(sql ,参数):执行增删改操作
 *
 * @author 
 * @Company http://www.sgw.com
 * @Version 1.0
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestJdbcTemplate {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Test
    public void testFindAll(){
        String sql = "select * from account";
//        方法返回值是List集合,list中是map、集合
//        List<Map<String, Object>> accountList = jdbcTemplate.queryForList(sql);
//        for (Map<String, Object> map : accountList) {
//            System.out.println(map);
//        }
        List<Account> accountList = jdbcTemplate.query(sql, new AccountRowMapper());
        for (Account account : accountList) {
            System.out.println(account);
        }

    }

    @Test
    public void testFindById(){
        String sql = "select * from account where id = ?";
//        List<Account> accountList = jdbcTemplate.query(sql, new AccountRowMapper(), 5);
//        System.out.println(accountList.size() == 1 ?accountList.get(0):"结果为null");
//        queryForObject(SQL语句,列与属性的映射, 参数):掌握
        Account account = jdbcTemplate.queryForObject(sql, new AccountRowMapper(), 5);
        System.out.println(account);
//        queryForObject(sql语句,参数列表(必须是数组类型), jdbcTemplate 自带映射:必须保证属性和列名一致)
//        Account account = jdbcTemplate.queryForObject(sql, new Object[]{1}, new BeanPropertyRowMapper<>(Account.class));
//        System.out.println(account);

    }

    @Test
    public void testSave(){
        String sql = "insert into account values(null , ? ,?)";
        jdbcTemplate.update(sql ,"zhangsan", 10000);
    }

    @Test
    public void testUpdate(){
        String sql = "update account set money = ?, name = ? where id = ?";
        jdbcTemplate.update(sql ,1000,"lisi",4);
    }

    @Test
    public void testDel(){
        String sql = "delete from account where id = ?";
        jdbcTemplate.update(sql , 4);
    }

    @Test
    public void testGetTotalCount(){
        String sql = "select count(*) from account";
//        queryForObject(sql语句, 返回值类型)
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
        System.out.println(count);
    }
}

4、在dao中使用jdbcTemplate方法一
a. applicationContext.xml
		<!--创建jdbcTemplate模板对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="springDataSource"></property>
    </bean>
b.在dao层中使用模板对象
@Repository
public class AccountDaoImpl implements AccountDao {

	  //自动注入模板对象
    @Autowired
    JdbcTemplate  jdbcTemplate;
    
}
5、在dao中使用jdbcTemplate方法二
a. 在dao实现类中继承接口JdbcDaoSupport类
	public class AccountDaoImpl2 extends JdbcDaoSupport implements AccountDao {
b.所有的dao对象需要在xml中创建,需要通过set方法注入数据源对象
		<!--创建dao层对象-->
    <bean id="accountDao" class="com.sgw.dao.impl.AccountDaoImpl2">
        <!--通过set方法注入数据源-->
        <property name="dataSource" ref="springDataSource"></property>
    </bean>
三、spring的事务控制
1、spring事务控制的api介绍–事务管理类
org.springframework.orm.hibernate5.HibernateTransactionManager: 在hibernate环境下使用
rg.springframework.jdbc.datasource.DataSourceTransactionManager: 在jdbcTemplate,mybatis(ibatis)环境下使用
2、事务的特性
a、事务的四个特性
	原子性: 不可再分割
	隔离性: 事务之间的隔离级别
	一致性: 要么全部完成,要么全部不完成
	持久性: 一旦提交持久化到数据中
b、隔离级别
	读未提交:read uncommited
		产生的问题:脏读,幻读,不可重复读
		脏读:读到了未提交的数据
		不可重复读:
		幻读(虚读):
	读已提交:read commited
		产生的问题:幻读,不可重复读
		解决的问题:脏读
	重复读:  repeatable read
		产生的问题:幻读
		解决的问题:脏读,不可重复读
	串行化(序列化): serializable 
		产生的问题:null
		解决的问题: 所有的问题
		隔离级别最高,效率最低
c、数据库的支持的隔离级别 -- 一般情况下选择都是默认的隔离级别
	mysql:支持:read uncommited  read commited  repeatable read  serializable  支持三个隔离级别
	默认的隔离级别:repeatable read
	Oracle支持:read commited   serializable   read only(只读)
	默认的隔离级别:read commited 

3、事务的传播
a. 掌握
REQUIRED: 必要的: 如果没有事务,则新建一个事务,如果有事务,加入这个事务当中, spring指定为默认值
	增删改:
SUPPORTS: 支持的: 如果没有事务,非事务执行,如果有事务,加入这个事务当中
	查询
b. 了解
MANDATORY: 可以使用当前的事务,如果没有事务,抛出异常
REQUERS_NEW: 新建一个事务,如果存在事务,则挂起事务
NOT_SUPPORTED: 必须非事务执行,如果有事务,则挂起事务
NEVER: 非事务执行,如果存在事务,抛出异常
NESTED: 有事务,嵌套执行,没有事务,执行REQUIRED
4、是否为只读的事务
a.如果是查询,则为只读的事务  readOnly=true
b.如果是增删改,则为非只读的事务,readOnly=false=
5、基于xml声明式事务管理(配置文件)(重点)(推荐)
a. 编程式事务管理:在业务层写了事务技术代码
b. 声明式事务管理:在配置文件声明事务对象,管理事务,业务层中没有任何事务代码
1) 引入依赖:
			<!--aop的切面配置需要的jar包-->
      <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.9</version>
      </dependency>
      <!--spring 的事务管理jar包-->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.0.2.RELEASE</version>
      </dependency>
      <!--spring 的基础包-->
			<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
      <!--spring自带数据源, 包含了事务管理类 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--两个测试包 -->
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
 2) 编写配置文件
 <!--创建事务管理器对象-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源属性:事务存在连接中- 连接存在连接池(数据源)中-->
        <property name="dataSource" ref="springDataSource"></property>
    </bean>

    <!--事务的增强: 过滤方法是否需要拦截
        id:唯一的标识
        transaction-manager:指定事务管理器
    -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <!--增强:方法的过滤-->
        <tx:attributes>
            <!--指定需要拦截的方法
            isolation:隔离级别, 一般选择默认的
            propagation:传播的行为,
            read-only: 是否为只读的事务,增删改:非只读事务 read-only=false
                                        查询:只读的事务:read-only=true


            find* :通配符配置,只要以 find开头即可
            -->
         <!--配置方式一:-->
            <!--增删改-->
            <!--<tx:method name="insert*" />-->
            <!--<tx:method name="add*" />-->
            <!--<tx:method name="update*" />-->
            <!--<tx:method name="del*" />-->
            <!--<tx:method name="delete*" />-->
            <!--<tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false" timeout="-1"/>-->
            <!--查询-->
            <!--<tx:method name="find*"  propagation="SUPPORTS" read-only="true" ></tx:method>-->
            <!--<tx:method name="select*" propagation="SUPPORTS" read-only="true" ></tx:method>-->
            <!--<tx:method name="query*" propagation="SUPPORTS" read-only="true"></tx:method>-->
            <!--<tx:method name="get*" isolation="DEFAULT" propagation="SUPPORTS" read-only="true" timeout="-1"></tx:method>-->
       <!--配置方式二-->
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="select*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="query*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"></tx:method>
            <!--其他方法的配置方法-->
            <tx:method name="*" propagation="REQUIRED" read-only="false"></tx:method>
        </tx:attributes>
    </tx:advice>
    <!--aop的配置:
        切面= 切入点 +通知(增强)
        -->
    <aop:config>
        <!--切面配置
            advice-ref: 通知关联对象
            pointcut: 切入点:
          -->
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.sgw.service.impl.*.*(..))"></aop:advisor>
    </aop:config>
 3) 业务层
 	业务层不需要任何事务管理,只需要提供业务代码即可
6、基于注解的配置(重点)
a. 引入依赖
	与xml完全一致
b. 配置文件
	1)配置事务管理类
	 <!--创建事务管理器对象-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源属性:事务存在连接中- 连接存在连接池(数据源)中-->
        <property name="dataSource" ref="springDataSource"></property>
    </bean>
  2) 开启事务的注解管理
  	<!--transaction-manager: 关联事务管理器对象-->
    <tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>

    <!--开启aop的注解:自动代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
 c. 业务层
 	在类上标记注解:@Transactional, 类中所有的方法都会使用事务管理
 	在方法上标记注解:@Transactional:只有该方法按照事务执行
 d.属性介绍
 @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, readOnly = false,timeout = -1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值