11-26 程宗武

11-26 Spring04

1. JdbcTemplate 概述

是Spring中对原生的JDBC的简单封装,更加方便我们对数据库的操作

1.1 JdbcTemplate 在Spring中的使用

maven中的配置依赖和数据源 数据源有C3P0 、DBCP和Druid以及Spring内置的数据源,这里我们选择Druid

<!--这里导入依赖时自动把相关联的对事务进行操作的 spring-tx-5.0.2.RELEASE.jar包也导进来了-->
<dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-jdbc</artifactId>
     <version>5.0.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

在xml配置文件中配置数据源以及Spring的JDBC

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--加载数据库配置信息-->
    <context:property-placeholder location="db.properties"/>
    <!--扫描包-->
    <context:component-scan base-package="top.wutiaojian.spring"/>
    
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg index="0" ref="druid"></constructor-arg>
    </bean>
    <bean id="druid" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

JdbcTemplate 的基本使用

查询所有

    //查询所有
    //query方法的第一个参数为SQL语句,第二个参数为把数据库获取出来的参数转换为实体类的匿名内部类,第三个参数为与SQL语句占位符一一对应的参数。
    @Test
    public void findAll() {
        String sql = "select * from tb_account where money > ?";
        List<Account> list = jdbcTemplate.query(sql, new RowMapper<Account>() {
            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;
            }
        }, 200);
        for (Account a :
                list) {
            System.out.println(a);
        }
    }

查询一行一列

//返回一行一列
//queryForObject方法查询结果为一行一列的结果类型的方法,第二个参数为返回值的结果类型,第三个参数为占位符赋值
    @Test
    public void findRow() {
        String sql = "select count(*) from tb_account where money > ?";
        Integer integer = jdbcTemplate.queryForObject(sql, Integer.class, 200);
        System.out.println(integer);
    }

2.Spring中的事务控制

Spring的事务控制是基于AOP的,并且有利于我们在进行分层开发时,对业务层事务的处理

PlatformTransactionManager 接口是Spring的事务管理器,里面提供了我们常用的操作事务的一些方法,如获取事务状态信息,提交事务回滚事务等方法 我们一般使用的是它的实现类DataSourceTransactionManager等

2.1 事务中的一些概念

事务的传播行为

REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)
MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常
REQUERS_NEW: 新建事务,如果当前在事务中,把当前事务挂起。

是否是只读事务

只读型事务:从这个事务开始的时间点开始,其他事务对数据库做的改变,将不影响这个只读事务的查询结果,这个多用于保持查询结果的一致性。
读写型事务:

3.基于XML的方式实现事务的控制

3.1mavne依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>spring04</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/springcontext -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/springjdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/springaspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- 日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
    </dependencies>
</project>

3.2 spring.xml文件的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--加载数据库配置信息-->
    <context:property-placeholder location="db.properties"/>
    <!--扫描包-->
    <context:component-scan base-package="top.wutiaojian.spring"/>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg index="0" ref="druid"></constructor-arg>
    </bean>
    <bean id="druid" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg index="0" ref="druid"/>
    </bean>
    <!--配置事务的通知引用事务管理器-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" read-only="false" propagation="REQUIRED"/>
            <tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
        </tx:attributes>
    </tx:advice>
       <!--配置AOP切入点表达式-->
    <aop:config>
        <aop:pointcut id="pt" expression="execution(* top.wutiaojian.spring.service.impl.*.*(..))"/>
          <!--配置切入点和事务的关系-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
    </aop:config>
</beans>

<!--在 tx:advice 标签内部 配置事务的属性 -->
<!--<tx:attributes>-->
<!-- 指定方法名称:是业务核心方法
    read-only:是否是只读事务。默认 false,不只读。
    isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。
    propagation:指定事务的传播行为。
    timeout:指定超时时间。默认值为:-1。永不超时。
    rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异
    常,事务不回滚。
    没有默认值,任何异常都回滚。
    no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异
    常时,事务回
    滚。没有默认值,任何异常都回滚。
-->

测试

@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(locations = "classpath:spring.xml")
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceImplTest {

    @Resource
    private IAccountService service;

    @Test
    public void transfer() {
        service.transfer(2, 6, 1000F);//执行失败,回滚事务
    }
}

4.基于注解实现事务的控制

重要的有一下几个注解
首先要在配置类中开启注解事务控制
@EnableTransactionManagement
其次在要实现事务的方法或者类上写上
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)注解
如果是写在类上,则表示这个类中的所有方法都是用这个事务去执行的
如果写在接口上,则表示实现这个接口的所有类中的方法都是执行的这个事务
如果写在方法上,则表示这个方法是按照这个事务去执行的
优先级:方法>类>接口
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
类似于在xml中<tx:method name="*" read-only="false" propagation="REQUIRED"/>这个配置

评论