Spring Boot工程应用篇(四)整合Mybatis、整合事务、整合日志、整合Redis

6. Spring Boot 整合Mybatis

6.1 总步骤

  • 在 pom 中导入三个依赖:MyBatis 与 Spring Boot 整合依赖、MySQL 驱动依赖、Druid 依赖
  • 将 dao 目录注册为资源目录
  • 在 Dao 接口上添加@Mapper 注解
  • 在主配置文件中注册三类信息:映射文件、实体类别名、数据源

6.2 需求

完成一个简单的注册功能。

6.3 定义工程

复制 《内嵌tomcat使用JSP页面》中的06-jsp 工程,并重命名为 07-mybatis。

6.3.1 修改 pom 文件

导入三个依赖:mybatis 与 Spring Boot 整合依赖、mysql 驱动依赖与 Druid 数据源依赖。

<!--mybatis 与 spring boot 整合依赖-->
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>1.3.2</version>
</dependency>
<!--mysql 驱动-->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.47</version>
</dependency>
<!-- druid 驱动 -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid</artifactId>
	<version>1.1.12</version>
</dependency>

6.3.2 修改 SomeHandler

在这里插入图片描述

6.3.3 定义 Service 接口及实现类

(1) 定义 Service 接口
在这里插入图片描述

(2) 定义 Servivce 实现类
在这里插入图片描述

6.3.4 定义实体类及 DB 表

(1) 定义实体类
在这里插入图片描述

(2) 定义 DB 表

在 DB 的 test 数据库中定义 student 表。
在这里插入图片描述

6.3.5 定义 Dao 接口

Dao 接口上要添加@Mapper 注解。
在这里插入图片描述

6.3.6 定义映射文件

此时映射文件和Mapper接口在同一个包下,所以需要注册资源目录:
在这里插入图片描述

6.3.7 注册资源目录

在 pom 文件中将 dao 目录注册为资源目录。

<build>
	<resources>
		<!--注册 dao 包下 mybatis 映射文件为资源目录-->
		<resource>
			<directory>src/main/java</directory>
			<includes>
				<include>**/*.xml</include>
			</includes>
		</resource>
	</resources>
</build>

在这里插入图片描述

6.3.8 修改主配置文件

在主配置文件中主要完成以下几件工作:

  • 注册映射文件
  • 注册实体类别名
  • 注册数据源

在这里插入图片描述

在这里插入图片描述

7. Spring Boot 整合事务

若工程直接或间接依赖于 spring-tx,则框架会自动注入 DataSourceTransactionManager事务管理器;若依赖于 spring-boot-data-jpa,则会自动注入 JpaTransactionManager。

7.1 定义工程

复制 07-mybatis 工程,并重命名为 08-transaction。

当前工程完成在对用户注册时一次插入到 DB 中两条注册信息。若在插入过程中有发生异常,则已完成插入的记录回滚。

7.2 修改启动类

这一步其实是非必须的
在这里插入图片描述

7.3 修改 Service 实现类

注解@Transactional:

/**
 * Defines zero (0) or more exception {@link Class classes}, which must be
 * subclasses of {@link Throwable}, indicating which exception types must cause
 * a transaction rollback.
 * 定义0(0)或多个异常{@link Class classes},这些异常必须是{@link Throwable}的子类,
 * 指示哪些异常类型必须导致事务回滚。
 * <p>By default, a transaction will be rolling back on {@link RuntimeException}
 * and {@link Error} but not on checked exceptions (business exceptions). See
 * {@link org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)}
 * for a detailed explanation.
 * 默认情况下,事务将回滚{@link RuntimeException}和{@link Error},
 * 但不会回滚已检查的异常(业务异常)。
 * 
 * <p>This is the preferred way to construct a rollback rule (in contrast to
 * {@link #rollbackForClassName}), matching the exception class and its subclasses.
 * <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(Class clazz)}.
 * @see #rollbackForClassName
 * @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)
 */
Class<? extends Throwable>[] rollbackFor() default {
    
    };

如果@Transactional不指定rollbackFor属性,那么默认只会回滚运行时异常:
在这里插入图片描述

8. Spring Boot 整合日志

8.1 logback 日志技术介绍

Spring Boot 中使用的日志技术为 logback。其与 Log4J 都出自同一人,性能要优于 Log4J,是 Log4J 的替代者。

在 Spring Boot 中若要使用 logback,则需要具有 spring-boot-starter-logging 依赖,而该依赖被 spring-boot-starter-web 所依赖,即不用直接导入 spring-boot-starter-logging 依赖。

8.2 spring boot 中使用 logback

在 Spring Boot 中使用 logback 日志,有两种方式。

(1) 添加配置属性

只需在核心配置文件中添加如下配置即可。
在这里插入图片描述

(2) 添加配置文件

该文件名为 logback.xml,且必须要放在 src/main/resources 类路径下。
在这里插入图片描述

9. Spring Boot 整合Redis(SSRM 整合应用)

9.1 实现步骤

  • 在 pom 中添加 Redis 与 Spring Boot 整合依赖
  • 在配置文件中注册 Redis 连接信息
  • 实体类实现序列化接口
  • 在启动类上添加@EnableCaching
  • 在查询方法上添加@Cacheble,在增删改方法上添加@CacheEvict
  • 若使用 API 方式操作 Redis,则需要注入 RedisTemplate,然后通过 RedisTemplate 获取到Redis 操作对象后就可以对 Redis 进行操作了。

9.2 Redis 数据分类

使用 Redis 缓存的数据可以划分为两类:

  • DB 更新后,Redis 缓存中的数据就要马上清除,以保证将来缓存中的数据与 DB 中的数据的绝对一致性,这是一类数据;
  • 还有一类,对数据准确性要求不是很高,只要与 DB 中的数据差别不大就可以,所以这类数据一般会为其设置过期时效。

9.3 定义工程

复制 08-transaction 工程,并重命名为 09-redisCache。

当前工程完成让用户在页面中输入要查询学生的 id,其首先会查看 Redis 缓存中是否存在,若存在,则直接从 Redis 中读取;若不存在,则先从 DB 中查询出来,然后再存放到 Redis缓存中。但用户也可以通过页面注册学生,一旦有新的学生注册,则需要将缓存中的学生信息清空。根据id查询出的学生信息要求必须是实时性的,其适合使用注解方式的Redis缓存。

同时,通过页面还可以查看到总学生数,但对其要求是差不多就行,无需是实时性的。对于 Spring Boot 工程,其适合使用 API 方式的 Redis 缓存,该方式方便设置缓存的到期时限。

9.3.1 修改 pom 文件

在 pom 文件中添加 Spring Boot 与 Redis 整合依赖。
在这里插入图片描述

在这里插入图片描述

9.3.2 修改主配置文件

在主配置文件中添加如下内容:
在这里插入图片描述

9.3.3 修改实体类 Student

由于要将查询的实体类对象缓存到 Redis,Redis 要求实体类必须序列化。所以需要实体类实现序列化接口。
在这里插入图片描述

9.3.4 修改代码

(1) 修改 index 页面
在这里插入图片描述

(2) 修改 Controller 类

在其中添加两个处理器方法。
在这里插入图片描述

(3) 修改 Service 接口

在 Service 接口中添加一个业务方法。
在这里插入图片描述

(4) 修改 Service 接口实现类
在这里插入图片描述

Redis在高并发情况下可能会存在哪些问题?
1) 缓存穿透:当从DB中查询结果为null时有可能会引发缓存穿透问题。
  其解决方案是为这些为null的结果赋予一个默认值

2) 缓存雪崩:当缓存中的某些缓存在同一很短的时段内几乎同时到期,此时就可能会引发缓存雪崩问题。
  其解决方案是,提前规划好系统中所有缓存的到期时间。

3) 热点缓存:当某一个缓存的有效期到达时其可能会引发热点缓存问题。
  其解决方案是,双重检测锁机制

在这里插入图片描述

(5) 修改 Dao 接口

在其中添加两个方法。
在这里插入图片描述

(6) 修改映射文件

可以使用简单类名作为别名。
在这里插入图片描述

9.3.5 启动 Redis

在这里插入图片描述

9.4 双重检测的线程安全问题

/**
 *  通过当前类的getInstance()方法可以获取到一个单例的Student对象
 *  注意:当前的代码与当前的应用程序没有任何关系
 *
 *  当前代码中存在线程安全问题:
 *  解决方案有三种:
 *  1)在方法签名上添加synchronized,使方法变为同步方法
 *  2)在存在线程安全问题的成员变量声明前添加volatile
 *  3)若存在线程安全问题的成员变量为Integer、Long、Boolean等,可以将它们
 *     定义为AtomicXxx类型
 *
 */
@Component   // 当前类是单例的
public class StudentFactory {
    
    
    private volatile Student student;

    public Student getInstance() {
    
    
        if(student == null) {
    
    
            synchronized (this) {
    
    
                if(student == null) {
    
    
                    // 以下语句的底层实现由三步构成:
                    // 1)申请堆空间m
                    // 2)使用对象的初始化数据初始化堆空间m
                    // 3)将student引用指向堆空间m
                    // 这三步的顺序没法保证一定是1->2->3
                    // 当然1肯定先执行,因为2和3都依赖1,但是2和3的顺序是不一定的
                    // 有可能出现 1->3->2,这个时候第一个线程执行到1->3的时候
                    // 另一个线程进来就会发现student!=null,直接返回student
                    // 但是student还没有初始化,此时student的属性是null和0
                    // 解决方案见类上面注释
                    student = new Student("张三", 33);
                }
            }
        }
        return student;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_41947378/article/details/108749391