Spring-JDBCTemplate

Spring的JDBC的模板

  • Spring是EE开发的一站式的框架,有EE开发的每层的解决方案。
  • Spring对持久层也提供了解决方案:ORM模块和JDBC的模板。
  • Spring提供了很多的模板用于简化开发。
    • JDBC
      • org.springframework.jdbc.core.jdbc.jdbcTemplate
    • Hibernate
      • orm.springframework.orm.hibernamte.HibernateTemplate

JDBC模板使用的入门

  • 1.引入jar包
    • Spring开发基本Jar包
    • 数据库驱动
    • Spring的JDBC模板的jar包

  • 2.创建数据库和表
create table account(
	id int primary key auto_increment,
	name varchar(20),
	money double
);
  • 3.使用JDBC的模板

@Test
public void test1(){
    // 1.创建连接池(数据库相关信息)
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false");
    dataSource.setUsername("root");
    dataSource.setPassword("1234");

    // 2.创建JDBC模板
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    jdbcTemplate.update("INSERT INTO account VALUES (null,?,?)","XhhBlog",100d);
}

将连接池和模板交给Spring管理

创建 application.xml

配置文件配置Bean

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT%2B8&amp;useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="1234"/>
    </bean>

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

</beans>

使用jdbcTemplate注解插入数据

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class SpringJDBCTest2 {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test(){
        jdbcTemplate.update("INSERT INTO account VALUES (null,?,?)","Xhh",1000D);
    }

}

使用开源连接池

DBCP

引入jar包

配置DBCP连接池

C3P0

引入jar包

c3p0配置数据库连接属性有点不一样

DRUID

引入jar包

配置

使用属性文件配置数据库连接信息

创建属性文件

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
jdbc.username=root
jdbc.password=1234

配置文件中引入属性文件

<bean>

<context/>

JDBC模板CRUD操作

我这里只粘代码,没有粘截图,自己看代码模板的语句即可。

插入操作

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class SpringJDBCTest2 {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test(){
        jdbcTemplate.update("INSERT INTO account VALUES (null,?,?)","Xhh",2000D);
    }

}

删除操作

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class SpringJDBCTest2 {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test(){
        jdbcTemplate.update("DELETE FROM account WHERE id = ?",13);
    }

}

更新操作

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class SpringJDBCTest2 {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test() {
        jdbcTemplate.update("UPDATE account SET name = ?,money = ? WHERE id = ?", "小灰灰", 2000D, 12);
    }

}

查询操作

查询某一个字段

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class SpringJDBCTest2 {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test() {
        // String.class 查询结果的类型
        String name = jdbcTemplate.queryForObject("SELECT name FROM account WHERE id = ?", String.class, 12);
        System.out.println(name);
    }

}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class SpringJDBCTest2 {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test() {
        // Long.class 查询结果的类型
        Long count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM account", Long.class);
        System.out.println(count);
    }

}

查询多条返回对象的集合

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class SpringJDBCTest2 {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test() {
        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 i) throws SQLException {
        Account account = new Account();
        account.setId(rs.getInt("id"));
        account.setName(rs.getString("name"));
        account.setMoney(rs.getDouble("money"));

        return account;
    }
}
public class Account {
    private Integer id;
    private String name;
    private Double money;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

查询单条

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class SpringJDBCTest2 {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Test
    public void test() {
        Account account = jdbcTemplate.queryForObject("SELECT * FROM account WHERE id = ?", new MyRowMapper(), 12);

        System.out.println(account);
    }

}


class MyRowMapper implements RowMapper<Account> {

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

        return account;
    }
}

事务

事务概述

什么是事务

逻辑上的一组操作,组成这组操作的各个单元,要么全都成功,要么全都失败。

事务的特性

原子性:事务不可分割
一致性:事务执行前后数据完整性保持一致
隔离性:一个事务的执行不应该受到其他事务的干扰
持久性:一旦事务结束,数据就持久化到数据库

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

读问题

脏读		:一个事务读到另一个事务未提交的数据。
不可重复读	:一个事务读到另一个事务已经提交的update的数据,导致一个事务中多次查询结果不一致。
虚读、幻读	:一个事务读到另一个事务已经提交的insert的数据,导致一个事务中多次查询结果不一致。

写问题

  • 丢失更新

解决读问题

设置事务的隔离级别

Read uncommitted	:未提交读,任何读问题解决不了。
Read committed	        :已提交读,解决脏读,但是不可重复读和虚读有可能发生。
Repeatable read	        :重复读,解决脏读和不可重复读,但是虚读有可能发生。
Serializable		:解决所有读问题。

Spring的事务管理的API

PlatformTransactionManager

PlatformTransactionManage: 平台事务管理器 是一个接口,下面有两个实现类

  • DataSourceTransactionManager:底层使用JDBC管理事务
  • HibernateTransactionManager:底层使用Hibernate管理事务

TransactionDefinition

  • 事务定义信息: 用于定义事务的相关的信息,隔离级别、超时信息、传播行为、是否只读。

TransactionStatus

  • 事务状态:用于记录在事务管理过程中,事务的状态的对象。

事务管理的API的关系

  • Spring进行事务管理的时候,首先平台事务管理器根据事务定义信息进行事务的管理。
  • 在事务管理过程中,产生各种状态,将这些状态的信息记录到事务状态的对象中。

Spring的事务的传播行为

什么是传播行为

一个业务方法当中,调用另一个业务的方法。

Spring中提供了七种事务的传播行为

保证多个操作在同一个事务中

PROPAGATION_REQUIRED 默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来
PROPAGATION_SUPPORTS 支持事务,如果A中有事务,使用A中的事务。如果A没有事务,不使用事务。
PROPAGATION_MANDATORY 如果A中有事务,使用A中的事务。如果A没有事务,抛出异常。

保证多个操作不在同一个事务中

PROPAGATION_REQUIRES_NEW 如果A中有事务,将A的事务挂起(暂停),创建新事务,只包含自身操作。如果A中没有事务,创建一个新事务,包含自身操作。
PROPAGATION_NOT_SUPPORTED 如果A中有事务,将A的事务挂起。不使用事务管理。
PROPAGATION_NEVER 如果A中有事务,报异常。

嵌套式事务

PROPAGATION_NESTED

  • 嵌套事务,如果A中有事务,按照A的事务执行,执行完成后,设置一个保存点。
  • 执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始位置,也可以回滚到保存点。

Spring事务管理

1.搭建Spring事务管理环境

创建AoccuntDao

public interface AccountDao {
    public void OutMoney(String from,Double money);
    public void InMoney(String to,Double money);
}

实现Dao接口

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    @Override
    public void OutMoney(String from, Double money) {
        this.getJdbcTemplate().update("update account set money=money-? where name =?",money,from);
    }

    @Override
    public void InMoney(String to, Double money) {
        this.getJdbcTemplate().update("update account set money= money+? where name=?",money,to);
    }
}

把Dao交给Spring管理

在Dao中注入数据源

在DAO当中注入jdbc模板,要保证dao继承了JdbcDaoSupport

继承之后, 就有了datasource的set方法,就可以注入了

Dao继承JdbcDaoSupport

DAO注入JDBC模板

创建Account业务

public interface AccountService {

    public void transferMoney(String from,String to, Double money);

}
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public void transferMoney(String from, String to, Double money) {
        accountDao.InMoney(to, money);
        accountDao.OutMoney(from, money);
    }
}

配置service 交给spring 并注入dao

测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class SpringJDBCTest2 {

    @Resource
    private AccountService accountService;

    @Test
    public void test() {
        accountService.transferMoney("XhhBlog","小灰灰",100D);
    }

}

2.添加事务

编程式事务

需要手动编写代码

配置平台事务管理器

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

Spring提供了事务管理的模板类

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

在业务层注入事务管理的模板

编写事务管理的代码

声明式事务

XML方式声明事务管理

引入aop的开发包

配置事务管理器

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

AOP的配置

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

配置

<aop:config>
    <aop:pointcut id="pointcut1" expression="execution(* com.qc.demo1.service.AccountServiceImpl.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>

注解方式声明事务管理

配置事务管理器

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

开启注解事务

<!--配置增强-->
<tx:annotation-driven transaction-manager="transactionManager"/>

在业务层添加注解

@Transactional

posted @ 2020-02-11 16:20  Leader_TBlog  阅读(119)  评论(0)    收藏  举报