spring学习笔记(三)

spring jdbc

spring tx

 

1、spring的jdbc模板

 

Spring提供了很多持久层技术的模板类简化编程:

 

 

 1.1、jdbc模板的基本使用

@Test
    // JDBC模板的基本使用:
    public void demo1(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///spring_day03");
        dataSource.setUsername("root");
        dataSource.setPassword("123");
        
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.update("insert into account values (null,?,?)", "会希",10000d);
    }

 

 

 

2、spring整合连接池

【配置内置连接池】

   <!-- 配置Spring的内置连接池 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///spring_day02"/>
        <property name="username" value="root"/>
        <property name="password" value="123"/>
    </bean>

 

 

【将模板配置到Spring中】

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

【编写测试类】

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo2 {
    
    @Resource(name="jdbcTemplate")
    private JdbcTemplate jdbcTemplate;
    
    @Test
    public void demo1(){
        jdbcTemplate.update("insert into account values (null,?,?)", "凤姐",10000d);
    }

}

 

2.1、  Spring中配置DBCP连接池:

【引入dbcp连接池的jar包】

【配置连接池】

   <!-- 配置DBCP连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///spring_day02"/>
        <property name="username" value="root"/>
        <property name="password" value="123"/>
    </bean>

 

 2.2、配置c3p0连接池:

 

【引入相应的jar包】

com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

 

【配置连接池】

 

   <!-- 配置C3P0连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///spring_day02"/>
        <property name="user" value="root"/>
        <property name="password" value="123"/>
    </bean>

 

 3、JDBC模板的CRUD的操作

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo3 {

    @Resource(name="jdbcTemplate")
    private JdbcTemplate jdbcTemplate;
    
    @Test
    // 插入操作
    public void demo1(){
        jdbcTemplate.update("insert into account values (null,?,?)", "冠希",10000d);
    }
    
    @Test
    // 修改操作
    public void demo2(){
        jdbcTemplate.update("update account set name=?,money =? where id = ?", "思雨",10000d,5);
    }
    
    @Test
    // 删除操作
    public void demo3(){
        jdbcTemplate.update("delete from account where id = ?", 5);
    }
    
    @Test
    // 查询一条记录
    public void demo4(){
        Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new MyRowMapper(), 1);
        System.out.println(account);
    }
    
    @Test
    // 查询所有记录
    public void demo5(){
        List<Account> list = jdbcTemplate.query("select * from account", new MyRowMapper());
        for (Account account : list) {
            System.out.println(account);
        }
    }
    
    class MyRowMapper implements RowMapper<Account>{

        @Override
        public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
            Account account = new Account();
            account.setId(rs.getInt("id"));
            account.setName(rs.getString("name"));
            account.setMoney(rs.getDouble("money"));
            return account;
        }
        
    }
}

 

4、事务

事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败.

 

4.1、 事务特性:

原子性    :强调事务的不可分割.

一致性    :事务的执行的前后数据的完整性保持一致.

隔离性    :一个事务执行的过程中,不应该受到其他事务的干扰

持久性    :事务一旦结束,数据就持久到数据库

4.2、如果不考虑隔离性引发安全性问题:

脏读              :一个事务读到了另一个事务的未提交的数据

不可重复读    :一个事务读到了另一个事务已经提交的update的数据导致多次查询结果不一致.

虚读              :一个事务读到了另一个事务已经提交的insert的数据导致多次查询结果不一致.

4.3、 解决读问题:设置事务隔离级别

未提交读       :脏读,不可重复读,虚读都有可能发生

已提交读       :避免脏读。但是不可重复读和虚读有可能发生

可重复读       :避免脏读和不可重复读.但是虚读有可能发生.

串行化的       :避免以上所有读问题.

 

5、Spring进行事务管理API

5.1、  PlatformTransactionManager:平台事务管理器.

***** 真正管理事务的对象

org.springframework.jdbc.datasource.DataSourceTransactionManager   使用Spring JDBCiBatis 进行持久化数据时使用

org.springframework.orm.hibernate3.HibernateTransactionManager     使用Hibernate版本进行持久化数据时使用

 

5.2、TransactionDefinition:事务定义信息

事务定义信息:

* 隔离级别

* 传播行为

* 超时信息

* 是否只读

5.2.1、TransactionStatus:事务的状态

 

记录事务的状态

Spring的这组接口是如何进行事务管理:

平台事务管理根据事务定义的信息进行事务的管理,事务管理的过程中产生一些状态,将这些状态记录到TransactionStatus里面

 

5.2.3、事务的传播行为

PROPAGION_XXX       :事务的传播行为

     * 保证同一个事务中

  PROPAGATION_REQUIRED     支持当前事务,如果不存在 就新建一个(默认)

  PROPAGATION_SUPPORTS    支持当前事务,如果不存在,就不使用事务

  PROPAGATION_MANDATORY   支持当前事务,如果不存在,抛出异常

 

  * 保证没有在同一个事务中

  PROPAGATION_REQUIRES_NEW    如果有事务存在,挂起当前事务,创建一个新的事务

  PROPAGATION_NOT_SUPPORTED   以非事务方式运行,如果有事务存在,挂起当前事务

  PROPAGATION_NEVER   以非事务方式运行,如果有事务存在,抛出异常

 

  PROPAGATION_NESTED  如果当前事务存在,则嵌套事务执行

 

5.3、Spring的编程式事务(了解)

 

5.3.1、配置事务管理器

 <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
    </bean>

 

5.3.2、配置事务管理器的模板

   <!-- 配置事务管理模板 -->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>

 

5.3.3、需要在业务层注入事务管理模板

    <!-- 配置业务层的类 -->
    <bean id="accountService" class="cn.xxxxx.transaction.demo1.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <!-- 注入事务管理模板 -->
        <property name="transactionTemplate" ref="transactionTemplate"/>
    </bean>

 

5.3.4、手动编写代码实现事务管理

public void transfer(final String from, final String to, final Double money) {
        
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                accountDao.outMoney(from, money);
                int d = 1 / 0;
                accountDao.inMoney(to, money);
                
            }
        });
        
        
    }

 

5.4、Spring的声明式事务管理XML方式(*****):

思想就是AOP.

不需要进行手动编写代码,通过一段配置完成事务管理

aop联盟.jar

Spring-aop.jar

aspectJ.jar

spring-aspects.jar

 

5.4.1、配置事务管理器

   <!-- 事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

 

5.4.2、 配置事务的通知

  <!-- 配置事务的增强 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
          <!-- 
                isolation="DEFAULT"        隔离级别
                propagation="REQUIRED"    传播行为
                read-only="false"    只读
                timeout="-1"        过期时间
                rollback-for=""        -Exception
                no-rollback-for=""    +Exception
             -->
            <tx:method name="transfer" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

 

5.4.3、 配置aop事务

 <aop:config>
        <aop:pointcut expression="execution(* cn.xxxxx.transaction.demo2.AccountServiceImpl.transfer(..))" id="pointcut1"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
    </aop:config>

 

5.5、Spring的声明式事务的注解方式: (*****)

 

5.5.1、  配置事务管理器:

<!-- 配置事务管理器 -->
     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <property name="dataSource" ref="dataSource"/>
     </bean>

 

5.5.2、   开启事务管理的注解:

<!-- 开启注解事务管理 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

 

5.5.3、 在使用事务的类上添加一个注解:@Transactional

 

posted @ 2018-10-17 21:12  木子木泗  阅读(305)  评论(0编辑  收藏  举报