Java工具类
本文最后更新于:2024年6月21日 凌晨
ChatGPT流式输出
调用ChatGPT接口,采用流式输出:
先在控制台进行流式输出,下面是效果图:
本次使用个人chagpt接口,可换乘openai:
引入okhttp3
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.1</version>
</dependency>
输出到控制台:
@GetMapping("/fast")
public Result fastChat(String msg) {
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
String jsonInputString = "{" +
"\"model\": \"chatglm2-6b\"," +
"\"messages\": [{" +
"\"role\": \"user\"," +
"\"content\": \""+msg+"\"" +
"}]," +
"\"temperature\": 0.7," +
"\"n\": 1," +
"\"max_tokens\": 1024," +
"\"stop\": []," +
"\"stream\": true," +
"\"presence_penalty\": 0," +
"\"frequency_penalty\": 0" +
"}";
RequestBody body = RequestBody.create(JSON, jsonInputString);
Request request = new Request.Builder()
.url("http://192.168.123.170:2421/chat/fastchat")
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
// 使用 InputStreamReader 和 BufferedReader 来处理UTF-8字符流
try (InputStreamReader isr = new InputStreamReader(response.body().byteStream(), StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(isr)) {
int intChar;
while ((intChar = reader.read()) != -1) {
char ch = (char) intChar;
System.out.print(ch);
Thread.sleep(50); // 延迟,以便一个接一个地输出字符
}
}
return Result.ok("Streamed successfully!");
} catch (Exception e) {
e.printStackTrace();
}
return Result.fail("fail");
}
SSE与前端进行流式输出
可以看出ChatGPT的回答方式采用的是event-stream
,及Server-Sent Events, SSE,这是一种允许服务器向客户端推送事件的技术
下面使用java与vue3进行演示
全局异常类
整体结构:
- exception
- GlobalExceptionHandler
- GlobalException
- result
- Result
- ResultCodeEnum
- 创建全局异常枚举类
ResultCodeEnum
@Getter
public enum ResultCodeEnum {
SUCCESS(200, "成功"),
FAIL(201, "失败"),
SERVICE_ERROR(2012, "服务异常"),
DATA_ERROR(204, "数据异常"),
ILLEGAL_REQUEST(205, "非法请求"),
REPEAT_SUBMIT(206, "重复提交"),
LOGIN_AUTH(208, "未登陆"),
PERMISSION(209, "没有权限");
private final Integer code;
private final String message;
private ResultCodeEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}
- 创建
Result
@Data
public class Result<T> {
// 状态码
private Integer code;
// 信息
private String message;
// 数据
private T data;
// 构造私有化
private Result() {
}
// 设置数据,返回方法
public static <T> Result<T> build(T data, Integer code, String message) {
// 创建Result对象,设置值,返回对象
Result<T> result = new Result<>();
// 判断data是否为空
if (data != null) {
// 设置数据到result对象中
result.setData(data);
}
// 设置其他值
result.setCode(code);
result.setMessage(message);
// 返回结果
return result;
}
// 成功
public static <T> Result<T> ok(T data) {
return build(data, ResultCodeEnum.SUCCESS.getCode(), ResultCodeEnum.SUCCESS.getMessage());
}
// 失败
public static <T> Result<T> fail(T data) {
return build(data, ResultCodeEnum.FAIL.getCode(), ResultCodeEnum.FAIL.getMessage());
}
}
- 创建统一异常处理类
GlobalExceptionHandler
// AOP面向切面
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e){
e.printStackTrace();
return Result.fail(null);
}
/**
* 自定义异常处理方法
* @param e
* @return
*/
@ExceptionHandler(GlobalException.class)
@ResponseBody
public Result error(GlobalException e){
return Result.build(null,e.getCode(),e.getMessage());
}
}
- 创建
GlobalException
@Data
public class GlobalException extends RuntimeException{
//异常状态码
private Integer code;
/**
* 通过状态码和错误消息创建异常对象
* @param message
* @param code
*/
public GlobalException(String message, Integer code) {
super(message);
this.code = code;
}
/**
* 接收枚举类型对象
* @param resultCodeEnum
*/
public GlobalException(ResultCodeEnum resultCodeEnum) {
super(resultCodeEnum.getMessage());
this.code = resultCodeEnum.getCode();
}
@Override
public String toString() {
return "GlobalException{" +
"code=" + code +
", message=" + this.getMessage() +
'}';
}
}
RedisUtil.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public final class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// =============================common============================
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
* @param key 键
* @param delta 要增加几(大于0)
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
* @param key 键
* @param delta 要减少几(小于0)
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
/**
* HashGet
* @param key 键 不能为null
* @param item 项 不能为null
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
* @param key 键
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
* @param key 键
* @param map 对应多个键值
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
*
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
// ============================set=============================
/**
* 根据key获取Set中的所有值
* @param key 键
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 将set数据放入缓存
*
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0)
expire(key, time);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 获取set缓存的长度
*
* @param key 键
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值为value的
*
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ===============================list=================================
/**
* 获取list缓存的内容
*
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
*
* @param key 键
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通过索引 获取list中的值
*
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
* 从头部插入leftPush
* @param key 键
* @param value 值
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().leftPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据索引修改list中的某条数据
*
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
上传图片
本地上传
本地路径方式
- 在Resource目录下有一个upload.html文件,和一个static文件夹,static下又有一个images文件夹,如下图
- upload.html
这里主要就是一个form表单,用来提交数据,但是要注意的是我这个表单用了post和enctype=”multipart/form-data”,以及input的类型是file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传图片</title>
</head>
<body>
<form action="/uplaod" method="post" enctype="multipart/form-data">
<input type="file" name="file" value="请选择你要上传的图片">
<input type="submit" value="上传">
</form>
</body>
</html>
- UploadController
为了方便演示,我把业务都放在controller,,首先我们要先分析文件上传有几步
- 文件校验(包括但不限于,图片的大小、图片的类型、图片是否为空、上传的是否是文件等)
- 将图片重命名,图片重命名又可分为以下几步
- 获取原来文件的后缀名,可以使用
file.getOriginalFilename()
获取原来的文件名 - 生成一个随机的新文件名,这里可以使用
UUID.randomUUID()
- 把新名称和原后缀名拼接起来作为新的文件名
- 获取原来文件的后缀名,可以使用
- 把图片上传的指定的目录下,我们这里讲的是Resource,就以Resource为例
new ApplicationHome(this.getClass())
可以获取当前程序运行的主页- 我们知道Java程序都是运行的.class字节码文件,所以
getDir()
获取文件夹位置其实是.class字节码文件的位置,需要使用getParentFile()
两次回到项目的主目录 - 获取到主目录的绝对路径拼接上从这里到Resource下的images
- 最后通过
file.transferTo(new File(path));
把文件上传到Resource下的images目录,并且返回一个url地址
package com.wang.upload.controller;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
* @version: java version 1.8
* @Author: WWJ
* @description:
* @date: 2023-02-17 23:41
*/
@RestController
public class UploadController {
@PostMapping("/upload")
public String UploadFile(MultipartFile file) {
if (file.isEmpty()) {
return "上传文件为空";
}
String originalFilename = file.getOriginalFilename();
//获取原来的文件名和后缀
String ext = "." + originalFilename.split("\\.")[1];
//生成一个新的文件名(以防有重复的名字存在导致被覆盖)
String uuid = UUID.randomUUID().toString().replace("-", "");
String newName = uuid + ext;
ApplicationHome applicationHome = new ApplicationHome(this.getClass());
String pre = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath() +
"\\src\\main\\resources\\static\\images\\";
String path = pre + newName;
try {
file.transferTo(new File(path));
} catch (IOException e) {
e.printStackTrace();
return "上传失败";
}
return path;
}
}
云服务器上传
OSS对象存储
创建Bucket
- 名称:随便起
- 地域:想你的服务器在哪就选哪个(也是随便选)
- 存储类型:标准存储
- 冗余存储:关闭
- 版本控制:关闭
- 读写权限:公共读写
代码
- 导入依赖
<!-- 阿里云oss依赖 --> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.9.1</version> </dependency> <!-- 日期工具栏依赖 --> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.10.1</version> </dependency>
在
applcation.yml文件中配置
:keyid与keysecret可以在阿里云的账号的AccessKey管理中,进行创建aliyun: endpoint: oss-cn-shanghai.aliyuncs.com keyid: xxxxxxxx keysecret: xxxxxxxxxxxxxxxx bucketname: xxxxxxx
如果创建的是子用户,一定要赋予该角色OSS权限控制
FileUploadController
@Api(tags = "文件上传接口") @RestController @RequestMapping("/upload") public class FileUploadController { @Autowired private FileUploadService fileUploadService; @ApiOperation("图片上传") @PostMapping("/fileUpload") public Result fileUpload(MultipartFile file) { String url = fileUploadService.uploadFile(file); return Result.ok(url); } }
FileUploadServiceImpl
@Service public class FileUploadServiceImpl implements FileUploadService { @Value("${aliyun.endpoint}") private String endPoint; @Value("${aliyun.keyid}") private String accessId; @Value("${aliyun.keysecret}") private String secreKey; @Value("${aliyun.bucketname}") private String bucketName; @Override public String uploadFile(MultipartFile file) { OSS ossClient = new OSSClientBuilder().build(endPoint, accessId, secreKey); try { // 上传文件流。 InputStream inputStream = file.getInputStream(); String fileName = file.getOriginalFilename(); //生成随机唯一值,使用uuid,添加到文件名称里面 String uuid = UUID.randomUUID().toString().replaceAll("-",""); fileName = uuid+fileName; //按照当前日期,创建文件夹,上传到创建文件夹里面 // 2023/02/02/01.jpg String timeUrl = new DateTime().toString("yyyy/MM/dd"); fileName = timeUrl+"/"+fileName; //调用方法实现上传 ossClient.putObject(bucketName, fileName, inputStream); // 关闭OSSClient。 ossClient.shutdown(); //上传之后文件路径 // https://wjwang.oss-cn-shanghai.aliyuncs.com/01.jpg return "https://"+bucketName+"."+endPoint+"/"+fileName; } catch (IOException e) { e.printStackTrace(); return null; } } }
文件大小报错异常
在SpringBoot的application.yml中配置
spring:
servlet:
multipart:
max-file-size: 100MB
max-request-size: 1000MB
MyBatis Plus
代码生成器
使用MyBatis Plus
,安装依赖
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
CodeGet.java
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
/**
* @author Wjwang
* @description 代码生成工具
* @date 2023/9/23 16:55:01
*/
public class CodeGet {
public static void main(String[] args) {
// 1、创建代码生成器
AutoGenerator mpg = new AutoGenerator();
// 2、全局配置
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setOutputDir("D:\\Project\\code\\test\\service\\service-admin\\src\\main\\java");
gc.setServiceName("%sService"); //去掉Service接口的首字母I
gc.setAuthor("Wjwang");
gc.setOpen(false);
mpg.setGlobalConfig(gc);
// 3、数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&useSSL=false");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
// 4、包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.wjwang");
pc.setModuleName("admin"); //模块名
pc.setController("controller");
pc.setService("service");
pc.setMapper("mapper");
mpg.setPackageInfo(pc);
// 5、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("user_info","admin_info");
strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作
strategy.setRestControllerStyle(true); //restful api风格控制器
strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符
mpg.setStrategy(strategy);
// 6、执行
mpg.execute();
}
}
分页插件
创建config.MybatisPlusConfig
,编写MybatisPlusConfig.java
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* MybatisPlus配置类
*/
@EnableTransactionManagement
@Configuration
@MapperScan("com.wjwang.*.mapper") // 根据项目结构引入
public class MybatisPlusConfig {
/**
* mp插件
*/
@Bean
public MybatisPlusInterceptor optimisticLockerInnerInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//向Mybatis过滤器链中添加分页拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
在Json格式中插入当前时间
// payload 为JSON格式数据
String payload = message.getPayload().toString();
获取当前时间
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = formatter.format(date);
JSONObject jsonObject = JSON.parseObject(payload);
在JSON中插入k,v对
jsonObject.put("time", time);
// 存入Redis缓存数据库中
redisUtil.lSet("sensor", jsonObject.toString());
解析JSON格式数据
JSON格式数据,通过key,获取value
Object massage = redisUtil.lGetIndex("sensor", 0);
JSONObject jsonObject = JSON.parseObject(massage.toString());
String sn = jsonObject.getString("SN");
BigDecimal temp = jsonObject.getBigDecimal("Temp");
BigDecimal humidity = jsonObject.getBigDecimal("Humidity");
String time = jsonObject.getString("time");
启动banner
${AnsiColor.BRIGHT_YELLOW}${AnsiStyle.BOLD}
////////////////////////////////////////////////////////////////////
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //
////////////////////////////////////////////////////////////////////
${AnsiColor.CYAN}${AnsiStyle.BOLD}
:: Java:${java.version}
:: Spring Boot Version: ${spring-boot.version}
${AnsiStyle.NORMAL}
Java工具类
https://junyyds.top/2023/05/17/Java工具类/