IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 5.3(Spring)JDBCTemplate和事物 -> 正文阅读

[Java知识库]5.3(Spring)JDBCTemplate和事物

SpringJDBCTemplate

什么是JDBCTemplate

Spring框架对JDBC进行了封装,使用这个可以方便的进行JDBC操作

但是之后会存在数据库的框架Mybatis,实际中也不会使用JDBC

示例操作

引入依赖

   <!--Mysql的去驱动连接依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!--JDBC依赖 经过Spring进行了整合的包含数据源等  -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>

        <!--Spring如果需要整合框架需要的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>

        <!--Spring的事物依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>

Spring配置文件

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

    <!--指定扫描包-->
    <!--只有扫描到的类  注解才会生效-->
    <context:component-scan base-package="cn"/>

    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    <!-- 数据库连接数据源 -->
    <!--xml中bean表示的都是一个类,这个类中属性等  将数据源放入Spring容器中    -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="jdbc:mysql://localhost:3306/usershow?characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="ok"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    </bean>

    <!-- JdbcTemplate 类  将JDBCTemplate放入Spring容器中 并引入数据源 -->
    <bean id= "jdbcTemplate" class= "org.springframework.jdbc.core.JdbcTemplate">
        <!--注入 dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

</beans>

javaBean

java连接数据库,为了方便操作数据库中的数据

将每一个表对应javaBean进行映射,这里可以使用IDEA的连接数据库生成

在这里插入图片描述

进行指定连接数据库,选择具体的库

在这里插入图片描述

指定数据表自定创建javaBean

package cn.pojo;


public class User {

  private long id;
  private String cname;
  private String mobile;
  private String qq;
  private String email;


  public long getId() {
    return id;
  }

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


  public String getCname() {
    return cname;
  }

  public void setCname(String cname) {
    this.cname = cname;
  }


  public String getMobile() {
    return mobile;
  }

  public void setMobile(String mobile) {
    this.mobile = mobile;
  }


  public String getQq() {
    return qq;
  }

  public void setQq(String qq) {
    this.qq = qq;
  }


  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }

}

测试是否连接成功

daoImple类,这里并没有使用规范,编写接口,编写实现等操作.

而是直接在数据访问层中一气呵成

import java.util.List;
import java.util.Map;

//数据访问层演示
//该注解将该类加入Spring容器中
@Repository("daoImple")
public class DaoImple {

//    通过IOC自动注入,将Spring容器中的对象进行引入
    @Autowired
    private JdbcTemplate jdbcTemplate;

//    我这里直接使用该方法进行测试
//    通过获取JDBCTemplate直接操作数据的操作
    public void get(){
//        sql编写
        String sql ="SELECT * FROM user";
//        通过JDBCTemplate的API进行操作获取所有的查询数据
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);

//        分别进行打印查询到的数据
        System.out.println("查询到总记录数"+maps.size());

        System.out.println("第一个查询结果的cname属性值"+maps.get(0).get("cname"));
    }

}
public class SpringIOCTest {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("SpringTest.xml");
        DaoImple daoImple = context.getBean("daoImple", DaoImple.class);
        daoImple.get();
    }
}

在这里插入图片描述

JDBCTemplate在一定基础上简化了JDBC的开发.

SQL与程序在一起,存在耦合.之后会使用Mybatis框架进行优化

Mysql可以做到SQL与代码分离.通过ORM对象关系映射.

JDBATemplate的API

上面通过向Spring容器中添加数据源,添加JDBCTemplat已经实现可以操作数据库.下面就介绍该类的具体API

方法描述
execute(String sql)可执行任何sql语句,但返回值是void,所以一般用于数据库的新建、修改、删除和数据表记录的增删改。
int update(String sql)增删改,args传递实参,返回受影响的记录数。
int update(String sql, Object…args)增删改,args传递实参,返回受影响的记录数。
List query(String sql, PreparedStatementSetter pss, RowMapper rowMapper)该方法根据String类型的参数提供的SQL语句创建PreparedStatement对象,通过RowMapper将结果返回到List中。
List query(String sql, Object[] args, RowMapper rowMapper)该方法使用Object[] 的值来设置SQL中的参数值,采用RowMapper回调方法可以直接返回List类型的数据。
queryForObject(String sql, Object[] args, RowMapper rowMapper)该方法将args参数绑定到SQL语句中,通过RowMapper返回单行记录,并转换为一个Object对象返回
queryForList(String sql,Object[] args, classelementType)该方法可以返回多行数据的结果,但必须是返回列表,elementType参数返回的是List元素类型。

增删改

1 1 、修改
@Override
public void updateBook(Book book){
        String sql="update t_book set username=?,ustatus=? where user_id=?";
        Object[]args={book.getUsername(),book.getUstatus(),book.getUserId()};
        int update=jdbcTemplate.update(sql,args);
        System.out.println(update);
        }
        2 2 、删除
@Override
public void delete(String id){
        String sql="delete from t_book where user_id=?";
        int update=jdbcTemplate.update(sql,id);
        System.out.println(update);
        }

查询

在这里插入图片描述

在这里插入图片描述

Spring事物

什么是事物

(1)事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操
作都失败
(2)典型场景:银行转账

  • lucy 转账 100 元 给 mary
  • lucy 少 100,mary 多 100

事物四个特性

  1. 一致性:就是说事物中的操作要么成功,要么都失败。
  2. 原子性:个人感觉其实与一致性是差不多的感觉,也是为了保证要么都成功,要么都失败。
  3. 隔离性:事物与事物直接是要相互不能够影响的。
  4. 持久性:事物成功,对数据库中操作的数据的改变是永久性的。

数据库的五种隔离级别

  1. Default:使用数据库默认的事务隔离级别
  2. Read_uncommited:未提交读,:脏读,不可重复读,虚读都有可能发生
  3. Read_conmmited:已提交读,不可重复读,虚读都有可能发生
  4. Repeatable_read:可重复读 虚读都有可能发生
  5. Serializeble:串化,锁表

七种传播行为

什么是传播行为:当一个事务调用两一个事务时,即A方法调用B方法时,并且A、B方法都具有事务的隔离级别,那么这现象就叫做传播行为。

Spring 支持 7 种事务传播行为(Transaction Propagation Behavior):

(1)必须有事务

  1. **PROPAGATION_REQUIRED :**如果没有,就开启一个事务;如果有,就加入当前事务(方法B看到自己已经运行在 方法A的事务内部,就不再起新的事务,直接加入方法A)
  2. **RROPAGATION_REQUIRES_NEW :**如果没有,就开启一个事务;如果有,就将当前事务挂起。(方法A所在的事务就会挂起,方法B会起一个新的事务,等待方法B的事务完成以后,方法A才继续执行)
  3. **PROPAGATION_NESTED:**如果没有,就开启一个事务;如果有,就在当前事务中嵌套其他事务
  4. **PROPAGATION_MANDATORY:**如果没有,就抛出异常;如果有,就使用当前事务

(2)事务可有可无

PROPAGATION_SUPPORTS: 如果没有,就以非事务方式执行;如果有,就加入当前事务(方法B看到自己已经运行在 方法A的事务内部,就不再起新的事务,直接加入方法A)

(3)不需要事务

  1. **PROPAGATION_NOT_SUPPORTED :**如果没有,就以非事务方式执行;如果有,就将当前事务挂起,(方法A所在的事务就会挂起,而方法B以非事务的状态运行完,再继续方法A的事务)
  2. **PROPAGATION_NEVER :**如果没有,就以非事务方式执行;如果有,就抛出异常。

小结

① 在多线程中配置事务的隔离级别,和传播特性之后,在产生事务挂起的情况时,会产生死锁,这时候需要配置超时时间,以便尽快熔断。
② 在同一个类里面,如果事务A方法通过this调用方法B事务时,在不同的情况下可能会出现,B方法的事务不会被切入进去,这时候可以将这个类暴露出去,在事务A中通过类来来调用事务B。
③ 方法A有事务,方法B没有事务,方法A调用方法B,B加入A的事务中。

事物操作示例

在这里插入图片描述

没有进行事物

我的数据库

在这里插入图片描述

我的Dao与Service

javaBean修改了

public class User {

    //为了看起来方便我没有复制出get/set
   
  private long id;
  private String cname;
  private String mobile;
  private String qq;
  private double money;
}

Dao层实现类

//将该类注入Spring容器中
@Repository("userdaoimple")
public class UserDaoImple implements UserDao {

//    通过自动装配将Spring容器中的操作数据库对象引入过来
    @Autowired
    private JdbcTemplate jdbcTemplate;


    public void subtractMethod(int id, int Money) {
        String sql = " UPDATE USER SET money = money-? WHERE id =? ";
        jdbcTemplate.update(sql,Money,id);
    }

    public void addMethod(int id, int Money) {
        String sql = " UPDATE USER SET money = money+? WHERE id =? ";
        jdbcTemplate.update(sql,Money,id);
    }
}

Service实现类

//通过该注解将该类注入Spring容器中
@Service("userservice")
public class UserServiceImple implements UserService {


    @Autowired
    private UserDao userDao;

    public void txMoney(int id1, int id2, int Money) {
        userDao.subtractMethod(id1,Money);

        userDao.addMethod(id2,Money);
    }
}

第一次执行

在这里插入图片描述

发现确实没有错误.

但是如果在执行Service的时候出现异常.那么结果

修改Service代码,使在中途出现异常. 那么结果就会出现,一部分SQL执行,一部分SQL不执行

 public void txMoney(int id1, int id2, int Money) {
        userDao.subtractMethod(id1,Money);

//        在这里制造一个算数异常
        int a= 10/0;

        userDao.addMethod(id2,Money);
    }

发现id1减少,id2没有增加

在这里插入图片描述

Spring 进行事务管理操作

有两种方式:编程式事务管理和声明式事务管理(使用)

编程式事物

在这里插入图片描述

声明式事物

  1. 基于注解方式
  2. 基于xml 配置文件方式

在 Spring 进行声明式事务管理,底层使用 AOP 原理
Spring 事务管理 API
提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
事务操作

Spring通过接口进行事物的处理,分别提供的实现类,对于不同的框架使用不同的实现类

JDBC和Mybatis都是使用DataSourceTransactionManager
在这里插入图片描述

声明式基于注解操作

在Spring配置文件中添加事物管理器和开启事物

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


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

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

//通过该注解将该类注入Spring容器中
@Service("userservice")
@Transactional()
public class UserServiceImple implements UserService {


    @Autowired
    private UserDao userDao;


    public void txMoney(int id1, int id2, int Money) {
        userDao.subtractMethod(id1,Money);

//        在这里制造一个算数异常
        int a= 10/0;

        userDao.addMethod(id2,Money);
    }
}

发现SQL要执行都执行

在这里插入图片描述

事物操作(声明式事物的管理参数)

在@Transactional注解中可以添加参数

事物传播行为(propagation)

多个事物方法直接进行调用,这个过程中事物是如何进行实现的

在业务逻辑层中,每个方法都是事物,当业务逻辑中,方法进行的调用,那么事物如何进行传播

在这里插入图片描述

事物的隔离级别

事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题

       1、未提交读(Read uncommitted)
        ①定义:就是一个事务读取到其他事务未提交的数据,是级别最低的隔离机制。

         ②缺点:会产生脏读、不可重复读、幻读。

         ③案例解读:以前交易所炒股的时候,股民老王购买了5000股,操作员操作录入(此时开启事务),操作时手误,多输入了一个0,数据保存但是未提交。此时老王查询自己的持股信息,发现自己居然有50000股,瞬间血压升高,昏倒在地。然后操作员发现自己录入错误,修改成正确的信息,录入完成(事务结束)。老王被救醒后,哆嗦这查询自己的持股,发现只有5000,没有增减,他之前看到的就是脏读数据。

         ④解决方案:采用更高级的隔离机制,如提交读。

   2、提交读(Read committed)

         ①定义:就是一个事务读取到其他事务提交后的数据。Oracle默认隔离级别。

         ②缺点:会产生不可重复读、幻读。

         ③案例解读:股市升高后,老王查看自己持有5000股,就想卖掉4000股,在老王卖股票的时候,老王的老婆看股市太高,就登录老王的账号,卖掉3000股。当老王想卖股票时,发现自己只有2000股,不是之前看到的5000股,这就是不可重复读问题。

         ④解决方案:采用更高级的隔离机制,如可重复读。

   3、可重复读(Repeatable read)

         ①定义:就是一个事务对同一份数据读取到的相同,不在乎其他事务对数据的修改。MySQL默认的隔离级别。

         ②缺点:会产生幻读。

         ③问题解读:股市忽涨忽跌,老王焦虑不安,按捺不住,想把持有的多种股票全部抛掉。与此同时,老外老婆听信砖家所言,使用老王的账号买了某只神股。老王抛掉所有股票后,查看自己的持股,猛然发现自己居然还持有一只股票,瞬间觉得一脸懵逼,这就是幻读导致。

         ④解决方案:采用更高级的隔离机制,序列化。

   4、序列化(Serializable)

         ①定义:事务串行化执行,隔离级别最高,牺牲了系统的并发性。

         ②缺点:可以解决并发事务的所有问题。但是效率地下,消耗数据库性能,一般不使用。

? img

timeout :超时时间

(1)事务需要在一定时间内进行提交,如果不提交进行回滚
(2)默认值是 -1 ,设置时间以秒单位进行计算

readOnly :是否只读

(1)读:查询操作,写:添加修改删除操作
(2)readOnly 默认值 false,表示可以查询,可以添加修改删除操作
(3)设置 readOnly 值是 true,设置成 true 之后,只能查询

rollbackFor :回滚

(1)设置出现哪些异常进行事务回滚

noRollbackFor :不回滚

(1)设置出现哪些异常不进行事务回滚

下面还存在Spring对于事物的XML和全注解。就不多介绍了

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-05 11:54:42  更:2021-12-05 11:55:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:32:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码