Spring5(二)JdbcTemplate和事务

JdbcTemplate

JdbcTemplate(概念和准备)

1.什么是JdbcTemplate?
Spring框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库操作。
2. 准备工作
(1)引入相关jar包
在这里插入图片描述
(2)在Spring配置文件配置数据库连接池

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
    <property name="url" value="jdbc:mysql:///user_db" />
    <property name="username" value="root" />
    <property name="password" value="123456" />
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

(3)配置 JdbcTemplate 对象,注入 DataSource

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

(4)创建 service 类,创建 dao 类,在 dao 注入 jdbcTemplate 对象
配置文件开启组件扫描
Service

@Service
public class BookService {
    
    
    @Autowired
    private BookDao bookDao;
}

Dao

@Repository
public class BookDaoImpl implements BookDao {
    
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
}

JdbcTemplate操作数据库(添加)

1.对应数据库创建实体类

package com.yxm.entity;

public class Book {
    
    
    private String userId;
    private String username;
    private String ustatus;

    public String getUserId() {
    
    
        return userId;
    }

    public void setUserId(String userId) {
    
    
        this.userId = userId;
    }

    public String getUsername() {
    
    
        return username;
    }

    public void setUsername(String username) {
    
    
        this.username = username;
    }

    public String getUstatus() {
    
    
        return ustatus;
    }

    public void setUstatus(String ustatus) {
    
    
        this.ustatus = ustatus;
    }
}

2.编写Service和Dao
(1)在dao进行数据库添加操作
(2)调用JdbcTemplate对象里面的update方法实现实现添加操作
在这里插入图片描述
有两个参数
⚫ 第一个参数:sql 语句
⚫ 第二个参数:可变参数,设置 sql 语句值

@Repository
public class BookDaoImpl implements BookDao {
    
    

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void add(Book book) {
    
    
        String sql="insert into t_book values(?,?,?)";
        int update = jdbcTemplate.update(sql, book.getUserId(), book.getUsername(), book.getUstatus());
        System.out.println(update);
    }
}

3.测试类

    @Test
    public void testJdbcTemplate(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        BookService bookService = context.getBean("bookService", BookService.class);
        Book book = new Book();
        book.setUserId("1");
        book.setUsername("java");
        book.setUstatus("a");
        bookService.addBook(book);
    }

在这里插入图片描述

JdbcTemplate 操作数据库(修改和删除)

修改

    @Override
    public void updateBook(Book book) {
    
    
        String sql="update t_book set username=?,ustatus=? where user_id=?";
        int update = jdbcTemplate.update(sql, book.getUsername(), book.getUstatus(), book.getUserId());
        System.out.println(update);
    }

测试类

    @Test
    public void testJdbcTemplate2(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        BookService bookService = context.getBean("bookService", BookService.class);
        Book book = new Book();
        book.setUserId("1");
        book.setUsername("js");
        book.setUstatus("b");
        bookService.updateBook(book);
    }

删除

    @Override
    public void deleteBook(String userId) {
    
    
        String sql="delete from t_book where user_id=?";
        int delete = jdbcTemplate.update(sql,userId);
        System.out.println(delete);
    }

测试类

    @Test
    public void testJdbcTemplate3(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        BookService bookService = context.getBean("bookService", BookService.class);
        bookService.deleteBook("1");
    }

JdbcTemplate操作数据库(查询返回某个值)

1.查询表里面有多少条记录,返回时某个值
2.使用 JdbcTemplate 实现查询返回某个值代码
在这里插入图片描述
有两个参数
⚫ 第一个参数:sql 语句
⚫ 第二个参数:返回类型 Class

    @Override
    public int seleteCount() {
    
    
        String sql="select count(*) from t_book";
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
        return count;
    }

测试类

    @Test
    public void testJdbcTemplate4(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        BookService bookService = context.getBean("bookService", BookService.class);
        int i = bookService.seleteCount();
        System.out.println(i);
    }

JdbcTemplate操作数据库(查询返回对象)

1.场景:查询图书详情
2.JdbcTemplate 实现查询返回对象
在这里插入图片描述
⚫ 有三个参数
⚫ 第一个参数:sql 语句
⚫ 第二个参数:RowMapper 是接口,针对返回不同类型数据,使用这个接口里面实现类完成数据封装
⚫ 第三个参数:sql 语句值

    @Override
    public Book findBookInfo(String userId) {
    
    
        String sql="select * from t_book where user_id=?";
        Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), userId);
        return book;
    }

测试类

    @Test
    public void testJdbcTemplate5(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        BookService bookService = context.getBean("bookService", BookService.class);
        Book book= bookService.findBookInfo("1");
        System.out.println(book);
    }

JdbcTemplate操作数据库(查询返回对象)

1.场景:查询图书详情分页
2.JdbcTemplate 实现查询返回集合
在这里插入图片描述
⚫ 有三个参数
⚫ 第一个参数:sql 语句
⚫ 第二个参数:RowMapper 是接口,针对返回不同类型数据,使用这个接口里面实现类完成数据封装
⚫ 第三个参数:sql 语句值

    @Override
    public List<Book> findAllBook() {
    
    
        String sql="select * from t_book";
        List<Book> books= jdbcTemplate.query(sql,new BeanPropertyRowMapper<Book>(Book.class));
        return books;
    }

测试类

    @Test
    public void testJdbcTemplate6(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        BookService bookService = context.getBean("bookService", BookService.class);
        List<Book> books= bookService.findAllBook();
        System.out.println(books);
    }

JdbcTemplate操作数据库(批量操作)

1、批量操作:操作表里面多条记录
2、JdbcTemplate 实现批量添加操作
在这里插入图片描述
⚫ 有两个参数
⚫ 第一个参数:sql 语句
⚫ 第二个参数:List 集合,添加多条记录数据
批量添加

    @Override
    public void batchAddBook(List<Object[]> batchArgs) {
    
    
        String sql="insert into t_book values(?,?,?)";
        int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
        System.out.println(Arrays.toString(ints));
    }

测试类

    @Test
    public void testJdbcTemplate7(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        BookService bookService = context.getBean("bookService", BookService.class);
        List<Object[]> batchArgs=new ArrayList<>();
        Object[] o1={
    
    "3","c++","a"};
        Object[] o2={
    
    "4","mysql","b"};
        Object[] o3={
    
    "5","vb","c"};
        batchArgs.add(o1);
        batchArgs.add(o2);
        batchArgs.add(o3);
        bookService.batchAddBook(batchArgs);
    }

批量修改

     @Override
     public void batchUpdateBook(List<Object[]> batchArgs) {
    
    
        String sql = "update t_book set username=?,ustatus=? where user_id=?";
        int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
        System.out.println(Arrays.toString(ints));
}

测试类

    @Test
    public void testJdbcTemplate8(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        BookService bookService = context.getBean("bookService", BookService.class);
        List<Object[]> batchArgs=new ArrayList<>();
        Object[] o1 = {
    
    "java0909","a3","3"};
        Object[] o2 = {
    
    "c++1010","b4","4"};
        Object[] o3 = {
    
    "MySQL1111","c5","5"};
        batchArgs.add(o1);
        batchArgs.add(o2);
        batchArgs.add(o3);
        bookService.batchUpdate(batchArgs);
    }

批量删除

     @Override
     public void batchDeleteBook(List<Object[]> batchArgs) {
    
    
             String sql = "delete from t_book where user_id=?";
             int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
             System.out.println(Arrays.toString(ints));
}

测试类

    @Test
    public void testJdbcTemplate9(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        BookService bookService = context.getBean("bookService", BookService.class);
        List<Object[]> batchArgs=new ArrayList<>();
        Object[] o1 = {
    
    "3"};
        Object[] o2 = {
    
    "4"};
        batchArgs.add(o1);
        batchArgs.add(o2);
        bookService.batchDelete(batchArgs);
    }

事务操作

事务操作(事务概念)

事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败
事务四个特性(ACID)
(1)原子性
(2)一致性
(3)隔离性
(4)持久性

事务操作(搭建事务操作环境)

1、创建数据库表,添加记录
在这里插入图片描述
2、创建 service,搭建 dao,完成对象创建和注入关系
(1)service 注入 dao,在 dao 注入 JdbcTemplate,在 JdbcTemplate 注入 DataSource

@Service
public class UserService {
    
    
    @Autowired
    private UserDao userDao;
}
@Repository
public class UserDaoImpl implements UserDao {
    
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
}

    @Override
    public void reduceMoney() {
    
    
        String sql="update t_account set money=money-? where username=?";
        jdbcTemplate.update(sql,100,"tom");
    }

    @Override
    public void addMoney() {
    
    
        String sql="update t_account set money=money+? where username=?";
        jdbcTemplate.update(sql,100,"jack");
    }
    public void accountMoney(){
    
    
        userDao.reduceMoney();
        userDao.addMoney();
    }

测试类

    @Test
    public void testJdbcTemplate(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }

在这里插入图片描述
3、上面代码,如果正常执行没有问题的,但是如果代码执行过程中出现异常,有问题

    public void accountMoney(){
    
    
        userDao.reduceMoney();
        //模拟异常
        int i=1/0;
        userDao.addMoney();
    }

在这里插入图片描述
tom少了100,jack没有多100,如何解决使用事务解决
4.加入事务的操作过程
通过代码实现

    public void accountMoney(){
    
    
        try{
    
    
            //开启事务
            userDao.reduceMoney();
            //模拟异常
            int i=1/0;
            userDao.addMoney();
        }catch (Exception e){
    
    
            //事务回滚
        }
    }

事务操作(Spring 事务管理介绍)

1、事务添加到 JavaEE 三层结构里面 Service 层(业务逻辑层)
2、在 Spring 进行事务管理操作
有两种方式:编程式事务管理和声明式事务管理(使用)
3、声明式事务管理
(1)基于注解方式(使用)
(2)基于 xml 配置文件方式
4、在 Spring 进行声明式事务管理,底层使用 AOP 原理
5、Spring 事务管理 API
(1)提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
在这里插入图片描述

事务操作(注解声明式事务管理)

1、在 spring 配置文件配置事务管理器

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

2、在 spring 配置文件,开启事务注解
(1)在 spring 配置文件引入名称空间 tx

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

(2)开启事务注解

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

3、在 service 类上面(或者 service 类里面方法上面)添加事务注解
(1)@Transactional,这个注解添加到类上面,也可以添加方法上面
(2)如果把这个注解添加类上面,这个类里面所有的方法都添加事务
(3)如果把这个注解添加方法上面,为这个方法添加事务

@Service
@Transactional
public class UserService {
    
    

在这里插入图片描述
可以看到加入这个注解模拟异常数据不会变化

事务的传播行为

在这里插入图片描述

事务隔离级别

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44226883/article/details/119477544