spring 03之JDBC模版与声明式事务

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/yjy91913/article/details/76473825

JDBC模版:

和数据库交换(类似于DBUtils)★
spring是一个一栈式框架,提供了dao层支持
1.jdbc模版
2.orm模块

入门案例:转账账户的添加

整合dbcp

步骤:
  1.导入jar (2个jar包 dbcp+pool) 可以在依赖包找 org.apache.commons
  2.配置dbcp数据源 BasicDataSource

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql:///s04_62"/>
    <property name="username" value="root"/>
    <property name="password" value="1234"/>
</bean>

★整合c3p0

步骤:
  1.导入jar包(1个或2个) 可以在依赖包找 com.mchange.c3p0
  2.配置c3p0数据源

  将数据库的4个参数抽取成属性文件(properties)
  在项目src目录下 创建一个jdbc.properties
  在spring配置文件中 需要加载解析属性文件

<!-- 配置c3p0 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

加载属性文件两种方式
  方式1:通过bean标签(不太用)

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <!-- 指定属性文件位置 -->
    <property name="location" value="classpath:jdbc.properties"/>
 </bean>

★方式2:通过context标签

<context:property-placeholder location="classpath:jdbc.properties"/>

3.属性注入,编写类
配置文件

<!-- 管理jdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>


    <bean id="accoundDao" class="com.xx.a_hello.AccountDao">
        <!-- 注入jdbc模版 -->
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>

Dao类

private JdbcTemplate jdbcTemplate;
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }


    public void save(String name,int money){
        jdbcTemplate.update("insert into account values(null,?,?)",name,money);
    }

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext1.xml")
public class TestJdbc {

    @Autowired
    private AccountDao1 accountDao;

    @Test
    public void save(){
        accountDao.save("阿童木", 1000);
    }

★jdbc模版的api(类似DBUtils)

cud操作:
  update(String sql,Object … args)

query操作:
  T queryForObejct(String sql,Class clazz,Object … args):返回的一行一列的值 聚合函数
  T queryForObejct(String sql,RowMapper rowmapper,Object … args):返回的一行多列的值 一条记录
  List query(String sql,RowMapper rowmapper,Object … args):返回的多行多列的值 多条记录(list)

  RowMapper是一个接口,需要我们自己创建实现类,将记录封装长指定的对象(类似于ResultSetHandler)

class MyRowMapper implements RowMapper<Account>{

    @Override
    /**
     * ResultSet:结果集 每行记录
     * index:索引
     */
    public Account mapRow(ResultSet rs, int index) throws SQLException {
        //创建account对象
        Account account = new Account();

        //获取每个字段值 给对象set进去 
        account.setId(rs.getInt("id"));
        account.setName(rs.getString("name"));
        account.setMoney(rs.getInt("money"));

        return account;
    }

通过刚才的案例,我们需要在配置文件中声明一个jdbc模版,在dao中需要提供jdbc模版属性(set),还需要在配置文件中给dao注入jdbc模版.
但是后面会有很多个dao,每个dao都需要需要提供jdbc模版属性(set),还需要在配置文件中给dao注入jdbc模版.

spring就提供了一个JdbcDaoSupport,我们可以让所有的dao继承JdbcDaoSupport,这个类中就已经提供好了模版的set和get方法
还提供一个方法 setDataSource,我们如果给dao注入一个DataSource的话,里面会帮我们将jdbc模版创建出来.
这样的话就不需要在配置文件中声明jdbc模版

结论:
若我们使用的xml方式配置文件做的,我们就可以让所有的dao继承JdbcDaoSupport,在配置文件中给dao注入数据源即可.
若我们使用的注解方式就不能用以上方法.因为我们自己编写dao中没有dataSource属性,就不能在属性添加@AutoWired.但是可以使用声明jdbc模版,给dao注入模版()

声明式事务(通过配置给service层添加事务)

事务特性:acid
 若不考虑隔离性会产生那些读问题
 通过设置隔离级别解决上面的读问题
   read uncommitted
   read committed
   repeatable read
   serializable
 事务加载service层.

spring中的事务控制

步骤:
 搭建转账环境
 1.新建web项目
   导入jar包 14个+c3p0
 2.提供一个accountservice,里面提供一个转账方法
 3.提供一个accountDao,里面需要提供两个方法,加钱和减钱方法
 4.将所有的bean交给spring管理
 5.创建一个测试类,测试service.

spring中事务的api

PlatformTransactionManager:平台事务管理器 接口
★两个实现类:
  DataSourceTransactionManager: 若dao层使用的jdbc和mybatis 就使用这个
  HibernateTransactionManager: 若dao层使用的hibernate 就使用这个

TransactionDifinition:事务定义对象
 指定事务的规则:
  隔离级别
  传播行为:常用值 REQUIRED和SUPPORTS 见excel说明
  是否只读(默认值:false,只有在做查询的时候才设置为true,效率高)
  超时信息(若值为-1:永不超时)

TransactionStatus:事务状态对象

★总结一句话:

  spring执行事务的时候,先通过TransactionDifinition定义事务的规则,通过PlatformTransactionManager执行事务,执行的过程中会产生一些信息,这些信息最终保存在TransactionStatus对象中

大前提:

都需要声明事务管理器(需要注入datasource).

<!-- 声明事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入数据源 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>

★使用xml方式控制事务

1.配置通知类(spring已经提供好了,我们需要指定规则)

<!-- 配置通知类:执行事务的规则 -->
<tx:advice transaction-manager="transactionManager" id="tx_advice">
    <tx:attributes>
        <!-- 开发中的格式:
        <tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" timeout="-1" read-only="false"/>
        <tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED"/>
        <tx:method name="delete*"/>
        <tx:method name="find*" isolation="DEFAULT" propagation="SUPPORTS" read-only="true"/>
        <tx:method name="get*" isolation="DEFAULT" propagation="SUPPORTS" read-only="true"/>
         -->
         <!--我们案例的配置-->
        <tx:method name="account" isolation="DEFAULT" propagation="REQUIRED" timeout="-1" read-only="false"/>
    </tx:attributes>
</tx:advice>

2.aop配置

<aop:config>
    <!-- 定义切入点 -->
    <!-- 
        实际开发中配置
    <aop:pointcut expression="execution(* com.xx.service..*.*(..))" id="pt1"/>
     -->

    <aop:pointcut expression="execution(* com.xx.b_xml.AccountService.*(..))" id="pt1"/>

    <!-- 配置切面  -->
    <aop:advisor advice-ref="tx_advice" pointcut-ref="pt1"/>
</aop:config>

★使用xml和注解混合方式控制事务

开发中一般
  将bean的创建和注入交给spring管理
  配置数据源,事务管理器,jdbc模版
在配置文件中
  开启组件扫描

<!-- 开启组件扫描  -->
    <context:component-scan base-package="com.xx.c_xml_anno"/>

  开启事务注解支持

<tx:annotation-driven transaction-manager="transactionManager"/>

在service上添加注解
@Transactional

(了解)使用纯注解方式控制事务

基本没用过,只是了解下有这种方式
步骤:
  加载属性文件
  配置数据源
  声明事务管理器
  声明jdbc模版
  开启组件扫描
  开启事务注解支持 @EnableTransactionManagement
若上面的配置都可以通过注解来做,那么配置文件就可以删除了

SpringConfig 类

@Configuration
@ComponentScan(value="com.xx")
@PropertySource("classpath:jdbc.properties")
@Import(JdbcConfig.class)
@EnableTransactionManagement
public class SpringConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer createPropertySourcesPlaceholderConfigurer(){
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean(name="jdbcTemplate")
    /**
     * @Qualifier("dataSource") 用来注入参数的
     */
    public JdbcTemplate createJdbcTemplate(@Qualifier("dataSource") DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }

    @Bean(name="transactionManager")
    public PlatformTransactionManager createPlatformTransactionManager(@Qualifier("dataSource") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }

JdbcConfig 类

@Configuration
public class JdbcConfig {
    @Value("${jdbc.driverClass}")
    private String driverClass;
    @Value("${jdbc.jdbcUrl}")
    private String jdbcUrl;
    @Value("${jdbc.user}")
    private String user;
    @Value("${jdbc.password}")
    private String password;


    @Bean(name="dataSource")
    public DataSource createDataSource(){
        ComboPooledDataSource ds = new ComboPooledDataSource();
        try {
            ds.setDriverClass(driverClass);
            ds.setJdbcUrl(jdbcUrl);
            ds.setUser(user);
            ds.setPassword(password);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        return ds;
    }

猜你喜欢

转载自blog.csdn.net/yjy91913/article/details/76473825