SpringBoot高级整合 尚硅谷雷锋阳 学习笔记
作者:互联网
SpringBoot高级整合 尚硅谷雷锋阳 学习笔记
这里写目录标题
- SpringBoot高级整合 尚硅谷雷锋阳 学习笔记
- Springboot与缓存
- SpringBoot 与消息
- SpringBoot 与检索
- SpringBoot 与任务(异步,定时,邮件 任务)
- SpringBoot 与安全
- SpringBoot 与开发热部署
- SpringBoot 与监控管理
Springboot与缓存
JSR107缓存规范
相信大家都能看得懂
使用JSR107需要导入下面的依赖包
Spring缓存抽象
代码实现
搭建基本环境
创建数据库
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`departmentName` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`lastName` VARCHAR(255) DEFAULT NULL,
`email` VARCHAR(255) DEFAULT NULL,
`gender` INT(2) DEFAULT NULL,
`d_id` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO employee(lastName,email,gender,d_id)VALUES('zhangsan','zhangsan@qq.com',1,1);
INSERT INTO employee(lastName,email,gender,d_id)VALUES('lisi','lisi@qq.com',0,2);
建两个bean实体类
package com.luyi.bean;
/**
* @author 卢意
* @create 2020-11-24 9:00
*/
public class Department {
private Integer id;
private String departmentName;
public Department() {
super();
// TODO Auto-generated constructor stub
}
public Department(Integer id, String departmentName) {
super();
this.id = id;
this.departmentName = departmentName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
@Override
public String toString() {
return "Department [id=" + id + ", departmentName=" + departmentName + "]";
}
}
package com.luyi.bean;
/**
* @author 卢意
* @create 2020-11-24 9:01
*/
public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender; //性别 1男 0女
private Integer dId;
public Employee() {
super();
}
public Employee(Integer id, String lastName, String email, Integer gender, Integer dId) {
super();
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
this.dId = dId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Integer getdId() {
return dId;
}
public void setdId(Integer dId) {
this.dId = dId;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", dId="
+ dId + "]";
}
}
application里添加Mybatis配置
spring.datasource.url=jdbc:mysql://localhost:3306/spring_cache?serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=123456
#Driver可不写,会根据连接自动添加
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#开启驼峰命名规则
mybatis.configuration.map-underscore-to-camel-case=true
#开启日志
logging.level.com.luyi.mapper=debug
新建mapper接口
package com.luyi.mapper;
import com.luyi.bean.Employee;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
/**
* @author 卢意
* @create 2020-11-24 9:04
*/
public interface EmployeeMapper {
@Select("SELECT * FROM employee WHERE id=#{id}")
Employee getEmpById(Integer id);
@Insert("INSERT INTO employee(lastName,email,gender,d_id)VALUES(#{lastName},#{email},#{gender},#{dId})")
void insertEmployee(Employee employee);
@Update("UPDATE employee SET lastName=#{lastName},email=#{email},gender=#{gender},d_id=#{dId} WHERE id=#{id}")
void updateEmp(Employee employee);
@Delete("DELETE FROM employee WHERE id=#{id}")
void deleteEmpById(Integer id);
}
新建test类
package com.luyi;
import com.luyi.mapper.EmployeeMapper;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.security.RunAs;
@SpringBootTest
@RunWith(SpringRunner.class)
class SpringbootstudyApplicationTests {
@Autowired
EmployeeMapper employeeMapper;
@Test
void contextLoads() {
employeeMapper.getEmpById(1);
}
}
查找成功
新建Employeeservice
package com.luyi.service;
import com.luyi.bean.Employee;
import com.luyi.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author 卢意
* @create 2020-11-24 9:10
*/
@Service
public class EmployeeService {
@Autowired
EmployeeMapper employeeMapper;
public Employee getEmp(Integer id){
System.out.println("查询" + id + "号员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
}
新建controller类
package com.luyi.controller;
import com.luyi.bean.Employee;
import com.luyi.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 卢意
* @create 2020-11-24 9:12
*/
@RestController
public class EmployeeController {
@Autowired
EmployeeService employeeService;
@GetMapping("/emp/{id}")
public Employee getEmployee(@PathVariable("id") Integer id){
Employee emp = employeeService.getEmp(id);
return emp;
}
}
启动项目
没加缓存时 每次访问都会调用数据库
体验缓存
主启动类加上开启缓存注解
service 放法加入缓存注解
缓存的key编写
先只用默认的注解进行测试
只查询了一次 就没有在调用数据库了
Cacheable运行流程
自动配置类导入了下面的缓存配置类
生效的缓存配置类
Cacheable其他属性
用配置类指定key
condition
第一个参数大于1 在进行缓存
unless 否定缓存 第一个参数等于2 就不缓存
sync异步模式 将返回值异步存在缓存中 不支持unless
Cacheput
既调用方法,又更新缓存
@CachePut与@Cacheable的区别
@Cacheable是先到缓存里查找有没有要查的数据,如果有就直接用缓存里的数据,不调用方法操作数据库,如果没有再调用方法操作数据库并把返回的数据保存到缓存里。(前置处理)(用于查询)
@CachePut是每次都先调用方法进行数据库操作,并把返回的数据保存到缓存里,如果缓存里已经有了就覆盖原来的数据。(后置处理)(用于修改)
运行时机:先调用目标方法,再将目标方法的返回结果保存到缓存中。(属性比@Cacheable少了一个sync,其他相同)
应用场景:修改了数据库的某个数据,同时更新缓存。
mapper里添加
@CachePut(value = "emp")
public Employee updateEmp(Employee employee){
System.out.println("updateEmp:" + employee);
employeeMapper.updateEmp(employee);
return employee;
}
EmployeeController类内添加
@GetMapping("/emp")
public Employee update(Employee employee){
Employee emp = employeeService.updateEmp(employee);
return emp;
}
CacheEvict 清除缓存
mapper添加方法
@CacheEvict(value = "emp", key = "#id")
public void deleteEmp(Integer id){
System.out.println("deleteEmp:" + id);
//数据库只有两个数据,这里就不删除了,只清理缓存中的数据
//employeeMapper.deleteEmpById(id);
}
conroller类
@GetMapping("/delemp")
public String deleteEmp(Integer id){
employeeService.deleteEmp(id);
return "success";
}
key默认使用传参的值
Caching(三合一)
全局配置 value="emp"就可以不写了
Redis
redis环境搭建
启动redis
Redis环境搭建
pom 文件添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置redis
spring.redis.host=192.168.216.138
springboot 自动配置redisTemplate
使用
Redis常见的五大数据类型
String(字符串)、List(列表)、Set(集合)、Hash(散列)、ZSet(有序集合)
stringRedisTemplate.opsForValue() String(字符串)
stringRedisTemplate.opsForList() List(列表)
stringRedisTemplate.opsForSet() Set(集合)
stringRedisTemplate.opsForHash() Hash(散列)
stringRedisTemplate.opsForZSet() ZSet(有序集合)
redisTemplate的方法和stringRedisTemplate是一样的,不同的是redisTemplate操作k-v都是对象的,而操作k-v都是字符串的
测试redisTemplate
@Test
public void test02(){
Employee employee = employeeMapper.getEmpById(1);
//如果保存对象,默认使用jdk系列化机制,系列化后的数据保存到redis中
redisTemplate.opsForValue().set("emp01", employee); //append是追加字符串的,set才是添加对象的,并且每次提交相同的key时,原来的value会被新的value覆盖
}
需要将Employee变成可序列化
默认的序列化器是jdk的
将数据以json的形式保存到redis:
自己将对象转为json(如使用gson)
修改redisTemplate默认的系列化(默认使用的是jdk的系列化器)我们想修改成json的序列化器
新建一个MyRedisConfig配置类
@Configuration
public class MyRedisConfig {
@Bean
public RedisTemplate<Object, Object> empRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
//设置默认的系列化器为Jackson2JsonRedisSerializer
template.setDefaultSerializer(serializer);
return template;
}
}
//自定义RedisTemplate
@Autowired
RedisTemplate<Object, Object> empRedisTemplate;
@Test
public void test03(){
Employee employee = employeeMapper.getEmpById(1);
empRedisTemplate.opsForValue().set("emp01", employee);
}
自定义CacheManger
现在引入了Redis 默认的缓存配置 SimpleCacheConfiguration不生效了 因为他的触发条件是没有CacheManager的类才生效
RedisCacheConfiguration的启动顺序比SimpleCacheConfiguration高 提前判断生效 放入RedisCacheManager
自定义redisCachemanager
这个样子就相当于我们容器内有了CacheManager 就不会去注册上面的默认缓存 查出来的也是默认序列化为josn的数据
新建一个Department的操作 进行缓存查询 第一次走数据库查询成功 将缓存存入
第二次走缓存查询就有问题了 上面写着无法从Department的json对象转为Emloyee的反序列化
因为这里配了Employee的序列化对象
那就只能在写一个部门的Template对象和部门的缓存管理器
使用的时候需要指定CacheManager
多个CacheManager需要定义一个主键CacheManager(默认使用)
编码的方式使用redis缓存
指定缓存管理器
SpringBoot 与消息
https://blog.csdn.net/weixin_43691773/article/details/109295391
SpringBoot 与检索
https://blog.csdn.net/weixin_43691773/article/details/109442332
SpringBoot 与任务(异步,定时,邮件 任务)
https://blog.csdn.net/weixin_43691773/article/details/109472499
SpringBoot 与安全
https://editor.csdn.net/md/?articleId=109143604
SpringBoot 与开发热部署
SpringBoot 与监控管理
各端点测试
控制台会有映射信息
尝试访问监控信息 发现没有授权
修改配置文件 将管理安全模式给关闭
从新进入
各字段功能
远程关闭程序
定制端点
更改bean的访问路径和id 都是 mybean和/mybean
也可以单独设置路径
不让beans端点被访问 需要在配置文件加入
值开启beans端点
定义端口号
自定义Healtindicator
当前健康检查 只有一个diskpace健康状态
springboot自带很多组件的健康检查
引入redis依赖个配置 就可以进行redis的健康检查
自定义健康状态指示器
标签:缓存,SpringBoot,雷锋,id,import,Employee,Integer,硅谷,public 来源: https://blog.csdn.net/weixin_43691773/article/details/110038097