一、什么是springboot
约定大于配置是springboot的核心用来简化配置的一个框架
Spring Boot 将日常企业应用研发中的各种场景都抽取出来,做成一个个的 starter(启动器),starter 中整合了该场景下各种可能用到的依赖,用户只需要在 Maven 中引入 starter 依赖,SpringBoot 就能自动扫描到要加载的信息并启动相应的默认配置。starter 提供了大量的自动配置,让用户摆脱了处理各种依赖和配置的困扰。所有这些 starter 都遵循着约定成俗的默认配置,并允许用户调整这些配置,即遵循“约定大于配置”的原则。
二、Swagger
作用
是一个动态生成接口文档的一个框架,用于和前端或测试岗位的同事进行对接。
实现案例
<!--导入swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--swagger用来生成前端页面-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2,新建一个config文件夹并新建以下文件
SwaggerConfig.java
package com.xxgc.helloworld.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.w3c.dom.DocumentType;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
//是否开启前端ui显示 生产环境调为false
.enable(true)
.select()
//扫描有哪些接口(controller)要生成文档
.apis(RequestHandlerSelectors.basePackage("com.xxgc.helloworld.controller"))
//接口中所有路径都扫描
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
//api文档标题
.title("HelloWorld工程")
//文档描述
.description("工程文档描述")
//服务条款url
.termsOfServiceUrl("https://www.baidu.com")
//版本号
.version("1.0.0")
.build();
}
}
InterceptorConfig.java
package com.xxgc.helloworld.config;
import com.xxgc.helloworld.interceptor.JWTInterceptors;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
/**
* @program: helloword
* @description: 拦截器配置
* @author: liutao
* @create: 2022-03-07 16:11
**/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
//配置拦截器规则
public void addInterceptors(InterceptorRegistry registry){
//swagger相关
ArrayList<String> swagger = new ArrayList<>();
swagger.add("/*.html");
swagger.add("/swagger-resources/**");
swagger.add("/webjars/**");
swagger.add("/v2/**");
swagger.add("/swagger-ui.html/**");
}
}
3,使用
controller.java
package com.xxgc.helloworld.controller;
import com.xxgc.helloworld.po.Info;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@PropertySource(value = "classpath:system.properties")
@RequestMapping("/info")
@Api(value="hello接口",tags ="用于返回helloworld",description = "测试helloworld")
public class HelloController {
@Value("${system.name}")
private String system;
@ApiOperation(value = "获取helloworld",notes = "获取helloworld")
@GetMapping("/hello")
@ResponseBody
public Info hello(){
return new Info(200,system+"hello world");
}
@ApiOperation(value = "给什么返回什么",notes = "你给什么返回什么")
@GetMapping("/getMsg")
@ResponseBody
public Info getMsg(@ApiParam(name="msg",value="信息",required = true) String msg){
return new Info(-201,msg);
}
}
效果图
三、springboot热部署
pom.xml
<!--Springboot热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
application.yml
spring:
devtools:
restart:
enabled: true #开启热部署
additional-paths: src/main/java #重启的目录
四、JWT
介绍
JSON Web Token(JWT)是一种开放标准,用于作为Web应用中的令牌,用于在各方之间安全地将信息作为JSON对象传输。在数据传输中完成数据加密、签名等相关处理。
实现前后端分离就用JWT
Jwt的核心是什么:一种信息交换,一种是用来做javaweb中的安全验证
流程
-
用户使用用户名密码请求服务器
-
服务器验证用户信息
-
服务器通过验证发送给用户一个token
-
客户端存储token,并每次请求时附带一个token值
-
服务器验证token并返回数据
实现案例
1,在pom.xml里导入依赖配置
<!-- 导入jwt-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.18.3</version>
</dependency>
2,新建一个po文件夹里面存放下面两个Java文件
info.java
package com.xxgc.helloworld.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
//Lombok自动生成set get方法
@Data
//全参构造
@AllArgsConstructor
//无参构造
@NoArgsConstructor
public class Info {
//返回状态码
private Integer code;
//返回信息
private String msg;
//返回的数据
private Object data;
//版本号
private String version;
//请求响应时间
private Date ResponseDate;
public Info(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Info(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
}
TokenInfo.java
package com.xxgc.helloworld.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @program: helloworld
* @description: token返回
* @author: liutao
* @create: 2022-03-07 17:25
**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TokenInfo {
/**
* 返回状态码
* 401 登录过期 或未登录
* -202 无效签名
* -203 算法不一致
* -204 token无效
*/
private Integer code;
//返回信息
private String message;
}
3,新建一个config文件夹并新建以下文件
InterceptorConfig.java
package com.xxgc.helloworld.config;
import com.xxgc.helloworld.interceptor.JWTInterceptors;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
/**
* @program: helloword
* @description: 拦截器配置
* @author: liutao
* @create: 2022-03-07 16:11
**/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
//配置拦截器规则
public void addInterceptors(InterceptorRegistry registry){
//swagger相关
ArrayList<String> swagger = new ArrayList<>();
swagger.add("/*.html");
swagger.add("/swagger-resources/**");
swagger.add("/webjars/**");
swagger.add("/v2/**");
swagger.add("/swagger-ui.html/**");
//jwt 相关
registry.addInterceptor(new JWTInterceptors())
.addPathPatterns("/**")//需要进行token验证的
.excludePathPatterns("/login/namePassLogin")//放行的
.excludePathPatterns(swagger);//放行swagger相关
}
}
4,新建一个interceptors文件夹
JWTInterceptors.java
package com.xxgc.helloworld.interceptor;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xxgc.helloworld.po.TokenInfo;
import com.xxgc.helloworld.utils.JWTUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @program: helloworld
* @description: JWT拦截器
* @author: liutao
* @create: 2022-03-07 15:55
**/
public class JWTInterceptors implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
TokenInfo info = new TokenInfo();
// 获取请求头中令牌
String token = request.getHeader("token");
try {
JWTUtils.verify(token);// 验证令牌
return true; // 放行请求
} catch (SignatureVerificationException e) {
info.setCode(-202);
info.setMessage("无效签名");
}catch (TokenExpiredException e){
info.setCode(401);
info.setMessage("登录过期");
}catch (AlgorithmMismatchException e){
info.setCode(-203);
info.setMessage("算法不一致");
}catch (Exception e){
info.setCode(-204);
info.setMessage("token无效");
}
// 将map以json的形式响应到前台 map --> json (jackson)
String json = new ObjectMapper().writeValueAsString(info);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
return false;
}
}
5,新建utils文件夹
JWTUtils.java
package com.xxgc.helloworld.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
/**
* @program: helloword
* @description: JWT工具类
* @author: liutao
* @create: 2022-03-07 15:20
**/
public class JWTUtils {
/**
* 加密和解密使用的密钥
* */
private static final String SING = "NIUYEYE";
//用于获取token
public static String getToken(Map<String,String> map){
Calendar instance = Calendar.getInstance();
//配置令牌失效时间 20秒后失效 (项目当中一般30分钟)
instance.add(Calendar.DATE,1);
//创建jwt
JWTCreator.Builder builder = JWT.create();
map.forEach((k,v) ->{
builder.withClaim(k,v);
});
String token = builder
.withExpiresAt(instance.getTime())//过期时间
.sign(Algorithm.HMAC256(SING));//签名
return token;
}
//合法性 校验
public static DecodedJWT verify(String token){
return JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
}
}
6,调用
在用户登录成功以后生成token
package com.xxgc.helloworld.service.Impl;
import com.xxgc.helloworld.bean.Users;
import com.xxgc.helloworld.bean.UsersExample;
import com.xxgc.helloworld.dao.UsersMapper;
import com.xxgc.helloworld.po.Info;
import com.xxgc.helloworld.service.ILoginService;
import com.xxgc.helloworld.utils.JWTUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.HashMap;
import java.util.List;
@Service
public class LoginService implements ILoginService {
//业务逻辑层和dao层关联
@Autowired
private UsersMapper um;
//ctrl + q
@Override
public Info namePassLogin(Users u) {
UsersExample example = new UsersExample();
example.createCriteria()
.andUsernameEqualTo(u.getUsername())
.andPasswordEqualTo(u.getPassword());
//alt+shift+l ctrl+alt+v 生成返回结果
List<Users> users = um.selectByExample(example);
//判断是否为空
if (CollectionUtils.isEmpty(users)) {
return new Info(-200, "用户名或密码错误");
} else {
HashMap<String, String> map = new HashMap<>();
map.put("username",users.get(0).getUsername());
String token= JWTUtils.getToken(map);
map.put("token",token);
return new Info(200, "登录成功", map);
}
}
}
7,登录返回token
没有token时访问,因为被拦截器拦截不能被放行
当携带token时正常访问
五、Quartz 框架(石英)
cron表达式
3,6,9,12每月1号 6点检查数据库
秒 分钟 小时 日 月 星期 年
0 0 6 1 3,6,9,12 ? *
例子 每个月5号9点执行
0 0 9 5 * ? *
QuickStart
创建job文件夹
SendMsgJob.java
package com.xxgc.helloworld.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Date;
/**
* @program: helloworld
* @description: 发送信息的打工人
* @author: liutao
* @create: 2022-03-08 19:00
**/
//alt + enter*3
public class SendMsgJob implements Job {
//可以在这里做一些资源配置
private void before(){
System.out.println("任务开始之前");
}
//最终执行方法
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("发送信息:你好"+ new Date());
}
//可以在这释放资源
private void after(){
System.out.println("任务结束过后");
}
}
创建scheduler文件夹
QuartzScheduler.java
package com.xxgc.helloworld.scheduler;
import com.xxgc.helloworld.job.SendMsgJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @program: helloword
* @description: 任务调度器
* @author: liutao
* @create: 2022-03-08 19:08
**/
@Slf4j
@Component
public class QuartzScheduler {
//工作名
private static final String JOB_NAME = "msg_report";
private static final String JOB_GROUP = "msg_report_group";
//触发器名
private static final String TRIGGER_NAME = "msg_report";
private static final String TRIGGER_GROUP = "msg_report_group";
//工作任务id
private static final String JOB_TASK_ID = "msg_task_id";
private SchedulerFactory schedulerFactory= new StdSchedulerFactory();
/**
* quartz 任务调度器
*/
// @Autowired
private Scheduler scheduler;
/**
* 初始化注入一下调度器
*/
public QuartzScheduler() throws SchedulerException {
scheduler = schedulerFactory.getScheduler();
}
/**
* 开始所有任务的方法
*/
public void startJob() throws SchedulerException {
scheduler.start();
}
public void add(int i,String cron) throws SchedulerException{
//你想给打工人传的话
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("msg","好好工作,过年我买大奔");
// newJob 新建一个工作
// usingJobData 给工作的打工人传值
// withIdentity 工作的名称
JobDetail jobDetail = JobBuilder
.newJob(SendMsgJob.class)
.usingJobData(jobDataMap)
.withIdentity(JOB_NAME + i, JOB_GROUP).build();
//调度时机 打工时机
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
// newTrigger 创建一个触发器
// withIdentity 触发器名
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity(TRIGGER_NAME + i, TRIGGER_GROUP)
.withSchedule(cronScheduleBuilder)
.build();
//把打工人和调度器进行绑定
scheduler.scheduleJob(jobDetail,cronTrigger);
}
//移除任务 拯救打工人
public boolean remove(int i) throws SchedulerException{
boolean b = scheduler.deleteJob(new JobKey(JOB_NAME + i, JOB_GROUP));
return b;
}
}
项目启动开始打工
启动入口
package com.xxgc.helloworld.listener;
import com.xxgc.helloworld.scheduler.QuartzScheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
/**
* @program: helloworld
* @description: 项目启动开始打工
* @author: liutao
* @create: 2022-03-08 19:51a
**/
@Configuration
public class QuartzStartListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private QuartzScheduler quartzScheduler;
// 项目启动会调用这个方法
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
try {
quartzScheduler.startJob();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
实现案例
1,在pom.xml里导入依赖配置
<!--任务调度器-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
2,导入数据库表
DROP TABLE
IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE
IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE
IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE
IF EXISTS QRTZ_LOCKS;
DROP TABLE
IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE
IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE
IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE
IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE
IF EXISTS QRTZ_TRIGGERS;
DROP TABLE
IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE
IF EXISTS QRTZ_CALENDARS;
CREATE TABLE QRTZ_JOB_DETAILS (
SCHED_NAME VARCHAR (120) NOT NULL,
JOB_NAME VARCHAR (200) NOT NULL,
JOB_GROUP VARCHAR (200) NOT NULL,
DESCRIPTION VARCHAR (250) NULL,
JOB_CLASS_NAME VARCHAR (250) NOT NULL,
IS_DURABLE VARCHAR (1) NOT NULL,
IS_NONCONCURRENT VARCHAR (1) NOT NULL,
IS_UPDATE_DATA VARCHAR (1) NOT NULL,
REQUESTS_RECOVERY VARCHAR (1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (
SCHED_NAME,
JOB_NAME,
JOB_GROUP
)
) ENGINE = INNODB;
CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR (120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL,
TRIGGER_GROUP VARCHAR (200) NOT NULL,
JOB_NAME VARCHAR (200) NOT NULL,
JOB_GROUP VARCHAR (200) NOT NULL,
DESCRIPTION VARCHAR (250) NULL,
NEXT_FIRE_TIME BIGINT (13) NULL,
PREV_FIRE_TIME BIGINT (13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR (16) NOT NULL,
TRIGGER_TYPE VARCHAR (8) NOT NULL,
START_TIME BIGINT (13) NOT NULL,
END_TIME BIGINT (13) NULL,
CALENDAR_NAME VARCHAR (200) NULL,
MISFIRE_INSTR SMALLINT (2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
),
FOREIGN KEY (
SCHED_NAME,
JOB_NAME,
JOB_GROUP
) REFERENCES QRTZ_JOB_DETAILS (
SCHED_NAME,
JOB_NAME,
JOB_GROUP
)
) ENGINE = INNODB;
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR (120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL,
TRIGGER_GROUP VARCHAR (200) NOT NULL,
REPEAT_COUNT BIGINT (7) NOT NULL,
REPEAT_INTERVAL BIGINT (12) NOT NULL,
TIMES_TRIGGERED BIGINT (10) NOT NULL,
PRIMARY KEY (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
),
FOREIGN KEY (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
)
) ENGINE = INNODB;
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR (120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL,
TRIGGER_GROUP VARCHAR (200) NOT NULL,
CRON_EXPRESSION VARCHAR (120) NOT NULL,
TIME_ZONE_ID VARCHAR (80),
PRIMARY KEY (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
),
FOREIGN KEY (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
)
) ENGINE = INNODB;
CREATE TABLE QRTZ_SIMPROP_TRIGGERS (
SCHED_NAME VARCHAR (120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL,
TRIGGER_GROUP VARCHAR (200) NOT NULL,
STR_PROP_1 VARCHAR (512) NULL,
STR_PROP_2 VARCHAR (512) NULL,
STR_PROP_3 VARCHAR (512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC (13, 4) NULL,
DEC_PROP_2 NUMERIC (13, 4) NULL,
BOOL_PROP_1 VARCHAR (1) NULL,
BOOL_PROP_2 VARCHAR (1) NULL,
PRIMARY KEY (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
),
FOREIGN KEY (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
)
) ENGINE = INNODB;
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR (120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL,
TRIGGER_GROUP VARCHAR (200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
),
INDEX (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
),
FOREIGN KEY (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
)
) ENGINE = INNODB;
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR (120) NOT NULL,
CALENDAR_NAME VARCHAR (200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME, CALENDAR_NAME)
) ENGINE = INNODB;
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR (120) NOT NULL,
TRIGGER_GROUP VARCHAR (200) NOT NULL,
PRIMARY KEY (SCHED_NAME, TRIGGER_GROUP)
) ENGINE = INNODB;
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR (120) NOT NULL,
ENTRY_ID VARCHAR (95) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL,
TRIGGER_GROUP VARCHAR (200) NOT NULL,
INSTANCE_NAME VARCHAR (200) NOT NULL,
FIRED_TIME BIGINT (13) NOT NULL,
SCHED_TIME BIGINT (13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR (16) NOT NULL,
JOB_NAME VARCHAR (200) NULL,
JOB_GROUP VARCHAR (200) NULL,
IS_NONCONCURRENT VARCHAR (1) NULL,
REQUESTS_RECOVERY VARCHAR (1) NULL,
PRIMARY KEY (SCHED_NAME, ENTRY_ID)
) ENGINE = INNODB;
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR (120) NOT NULL,
INSTANCE_NAME VARCHAR (200) NOT NULL,
LAST_CHECKIN_TIME BIGINT (13) NOT NULL,
CHECKIN_INTERVAL BIGINT (13) NOT NULL,
PRIMARY KEY (SCHED_NAME, INSTANCE_NAME)
) ENGINE = INNODB;
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR (120) NOT NULL,
LOCK_NAME VARCHAR (40) NOT NULL,
PRIMARY KEY (SCHED_NAME, LOCK_NAME)
) ENGINE = INNODB;
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS (
SCHED_NAME,
REQUESTS_RECOVERY
);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS (SCHED_NAME, JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS (
SCHED_NAME,
JOB_NAME,
JOB_GROUP
);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS (SCHED_NAME, JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS (SCHED_NAME, CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP,
TRIGGER_STATE
);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_GROUP,
TRIGGER_STATE
);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS (SCHED_NAME, NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_STATE,
NEXT_FIRE_TIME
);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS (
SCHED_NAME,
MISFIRE_INSTR,
NEXT_FIRE_TIME
);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS (
SCHED_NAME,
MISFIRE_INSTR,
NEXT_FIRE_TIME,
TRIGGER_STATE
);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS (
SCHED_NAME,
MISFIRE_INSTR,
NEXT_FIRE_TIME,
TRIGGER_GROUP,
TRIGGER_STATE
);
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS (
SCHED_NAME,
INSTANCE_NAME,
REQUESTS_RECOVERY
);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS (
SCHED_NAME,
JOB_NAME,
JOB_GROUP
);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, TRIGGER_GROUP);
COMMIT;
3,在application.yml里进行配置
#quartz的持久化配置
quartz:
#相关属性配置
properties:
org:
quartz:
scheduler:
instanceName: quartzScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: false
clusterCheckinInterval: 10000
useProperties: false
dataSource: quartzDs
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
#数据库方式
job-store-type: JDBC
#初始化表结构
jdbc:
initialize-schema: NEVER
#数据源配置
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/springboot-study?useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
4,创建job文件夹创建一个job
SendMsgJob.java
package com.xxgc.helloworld.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Date;
/**
* @program: helloworld
* @description: 发送信息的打工人
* @author: liutao
* @create: 2022-03-08 19:00
**/
//alt + enter*3
public class SendMsgJob implements Job {
//可以在这里做一些资源配置
private void before(){
System.out.println("任务开始之前");
}
//最终执行方法
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("发送信息:你好"+ new Date());
}
//可以在这释放资源
private void after(){
System.out.println("任务结束过后");
}
}
5,创建config文件夹添加以下文件
QuartzStartListener.java
package com.xxgc.helloworld.config;
import com.xxgc.helloworld.scheduler.QuartzScheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
/**
* @program: helloworld
* @description: 项目启动开始打工
* @author: liutao
* @create: 2022-03-08 19:51a
**/
@Configuration
public class QuartzStartListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private QuartzScheduler quartzScheduler;
// 项目启动会调用这个方法
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
try {
quartzScheduler.startJob();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
5,创建一个utils文件夹添加以下文件
QuartzManagerUtils.java
package com.xxgc.helloworld.utils;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Map;
/**
* @program: helloword
* @description: 任务调度器工具类
* @author: liutao
* @create: 2022-03-08 21:03
**/
public class QuartzManagerUtils {
private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory(); //创建一个SchedulerFactory工厂实例
private static final String JOB_GROUP_NAME = "FH_JOBGROUP_NAME"; //任务组
private static final String TRIGGER_GROUP_NAME = "FH_TRIGGERGROUP_NAME"; //触发器组
/**添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
* @param jobName 任务名
* @param cls 任务
* @param time 时间设置,参考quartz说明文档
*/
public static void addJob(String jobName, Class<? extends Job> cls, String time) {
try {
Scheduler sched = gSchedulerFactory.getScheduler(); //通过SchedulerFactory构建Scheduler对象
JobDetail jobDetail= JobBuilder.newJob(cls).withIdentity(jobName,JOB_GROUP_NAME).build(); //用于描叙Job实现类及其他的一些静态信息,构建一个作业实例
CronTrigger trigger = (CronTrigger) TriggerBuilder
.newTrigger() //创建一个新的TriggerBuilder来规范一个触发器
.withIdentity(jobName, TRIGGER_GROUP_NAME) //给触发器起一个名字和组名
.withSchedule(CronScheduleBuilder.cronSchedule(time))
.build();
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start(); // 启动
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**添加一个定时任务,使用默认的任务组名,触发器名,触发器组名 (带参数)
* @param jobName 任务名
* @param cls 任务
* @param time 时间设置,参考quartz说明文档
*/
public static void addJob(String jobName, Class<? extends Job> cls, String time, Map<String,Object> parameter) {
try {
Scheduler sched = gSchedulerFactory.getScheduler(); //通过SchedulerFactory构建Scheduler对象
JobDetail jobDetail= JobBuilder.newJob(cls).withIdentity(jobName,JOB_GROUP_NAME).build(); //用于描叙Job实现类及其他的一些静态信息,构建一个作业实例
jobDetail.getJobDataMap().put("parameterList", parameter); //传参数
CronTrigger trigger = (CronTrigger) TriggerBuilder
.newTrigger() //创建一个新的TriggerBuilder来规范一个触发器
.withIdentity(jobName, TRIGGER_GROUP_NAME) //给触发器起一个名字和组名
.withSchedule(CronScheduleBuilder.cronSchedule(time))
.build();
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start(); // 启动
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**添加一个定时任务
* @param jobName 任务名
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param jobClass 任务
* @param time 时间设置,参考quartz说明文档
*/
public static void addJob(String jobName, String jobGroupName,
String triggerName, String triggerGroupName, Class<? extends Job> jobClass,
String time) {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName,jobGroupName).build();// 任务名,任务组,任务执行类
CronTrigger trigger = (CronTrigger) TriggerBuilder // 触发器
.newTrigger()
.withIdentity(triggerName, triggerGroupName)
.withSchedule(CronScheduleBuilder.cronSchedule(time))
.build();
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start(); // 启动
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**添加一个定时任务 (带参数)
* @param jobName 任务名
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param jobClass 任务
* @param time 时间设置,参考quartz说明文档
*/
public static void addJob(String jobName, String jobGroupName,
String triggerName, String triggerGroupName, Class<? extends Job> jobClass,
String time, Map<String,Object> parameter) {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName,jobGroupName).build();// 任务名,任务组,任务执行类
jobDetail.getJobDataMap().put("parameterList", parameter); //传参数
CronTrigger trigger = (CronTrigger) TriggerBuilder // 触发器
.newTrigger()
.withIdentity(triggerName, triggerGroupName)
.withSchedule(CronScheduleBuilder.cronSchedule(time))
.build();
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start(); // 启动
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/** 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)
* @param jobName 任务名
* @param time 新的时间设置
*/
public static void modifyJobTime(String jobName, String time) {
try {
Scheduler sched = gSchedulerFactory.getScheduler(); //通过SchedulerFactory构建Scheduler对象
TriggerKey triggerKey = TriggerKey.triggerKey(jobName,TRIGGER_GROUP_NAME); //通过触发器名和组名获取TriggerKey
CronTrigger trigger = (CronTrigger)sched.getTrigger(triggerKey); //通过TriggerKey获取CronTrigger
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(time)) {
JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME); //通过任务名和组名获取JobKey
JobDetail jobDetail = sched.getJobDetail(jobKey);
Class<? extends Job> objJobClass = jobDetail.getJobClass();
removeJob(jobName);
addJob(jobName, objJobClass, time);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**修改一个任务的触发时间
* @param triggerName 任务名称
* @param triggerGroupName 传过来的任务名称
* @param time 更新后的时间规则
*/
public static void modifyJobTime(String triggerName, String triggerGroupName, String time) {
try {
Scheduler sched = gSchedulerFactory.getScheduler(); //通过SchedulerFactory构建Scheduler对象
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName,triggerGroupName); //通过触发器名和组名获取TriggerKey
CronTrigger trigger = (CronTrigger)sched.getTrigger(triggerKey); //通过TriggerKey获取CronTrigger
if (trigger == null) return;
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(trigger.getCronExpression());
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(time)) {
trigger = (CronTrigger)trigger.getTriggerBuilder() //重新构建trigger
.withIdentity(triggerKey)
.withSchedule(scheduleBuilder)
.withSchedule(CronScheduleBuilder.cronSchedule(time))
.build();
sched.rescheduleJob(triggerKey, trigger); //按新的trigger重新设置job执行
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**移除一个任务(使用默认的任务组名,触发器名,触发器组名)
* @param jobName 任务名称
*/
public static void removeJob(String jobName) {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName,TRIGGER_GROUP_NAME); //通过触发器名和组名获取TriggerKey
JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME); //通过任务名和组名获取JobKey
sched.pauseTrigger(triggerKey); // 停止触发器
sched.unscheduleJob(triggerKey);// 移除触发器
sched.deleteJob(jobKey); // 删除任务
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**移除一个任务
* @param jobName 任务名
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
*/
public static void removeJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName) {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName,triggerGroupName); //通过触发器名和组名获取TriggerKey
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName); //通过任务名和组名获取JobKey
sched.pauseTrigger(triggerKey); // 停止触发器
sched.unscheduleJob(triggerKey);// 移除触发器
sched.deleteJob(jobKey); // 删除任务
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 启动所有定时任务
*/
public static void startJobs() {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 关闭所有定时任务
*/
public static void shutdownJobs() {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
if (!sched.isShutdown()) {
sched.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
6,使用
QuartzScheduler.java
@Test
public void test1() throws SchedulerException, InterruptedException {
/* 2022年 3月 8日 20时 20分 0秒开始 每5秒执行一次 */
QuartzManagerUtils.addJob("打工仔", SendMsgJob.class,"0/3 * * * * ? *");
Thread.sleep(500000);
}
效果
六、Redis
1,在pom.xml里导入依赖配置
<!--redis相关-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
2,核心配置文件
application.yml
#Redis配置
redis:
host: 127.0.0.1
port: 6379
#没用就填空
password:
jedis:
pool:
#连接池最大连接数
max-active: 8
#阻塞时间 (负表示没有)
max-wait: -1
#最大空闲连接
max-idle: 8
#最小空闲连接
min-idle: 0
#连接超时时间
timeout: 30000
3,创建config文件夹添加以下文件
RedisConfig.java
package com.xxgc.helloworld.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import java.lang.reflect.Method;
import java.time.Duration;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.jedis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.jedis.pool.max-wait}")
private int maxWait;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.min-idle}")
private int minIdle;
@Bean
public KeyGenerator wiselyKeyGenerator(){
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(host);
factory.setPort(port);
factory.setTimeout(timeout); //设置连接超时时间
factory.setPassword(password);
factory.getPoolConfig().setMaxIdle(maxIdle);
factory.getPoolConfig().setMinIdle(minIdle);
factory.getPoolConfig().setMaxTotal(maxActive);
factory.getPoolConfig().setMaxWaitMillis(maxWait);
return factory;
}
// 管理缓存
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl( Duration.ofHours(1)); // 设置缓存有效期一小时
return RedisCacheManager
.builder( RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration).build();
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口
template.afterPropertiesSet();
return template;
}
private void setSerializer(StringRedisTemplate template) {
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
}
}
4,创建utils文件夹添加以下文件
RedisUtils.java
package com.xxgc.helloworld.utils;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
/**
* @Program: HelloWorld
* @ClassName RedisUtils
* @Description: Redis工具类
* @Author: liutao
* @DateTime: 2022/3/11 10:40
* @Version: 1.0
*/
@Service
public class RedisUtils {
@Autowired
private RedisTemplate redisTemplate;
/**
* 写入缓存
*
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 写入缓存设置时效时间
*
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value, Long expireTime, TimeUnit timeUnit) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, timeUnit);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 批量删除对应的value
*
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量删除key
*
* @param pattern
*/
public void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0) {
redisTemplate.delete(keys);
}
}
/**
* 删除对应的value
*
* @param key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判断缓存中是否有对应的value
*
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存
*
* @param key
* @return
*/
public Object get(final String key) {
Object result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
return result;
}
/**
* 哈希 添加
*
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key, hashKey, value);
}
/**
* 哈希获取数据
*
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.get(key, hashKey);
}
/**
* 列表添加
*
* @param k
* @param v
*/
public void lPush(String k, Object v) {
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush(k, v);
}
/**
* 列表获取
*
* @param k
* @param l
* @param l1
* @return
*/
public List<Object> lRange(String k, long l, long l1) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.range(k, l, l1);
}
/**
* 集合添加
*
* @param key
* @param value
*/
public void add(String key, Object value) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key, value);
}
/**
* 集合获取
*
* @param key
* @return
*/
public Set<Object> setMembers(String key) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
* 有序集合添加
*
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key, Object value, double scoure) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key, value, scoure);
}
/**
* 有序集合获取
*
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
}
5,使用测试
package com.xxgc.helloworld.util;
import com.xxgc.helloworld.utils.RedisUtils;
import org.junit.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;
/**
* @Program: HelloWorld
* @ClassName RedisUtilsTest
* @Description: Redis测试类
* @Author: liutao
* @DateTime: 2022/3/11 12:19
* @Version: 1.0
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisUtilsTest {
@Autowired
RedisUtils redisUtils;
@Test
public void test(){
//往缓存设置值
boolean a = redisUtils.set("name", 123456);
System.out.println("a = " + a);
}
@Test
public void test1(){
Integer name = (Integer) redisUtils.get("name");
System.out.println("name = " + name);
}
}
效果