Spring事务、5.0新特性(四)

一、JdbcTemplate概要

1.1、JdbcTemplate简介

  JdbcTemplate的本质是一个对数据库操作的工具,和apache的DButil一样,都是对数据库进行更方便的操作。JdbcTemplate是Spring框架在jdbc上面做了一定的封装,使用spring的注入功能,将DataSource注册到JdbcTemplate之中。

优点
1、将jdbc创意创建连接、语句对象、设置SQL参数,释放资源等一系列操作封装到JdbcTemplate工具中,简化了代码量,使用方便简单。
2、运行期:高效、内嵌Spring框架中、支持基于AOP的声明式事务

缺点:必须于Spring框架结合在一起使用、不支持数据库跨平台、默认没有缓存


1.2、JdbcTemplate提供的方法

  JdbcTemplate位于中spring-jdbc-x.x.x .RELEASE.jar中。其全限定命名为org.springframework.jdbc.core.JdbcTemplate。要使用JdbcTemlate还需一个spring-tx-x.x.x, RELEASE.jar这个包包含了一下事务和异常控制。
这里我们使用这个:
在这里插入图片描述
除此之外,连接数据库还需要数据源数据库驱动
在这里插入图片描述
设计到事务提交还需要事务依赖的jar包:
在这里插入图片描述
如果还需要整个MyBatis、Hibanate,还需要jar包:
在这里插入图片描述

(1)execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
(2)update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
(3)query方法及queryForXXX方法:用于执行查询相关语句;
(4)call方法:用于执行存储过程、函数相关语句。


1.3、Spring配置数据源的三种方式

方式一Spring内置数据源配置
Class:DriverManagerDataSource
全限定名:org.springframework.jdbc.datasource.DriverManagerDataSource
不需要添加任何jar


方式二apache的 dbcp数据源配置
Class:BasicDataSource
全限定名:org.apache.commons.dbcp.BasicDataSource
需要添加:com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
com.springsource.org.apache.commons.pool-1.5.3.jar

方式三c3p0的 数据源配置
Class:ComboPooledDataSource
全限定名:com.mchange.v2.c3p0.ComboPooledDataSource
需要添加:com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

二、JdbcTemplate案例

因为dbcp和C3p0大家都比较熟悉,下面我们就使用Spring的内置数据源进行演示。

2.1、简单案例

(如果看不懂,你叫人打我)

1、创建数据表:

 create table account(
 	id int primary key auto_increment,
 	name varchar(40),
 	money float
 )character set utf8 collate utf8_general_ci;
 
 insert into account(name,money) values('aaa',1000);
 insert into account(name,money) values('bbb',1000);

2、创建一个Maven项目:
在这里插入图片描述
3、pom.xml 引入jar包:
在这里插入图片描述
4、写一个测试类进行测试:
在这里插入图片描述
能正常运行,确定案例成功之后。接下来我们将数据库的配置换成注解或xml的配置。

5、创建一个Dao接口:
在这里插入图片描述
在这里插入图片描述
5、创建一个接口实现类AccountDaoImpl.java

package com.it.dao.impl;
import com.it.dao.IAccountDao;
import com.it.domain.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import java.util.List;
/**
 * 账户的持久层实现类
 */
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {

    @Override
    public Account findAccountById(Integer accountId) {
        List<Account> accounts = super.getJdbcTemplate().query("select * from account where id = ?",
                                                                    new BeanPropertyRowMapper<Account>(Account.class),
                                                                    accountId
                                                               );
        return accounts.isEmpty()?null:accounts.get(0);
    }

    @Override
    public Account findAccountByName(String accountName) {
        List<Account> accounts = super.getJdbcTemplate().query("select * from account where name = ?",
                                                                    new BeanPropertyRowMapper<Account>(Account.class),
                                                                    accountName
                                                                );
        if(accounts.isEmpty()){
            return null;
        }
        if(accounts.size()>1){
            throw new RuntimeException("结果集不唯一");
        }
        return accounts.get(0);
    }

    @Override
    public void updateAccount(Account account) {
        super.getJdbcTemplate().update("update account set name=?,money=? where id=?",
                                        account.getName(),
                                        account.getMoney(),
                                        account.getId()
                                        );
    }
}

6、创建一个bean.xml配置文件:
在这里插入图片描述
在这里插入图片描述

7、编写测试类进行测试:
在这里插入图片描述

2.2、升级案例

接下来演示一下JdbcTemplate的CRUD和使用聚合函数的使用。
先来一波简单JdbcTemplate的CRUD的使用方法:
在这里插入图片描述

接下来是查询,在来里面选择两个常用的演示:
(接上面的测试类)

先定义一个返回集策略:
在这里插入图片描述
然后执行下面SQL:

1、查询账户余额大于1000的用户

List<Account> accounts = jt.query("select * from account where money > ?",new BeanPropertyRowMapper<Account>(Account.class),1000f);
 for(Account account : accounts){
     System.out.println(account);
 }

或者:

//查询一个
List<Account> accounts = jt.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),1);
System.out.println(accounts.isEmpty()?"没有内容":accounts.get(0));

2、查询返回一行一列:


//查询返回一行一列(使用聚合函数,但不加group by子句)
Long count = jt.queryForObject("select count(*) from account where money > ?",Long.class,1000f);
System.out.println(count);

三、事务

3.1、概念

:什么是事务?
  事务是数据库操作最基本的单元,逻辑上一组操作,要么成功,要么失败。如果有一个失败操作,那么该事务中的所有操作都失败。
典型案例:银行转账

事务四大特性(ACID)
(1)原子性 :(对数据库的操作,要么都成功,要么都失败)
(2)一致性 : (操作之前和操作之后,总量不变)
(3)隔离性:(多事务操作时候,事务与事务之间不会相互影响)
(4)持久性:(提交事务以后,表中数据发生变化,不再改变)


3.2、银行转账案例

模拟之前的例子,自己去写

3.3、Spring事务管理介绍

1、事务添加到JavaEE三层结构里面的Service层(业务逻辑层)

2、在Spring进行事务管理操作

有两种方式:编程式事务管理和声明式事务管理(使用)
声明式事务(使用Spring提供的事务注解来实现,比较常用)
编程式事务:通过使用编码最常用的就是try....catch 来写commit()rollback()方法。比如我往数据库执行在A表中插数据,B表中修改删除数据,那么当我执行完A操作的时候,B操作异常了,此时我们需要在catch中写一个rollback()方法,并执行把A表中新增的数据删除,把B表中删除的数据新增操作。
总结在大厂里面往往两种方式结合起来一起使用的。

3、声明式事务管理
(1)基于注解方式
(2)基于xml配置文件方式

4、在Spring进行声明式事务管理,底层使用AOP原理

5、Spring事务管理API
(1)提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类:
在这里插入图片描述

3.4、基于注解声明式事务管理

1、在spring配置文件中,配置事务管理器:
在这里插入图片描述
然后来配置事务管理器:
在这里插入图片描述

2、在Spring配置文件中,开启事务注解
(1)在spring配置文件引入事务名称空间tx
在这里插入图片描述

(2)开启事务注解:
开启注解的时候,要指定使用哪个事务管理器:
在这里插入图片描述

3、在service类上面(获取service类里面方法上面)添加事务注解

@Transactional注解可以加到类上面,也可以加到方法上面。
(1)添加到类上:表示该类中的所有方法都添加上了事务
(2)添加到方法上:只是为该方法添加了事务
这里我们将注解最终加载类上面做演示。
在这里插入图片描述
提交事务报错演示:
在这里插入图片描述
在这里插入图片描述
此时执行程序,报错了以后,发现添加了分布式事务以后金额并没有发生变化:
在这里插入图片描述


3.5、完整注解声明式事务管理

  以上例子我们已经讲了基于xml的方式来使用Spring事务。下面我们来说下基于完整注解声明是式事务管理.
步骤:
1、创建java配置类,使用配置类替代xml配置
创建一个java类,然后使用@Configuration标明该类是一个配置类。@ComponentScan开启spring组件扫描,使用@EnableTransactionManagement开启事务。
在这里插入图片描述

2、创建Bean实例
使用@Bean注解创建Bean。使用@Bean来代替xml中的<Bean>标签
在xml中是这样配置的:
在这里插入图片描述
下面转成完全注解是这样配置的:
在这里插入图片描述

同理,再来创建其他Bean对象:
在这里插入图片描述
在这里插入图片描述
3、测试:
测试前先确定自己的业务类上是否使用了@Transactional注解
在这里插入图片描述
写一个测试方法:
在这里插入图片描述


四、日志框架

Spring5.0的新功能:
在这里插入图片描述
1、整合Spring5基于java8实现,运行时兼容JDK9。
在这里插入图片描述
2、Spring5里面自带了通过的日志封装。如果想要整合其他的第三方日志框架也是可以的,比如:log4j2
  Spring5已经移除了Log4jConfigListener,该玩意是为了进行log4j整合的。所以spring5本身并不支持log4j,官方建议使用Log4j2的版本,因为log4j里面存在好多漏洞未升级。如果基于什么原因只想要log4j,那么只能讲Spring降级成4.0


4.1、Spring5整合log4j2

步骤:
1、引入log4j2的jar包依赖和配置文件
在这里插入图片描述
在这里插入图片描述
2、创建log4j2的配置文件
由于log4j2框架代码硬编码读取配置文件为log4j2.xml,所以日志文文件的命名必须是log4j2.xml
在这里插入图片描述
以下是我创建的最基本的日志结构:

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,可以看到log4j2内部各种详细输出-->
<configuration status="INFO">
    <!--先定义所有的appender-->
    <appenders>
        <!--输出日志信息到控制台-->
        <console name="Console" target="SYSTEM_OUT">
            <!--控制日志输出的格式-->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </console>
    </appenders>
    <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
    <!--root:用于指定项目的根日志,如果没有单独指定Logger,则会使用root作为默认的日志输出-->
    <loggers>
        <root level="info">
            <appender-ref ref="Console"/>
        </root>
    </loggers>
</configuration>

这里说一下日志级别,比如我的日志级别是debug,那么日志会将自己级别和比自己日志级别大的都显示出来,比如FATAL、ERROR 、 WARN 、 INFO、DEBUG都会显示出来

3、执行测试方法,查看日志级别
执行方法:
在这里插入图片描述
或者自己写一个测试类测试日志级别也可以:
在这里插入图片描述

五、核心容器新特性

在这里插入图片描述

5.1、支持@Nullable注解

@Nullable可以用在方法上面、属性上面、参数上面。
方法上:表示方法返回值可以为空
属性上:属性值可以为空
参数上:参数值可以为空
在这里插入图片描述
在这里插入图片描述


5.2、支持函数时风格GenericApplicationContext

之前我们学习的都是用基于注解或者xml的方式将对象交给spring容器管理。现在我们想要将自己new的对象方法spring容器中,该怎么办呢?
答案:使用函数式风格创建对象,并交给spring容器进行管理。

1、写一个测试类,创建GenericApplicationContext对象
在这里插入图片描述
这里获取对象的时候需要注解,spring5,该类不会默认给我们注入的Bean取名为类名首字母小写,要么自己指定,要么写全类名。上述方法就是通过全类型类获取的Bean,下面要是一下通过指定Bean的ID类获取:
在这里插入图片描述

5.3、支持整合Junit5

在这里插入图片描述
  之前我们写单元测试的时候会写很多创建ApplicationContext对象,读取xml配置文件,并使用getBean()获取对象的方法,而为了提高测试,Spring提供了使用注解来简化单元测试代码的操作。

步骤:
1、引入Spring单元测试相关依赖
在这里插入图片描述

2、Junit4版本测试程序
在这里插入图片描述
3、整合Junit5
1、删除引入的Junit4 jar包
删除默认的test包:
在这里插入图片描述

2、添加Junit5
在这里插入图片描述
此时测试包变成了这个:
在这里插入图片描述

3、创建测试类,使用注解完成
在这里插入图片描述
4、使用复合注解进行优化
在这里插入图片描述

5.4、新模块SpringWebFlux

在这里插入图片描述
在这里插入图片描述

SpringWebflue介绍:
  SpringWebflue是spring5添加的新模块,用于web开发的,功能和SpringMVC类似的,但是底层原理和SpringMVC不同。Webflue使用当前一种比较流程的响应式编程出现的框架。
  使用传统的web框架,比如SpringMVC,这些基于Servlet容器基础上运行,而SpringWebflue是一种异步、非阻塞的框架,异步非阻塞的框在在Servlet3.1 以后才支持。SpringWebflue的核心是基于Reactor的相关API进行实现的。

同步:调用者发送请求,等待回应以后再去执行其他服务
异步:调用者发送请求,无论是否回应请求,都去执行其他服务
阻塞:收到请求以后,等着,不马上回馈请求方,而是做完了请求任务以后才做出反馈。
非阻塞:收到请求以后,立马给出反馈,然后再去做请求方给的事情。
阻塞需要等待,非阻塞不需要等待。
这么一说,是不是立马想到MQ,MQ消息缓存就是这一机制。

SpringWebflue特点:
1、异步、非阻塞(在不扩展硬件资源的情况下,可以提高系统的吞吐量和伸缩性,能够在同一时间内处理更多请求。以Reactor为基础实现的响应式编程)
2、函数式编程:Spring5是基于java8,webflux能够使用java8的函数式编程方式来实现路由的请求。
3、和SpringMVC比较:
在这里插入图片描述
(1)两个框架都可以使用注解方式,都支持运行在Tomcat容器中。
(2)SpringMVC采用的的命令式编程(代码一行一行执行),Webflux采用异步的响应式编程(提高服务器吞吐量)
如果在硬件资源情况有限,且又要处理大量请求的情况下,那么就使用WebFlux。

响应式编程:
(1)响应式编程是一种面向数据流和变化传播的编程规范。这意味着可以在编程语言中很方便的表达静态或动态数据。而相关的计算模型会自动将变化的值通过数据流进行传播。
比如:在excel中,单元格可以包含字面值或者类似“=B1+C2”的公式,而包含公式的单元格的值就会根据其他单元格的值的变化而变化。

(2)Java8及其之前的版本
响应式编程实际底层是运用了观察者模式,观察着模式则是着重点在关心数据的变化,根据数据的变化做出不同的反应。在java8中提供了观察者模式的两个类,一个是ObserverObservable
在这里插入图片描述

Reactor的实现
(1)响应式编程操作中,Reactor是满足Reactive规范框架
(2)Reactor于两个核心类,MonoFlux,这两个实现接口Publisher,提供丰富操作符,Flux对象实现发布者,返回N个元素;Mono实现翻发布者,返回0或者1个元素。
在这里插入图片描述

(3)Flux和Mono都是数据流的发布者,使用Flux和Mono都可以发出三种数据信息,分别是:元素值、错误信号、完成信号。而且错误信号和完成信号都代表终止信号,告诉定位者该数据流已结束。错误的信号终止数据流同时把错误信息传送给订阅者
1、错误信号和完成信号是不能共存的。
2、如果没有发送任何的元素值,而是直接发送错误或者完成信号,那么就表示现在是个空的数据流。
3、如果没有错误信号,没有完成信号,表示是无线的数据流。
如果订阅者不进行订阅,那么信号是不会输出的。

首先引入依赖:
在这里插入图片描述

在这里插入图片描述

  1. 创建数据流例子
    在这里插入图片描述

不对信号进行订阅,那么信号是不会输出的:
订阅:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值