spring相关知识点3

spring_day03

spring整合JDBC:spring封装JDBC,spring这一对象容器中提供了一个可以操作数据库的对象,JDBC Template类似于DBUtils Template
1.导包(4个核心包+2个日志包+JDBC驱动包+数据库连接池c3p0+test包+aop包+spring JDBC包+spring-tx包)
2.数据库建表:准备连接池、创建JDBC模板对像(模板对象需要注入数据源)、调用SQL语句、插入表中 这里db.properties连接的是数据库而不是表
3.运用spring容器管理增删改查(注:这里测试采用高级版即注解形式,可以自动注入对象)
(这里有个有意思的现象:/spring_day03/src/cn/itcast/b_jdbctemplate/UserDaoImpl.java没有@Repository而且没有开启<component:scan.../>但是也能注入)(个人理解是因为在applicationContext.xml中配置了关于UserDaoImpl的bean,虽然没开启自动扫描,但是Test中需要UserDaoImpl类注入时会去spring容器中找对象,而不管这种对象是通过包扫描配置还是xml配置注册到spring容器中)
注意:关于2中创建模板对象有两种方式,
第一种UserDaoImpl仅实现接口,这时需要主动在UserDaoImpl中加上JdbcTemplate属性域,这时配置文件applicationContext.xml需考虑数据源注入到JdbcTemplate,然后将JdbcTemplate将注入到UserDaoImpl中,在Demo测试中操作UserDaoImpl对象进行增删改查,以JdbcTemplate的方法执行sql语句
第二种UserDaoImpl不仅实现接口还继承JdbcDaoSupport,JdbcDaoSupport中有JdbcTemplate属性域,有数据源的set方法,所以此时applicationContext.xml只需考虑数据源注入到userDaoImpl中,后面的事源代码了,但是有个疑惑,JdbcDaoSupport中的set方法怎么将数据源注入,没有注解,难道是配置文件注入吗?

二.事务特性:acid
//https://www.zhihu.com/question/31346392
事务隔离性并发:脏读、幻读、不可重复读
事务隔离级别:1、2、4、8 1:读未提交 2:读已提交 4:可重复读 8:串行化
spring封装了事务管理代码:打开事务、提交事务、回滚事务
在不同平台(JDBC、Hibernate、MyBatis)操作事务的代码各不相同,所以spring提供了一个接口(PlatformTransactionManager接口),针对不同平台,提供不同的实现类(JDBCTransactionManager、HibernateTransactionManager)
spring事务管理,核心就是TransactionManager
spring管理事务的属性介绍:事务的隔离级别、本次事务是否只读、事务的传播行为(如下)
PROPAGATION_REQUIRED:支持当前事务,如果不存在,就新建一个
PROPAGATION_SUPPORTS:支持当前事务,如果不存在,就不使用事务
PROPAGATION_HANDATORY:支持当前事务,如果不存在,抛出异常
PROPAGATION_REQUIRED_NEW:如果有事务存在,挂起当前事务,创建新的事务
PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER:以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED:如果当前事务存在,则嵌套执行(会开新事务)
这里测试采用extends JdbcDaoSupport的自带JdbcTemplate来测试
ad.decreaseMoney(from,money); int a=1/0; ad.addMoney(to,money);这样需要事务进行管理,以免原子性出错
spring管理事务常用的两种方式:编码式、aop的xml配置式(aop)、注解配置(aop)
后两种常用
编码式:

//public void transfer(final Integer from,final Integer to,final Double money)
@Override
public void transfer(Integer from, Integer to, Double money) {
    //模板已经封装好了打开关闭回滚,告诉模板干什么就行了
    tt.execute(new TransactionCallbackWithoutResult() {
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus arg0) {
            //减钱
            ad.decreaseMoney(from, money);

            //int a = 1/0;

            //加钱
            ad.addMoney(to, money);
        }
    });
    //execute方法:1.打开事务2.调用doInTransactionWithoutResult方法
    //3.提交事务  

xml配置式:

<!-- 事务核心管理器,封装了所有事务操作,依赖于连接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 注入:需要将dataSource注入到JDBCTemplate,将JDBCTemplate注入到UserDaoImpl,将UserDaoImpl注入到spring-->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/e3mall-32?characterEncoding=utf-8"></property>
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="user" value="anmi"></property>
<property name="password" value="anmi123"></property>
</bean>

<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 以方法为单位,指定方法应用什么事务属性
    isolation:隔离级别
    propagation:传播行为
 -->
    <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
    <tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
    <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
    <tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
    <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
    <tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
    <tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
    <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
    <tx:method name="transfer*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>

<!-- 配置织入 -->
<aop:config>
<aop:pointcut expression="execution(* cn.itcast.service.*ServiceImpl.*(..))" id="txPc"/>
<!-- 配置切面 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
</aop:config>

<bean name="accountDaoImpl" class="cn.itcast.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>

<bean name="accountServiceImpl" class="cn.itcast.service.AccountServiceImpl">
<property name="ad" ref="accountDaoImpl"></property>
</bean>  

注解式:(将配置事务通知和配置织入改为开启使用注解管理aop事务)

<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 注入:需要将dataSource注入到JDBCTemplate,将JDBCTemplate注入到UserDaoImpl,将UserDaoImpl注入到spring-->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/e3mall-32?characterEncoding=utf-8"></property>
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="user" value="anmi"></property>
<property name="password" value="anmi123"></property>
</bean>

<tx:annotation-driven/>

<bean name="accountDaoImpl" class="cn.itcast.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>

<bean name="accountServiceImpl" class="cn.itcast.service.AccountServiceImpl">
<property name="ad" ref="accountDaoImpl"></property>
</bean>  

加注解的代码:

//以下注解只在Demo2测试使用,可以直接加到该类上设置全局,此时若有局部属性差异可在局部设置
@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)
@Override
public void transfer(Integer from, Integer to, Double money) {
    //减钱
    ad.decreaseMoney(from, money);

    //int a = 1/0;

    //加钱
    ad.addMoney(to, money);
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值