一、mysql连接的配置—mybatis-plus设置
application.yml配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/db?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
username: root
password: "密码"
@SpringBootApplication
@MapperScan(basePackages = "com.springboottest.springboottest.mappers") //扫描的类,但是xml也要在同包下面,不在就要自己配置xml扫描了
用到的poml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springbootTest</groupId>
<artifactId>springbootTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootTest</name>
<description>springbootTest</description>
<properties>
<java.version>8</java.version>
<fastjson.version>1.2.66</fastjson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
<!--<dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>2.3.0</version>-->
<!--</dependency>-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
每层类要实现的接口
//mapper层
public interface UserMapper extends BaseMapper<User>
//service层
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService
public interface UserService extends IService<User>
//entity类
public class User implements Serializable
二、OKhttp配置-----请求发送
poml配置
<!--okhttp-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.2.0</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
OKHttpUtils类
package com.springboottest.springboottest.utils;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author 豆子
* @create 2023-09-21 12:32
*/
public class OKHttpUtils {
/**
* 请求超时时间5秒
*/
private static final int TIME_OUT_SECONDS = 8;
private static Logger logger = LoggerFactory.getLogger(OKHttpUtils.class);
private static OkHttpClient.Builder getClientBuilder() {
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder().followRedirects(false).retryOnConnectionFailure(false);
clientBuilder.connectTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS).readTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS);
return clientBuilder;
}
private static Request.Builder getRequestBuilder(Map<String, String> header) {
Request.Builder requestBuilder = new Request.Builder();
if (null != header) {
for (Map.Entry<String, String> map : header.entrySet()) {
String key = map.getKey();
String value;
if (map.getValue() == null) {
value = "";
} else {
value = map.getValue();
}
requestBuilder.addHeader(key, value);
}
}
return requestBuilder;
}
private static FormBody.Builder getBuilder(Map<String, String> params) {
FormBody.Builder builder = new FormBody.Builder();
if (params == null) {
return builder;
}
for (Map.Entry<String, String> map : params.entrySet()) {
String key = map.getKey();
String value;
if (map.getValue() == null) {
value = "";
} else {
value = map.getValue();
}
builder.add(key, value);
}
return builder;
}
public static String getRequest(String url){
ResponseBody responseBody = null;
try {
OkHttpClient.Builder clientBuilder = getClientBuilder();
Request.Builder requestBuilder = getRequestBuilder(null);
OkHttpClient client = clientBuilder.build();
Request request = requestBuilder.url(url).build();
Response response = client.newCall(request).execute();
responseBody = response.body();
String responseStr = responseBody.string();
logger.info("postRequest请求地址:{},返回信息:{}", url, responseStr);
return responseStr;
} catch (SocketTimeoutException | ConnectException e) {
logger.error("OKhttp POST 请求超时,url:{}", url, e);
throw new RuntimeException("超时");
} catch (Exception e) {
logger.error("OKhttp GET 请求异常", e);
return null;
} finally {
if (responseBody != null) {
responseBody.close();
}
}
}
public static String postRequest(String url, Map<String, String> params){
ResponseBody body = null;
try {
if (params == null) {
params = new HashMap<>();
}
OkHttpClient.Builder clientBuilder =
new OkHttpClient.Builder().followRedirects(false).retryOnConnectionFailure(false);
clientBuilder.connectTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS).readTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS);
OkHttpClient client = clientBuilder.build();
FormBody.Builder builder = new FormBody.Builder();
RequestBody requestBody = null;
for (Map.Entry<String, String> map : params.entrySet()) {
String key = map.getKey();
String value;
if (map.getValue() == null) {
value = "";
} else {
value = map.getValue();
}
builder.add(key, value);
}
requestBody = builder.build();
Request.Builder requestBuilder = new Request.Builder();
Request request = requestBuilder.url(url).post(requestBody).build();
Response response = client.newCall(request).execute();
body = response.body();
String responseStr = body.string();
logger.info("postRequest请求地址:{},参数:{},返回信息:{}", url, JsonUtils.convertObj2Json(params), responseStr);
return responseStr;
} catch (SocketTimeoutException | ConnectException e) {
logger.error("OKhttp POST 请求超时,url:{},请求参数:{}", url, JsonUtils.convertObj2Json(params), e);
throw new RuntimeException("超市化");
} catch (Exception e) {
logger.error("OKhttp POST 请求异常,url:{},请求参数:{}", url, JsonUtils.convertObj2Json(params), e);
return null;
} finally {
if (body != null) {
body.close();
}
}
}
public static String postRequestJson(String url, String jsonParams){
ResponseBody body = null;
try {
if (jsonParams == null) {
jsonParams = "{}";
}
OkHttpClient.Builder clientBuilder =
new OkHttpClient.Builder().followRedirects(false).retryOnConnectionFailure(false);
clientBuilder.connectTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS).readTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS);
OkHttpClient client = clientBuilder.build();
MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
RequestBody requestBody = RequestBody.create(mediaType, jsonParams);
Request.Builder requestBuilder = new Request.Builder();
Request request = requestBuilder.url(url).post(requestBody).build();
Response response = client.newCall(request).execute();
body = response.body();
String responseStr = body.string();
logger.info("postRequest请求地址:{},参数:{},返回信息:{}", url, jsonParams, responseStr);
return responseStr;
} catch (SocketTimeoutException | ConnectException e) {
logger.error("OKhttp POST 请求超时,url:{},请求参数:{}", url, jsonParams, e);
throw new RuntimeException("请求超时");
} catch (Exception e) {
logger.error("OKhttp POST 请求异常,url:{},请求参数:{}", url, jsonParams , e);
return null;
} finally {
if (body != null) {
body.close();
}
}
}
}
JsonUtils类型,进行类型转化使用
package com.springboottest.springboottest.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class JsonUtils {
private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);
public static String convertObj2Json(Object obj) {
return JSON.toJSONString(obj);
}
public static <T> T convertJson2Obj(String json, Class<T> classz) {
return JSONObject.parseObject(json, classz);
}
public static <T> List<T> convertJsonArray2List(String json, Class<T> classz) {
return JSONArray.parseArray(json, classz);
}
public static void main(String[] args) {
}
}
使用方式
@SpringBootTest(classes = {com.springboottest.springboottest.SpringbootTestApplication.class})
class SpringbootTestApplicationTests {
@Autowired
private UserController userController;
@Test
void contextLoads() {
User userById = userController.getUserById(2);
System.out.println(userById);
userById.setId(6);
userById.setUsername("zhangsan");
userById.setPassword("05");
userById.setName("zhangdai");
//int i = userController.insertUserByid(userById);
//System.out.println(i);
String request = OKHttpUtils.getRequest("http://localhost:8080/getUserList");
System.out.println(request);
String userInfo = JsonUtils.convertObj2Json(userById);
OKHttpUtils.getRequest("http://localhost:8080/delUser/6");
String s = OKHttpUtils.postRequestJson("http://localhost:8080/inserUser", userInfo);
System.out.println(s);
}
}
三、Redis配置
pom文件
<!--redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.6.1</version>
</dependency>
redis的配置信息
#Spring redis配置
spring:
redis:
# Redis数据库索引(默认为0)
database: 5
host: 127.0.0.1
port: 6379
# 连接超时时间(毫秒)
connect-timeout: 2000
jedis:
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0
RedisUtil工具类
package com.springboottest.springboottest.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
@Component
//redis的工具类,操作redis的工具类底层还是使用了StringRedisTemplate,工具类 template依赖于这个maven工具包spring-boot-starter-data-redis
public class RedisUtil {
//这里使用这个模版对象的因为如果
//使用RedisTemplate对象的话,对象保存到缓存中的时候,会包对应的对象类型一起缓存起来,使得内存开销户变大,但是可以通过配置redis的序列化器,来进行转化,可以去解决
//这个StringRedisTempale是平时用的多的,我们用到对象类型的时候需要手动的将其进行转化json在进行保存,反序列化也是将其进行自动转换可以使用ObjectMapper进行json的转化,或者fastJson进行转化
private final StringRedisTemplate stringRedisTemplate;
@Autowired //通过构成函数的形式进行自动注入
public RedisUtil(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
// *********************************************** key相关操作 start
/**
* 删除key
*/
public void delete(String key) {
stringRedisTemplate.delete(key); //del key
}
/**
* 批量删除key
*/
public void delete(Collection<String> keys) {
stringRedisTemplate.delete(keys); //del key1 key2 key3 ...
}
/**
* 序列化key
*/
public byte[] dump(String key) {
return stringRedisTemplate.dump(key); //DUMP key
}
/**
* 是否存在key
*/
public Boolean hasKey(String key) {
return stringRedisTemplate.hasKey(key); //EXISTS key
}
/**
* 设置过期时间
*/
public Boolean expire(String key, long timeout, TimeUnit unit) {
return stringRedisTemplate.expire(key, timeout, unit); //EXPIRE key seconds
}
/**
* 获取过期时间
* @return
*/
public Long ttl(String key) {
return stringRedisTemplate.opsForValue().getOperations().getExpire(key); //TTL key
}
/**
* 设置过期时间
*/
public Boolean expireAt(String key, Date date) {
return stringRedisTemplate.expireAt(key, date); //EXPIREAT key timestamp 命令用来设置键的过期时间点
}
/**
* 查找匹配的key
*/
public Set<String> keys(String pattern) {
return stringRedisTemplate.keys(pattern); //KEYS pattern
}
/**
* 将当前数据库的 key 移动到给定的数据库 db 当中
*/
public Boolean move(String key, int dbIndex) {
return stringRedisTemplate.move(key, dbIndex); //MOVE key db db为指定的索引
}
/**
* 移除 key 的过期时间,key 将持久保持,使得key进行持久化
*/
public Boolean persist(String key) {
return stringRedisTemplate.persist(key); //PERSIST key 设置持久化
}
/**
* 返回 key 的剩余的过期时间
*/
public Long getExpire(String key, TimeUnit unit) {
return stringRedisTemplate.getExpire(key, unit); //ttl keys 和上面差不多的
}
/**
* 返回 key 的剩余的过期时间
*/
public Long getExpire(String key) {
return stringRedisTemplate.getExpire(key); //ttl keys
}
/**
* 从当前数据库中随机返回一个 key
*/
public String randomKey() {
return stringRedisTemplate.randomKey(); //randomkey
}
/**
* 修改 key 的名称
*/
public void rename(String oldKey, String newKey) {
stringRedisTemplate.rename(oldKey, newKey); //rename weather tianqi
}
/**
* 仅当 newkey 不存在时,将 oldKey 改名为 newkey
*/
public Boolean renameIfAbsent(String oldKey, String newKey) {
return stringRedisTemplate.renameIfAbsent(oldKey, newKey); //renamenx oldkey newkey
}
/**
* 返回 key 所储存的值的类型
*/
public DataType type(String key) {
return stringRedisTemplate.type(key); //type key
}
//*************************************************string相关操作
/**
* 设置指定 key 的值
*/
public void set(String key, String value) {
stringRedisTemplate.opsForValue().set(key, value); //set key value
}
/**
* setnx设置指定 key 的值
*/
public Boolean setNx(String key, String value) {
return stringRedisTemplate.opsForValue().setIfAbsent(key, value); //如果key不存在才会进行设置值 setnx key value
}
/**
* setnx设置指定设置指定 key 的值
*/
public Boolean setNx(String key, String value, Long timeOut, TimeUnit unit) {
return stringRedisTemplate.opsForValue().setIfAbsent(key, value, timeOut, unit); //设置过期时间 SET key value EX NX
// PX milliseconds 启动ex表示单位为秒, px表示过期时间为毫秒两者选择其一
//set name3 dou ex 10 nx
// set name5 hh px 3000 nx
}
/**
* 设置指定 key 的值并设置有效期
*/
public void set(String key, String value, long timeout, TimeUnit unit) {
stringRedisTemplate.opsForValue().set(key, value, timeout, unit); //SET key value PX|ex 秒数, 和上面的那个一样
}
/**
* 获取指定 key 的值
*/
public String get(String key) {
return stringRedisTemplate.opsForValue().get(key); // get key
}
/**
* 返回 key 中字符串值的子字符
*/
public String getRange(String key, long start, long end) {
return stringRedisTemplate.opsForValue().get(key, start, end); //redis还可以获取字符串类型中的指定位置的子串 getrange key start end 范围为[start, end]
}
/**
* 将给定 key 的值设为 value ,并返回 key 的旧值(old value)
*/
public String getAndSet(String key, String value) {
return stringRedisTemplate.opsForValue().getAndSet(key, value); //对key的进行修改并且放回旧的值 GETSET key value
}
/**
* 对 key 所储存的字符串值,获取指定偏移量上的位(bit)
*/
public Boolean getBit(String key, long offset) {
return stringRedisTemplate.opsForValue().getBit(key, offset); //GETBIT key offset
}
/**
* 批量获取
*/
public List<String> multiGet(Collection<String> keys) {
return stringRedisTemplate.opsForValue().multiGet(keys); //批量获取可以 MGET key1 key2 key3 ...
}
/**
* 设置ASCII码, 字符串'a'的ASCII码是97, 转为二进制是'01100001', 此方法是将二进制第offset位值变为value
*/
public boolean setBit(String key, long offset, boolean value) {
return stringRedisTemplate.opsForValue().setBit(key, offset, value); //SETBIT key offset value
}
/**
* 将值 value 关联到 key ,并将 key 的过期时间设为 timeout
*/
public void setEx(String key, String value, long timeout, TimeUnit unit) {
stringRedisTemplate.opsForValue().set(key, value, timeout, unit); //SET key value PX milliseconds
}
/**
* 只有在 key 不存在时设置 key 的值
*/
public boolean setIfAbsent(String key, String value) {
return stringRedisTemplate.opsForValue().setIfAbsent(key, value); //SETNX key value
}
/**
* 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始
*/
public void setRange(String key, String value, long offset) {
stringRedisTemplate.opsForValue().set(key, value, offset); //SETRANGE key offset value
}
/**
* 获取字符串的长度
*/
public Long size(String key) {
return stringRedisTemplate.opsForValue().size(key); //STRLEN key
}
/**
* 批量添加
*/
public void multiSet(Map<String, String> maps) {
stringRedisTemplate.opsForValue().multiSet(maps); //MSET key1 value1 key2 value2 ...
}
/**
* 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在
*/
public boolean multiSetIfAbsent(Map<String, String> maps) {
return stringRedisTemplate.opsForValue().multiSetIfAbsent(maps); //MSETNX key1 value1 key2 value2 ...
}
/**
* 增加(自增长), 负数则为自减
*/
public Long incrBy(String key, long increment) {
return stringRedisTemplate.opsForValue().increment(key, increment); //INCRBY key increment
}
/**
* 增加(自增长), 负数则为自减 浮点数
*/
public Double incrByFloat(String key, double increment) {
return stringRedisTemplate.opsForValue().increment(key, increment); //INCRBY key increment
}
/**
* 追加到末尾
*/
public Integer append(String key, String value) {
return stringRedisTemplate.opsForValue().append(key, value); //APPEND key value
}
//**************************************************hash相关操作
/**
* 获取存储在哈希表中指定字段的值
*/
public Object hGet(String key, String field) {
return stringRedisTemplate.opsForHash().get(key, field); //HGET key field
}
/**
* 获取所有给定字段的值
*/
public Map<Object, Object> hGetAll(String key) {
return stringRedisTemplate.opsForHash().entries(key); //hgetall key
}
/**
* 获取所有给定字段的值
*/
public List<Object> hMultiGet(String key, Collection<Object> fields) {
return stringRedisTemplate.opsForHash().multiGet(key, fields); //HMGET key field1 field2 ...
}
public void hPut(String key, String hashKey, String value) {
stringRedisTemplate.opsForHash().put(key, hashKey, value); //HSET key hashKey value
}
public void hPutAll(String key, Map<String, String> maps) {
stringRedisTemplate.opsForHash().putAll(key, maps); //HMSET key field1 value1 field2 value2 ...
}
public Boolean hPutAll(String key, Map<String, String> maps, long timeout, TimeUnit unit) {
stringRedisTemplate.opsForHash().putAll(key, maps); //HMSET key field1 value1 field2 value2 ...
return expire(key, timeout, unit); //EXPIRE key seconds
}
/**
* 仅当hashKey不存在时才设置
*/
public Boolean hPutIfAbsent(String key, String hashKey, String value) {
return stringRedisTemplate.opsForHash().putIfAbsent(key, hashKey, value); //HSETNX key field value
}
/**
* put一个值并设置过期时间
*/
public Boolean hPutAndExpire(String key, String hashKey, String value, long timeout, TimeUnit unit) {
Boolean boo = stringRedisTemplate.opsForHash().putIfAbsent(key, hashKey, value); //HSETNX key field value
expire(key, timeout, unit); //EXPIRE key seconds
return boo;
}
/**
* 删除一个或多个哈希表字段
*/
public Long hDelete(String key, Object... fields) {
return stringRedisTemplate.opsForHash().delete(key, fields); //HDEL key field1 field2 ...
}
/**
* 查看哈希表 key 中,指定的字段是否存在
*/
public boolean hExists(String key, String field) {
return stringRedisTemplate.opsForHash().hasKey(key, field); //HEXISTS key field
}
/**
* 为哈希表 key 中的指定字段的整数值加上增量 increment
*/
public Long hIncrBy(String key, Object field, long increment) {
return stringRedisTemplate.opsForHash().increment(key, field, increment); //HINCRBY key field increment
}
/**
* 为哈希表 key 中的指定字段的整数值加上增量 increment
*/
public Double hIncrByFloat(String key, Object field, double delta) {
return stringRedisTemplate.opsForHash().increment(key, field, delta); //HINCRBY key field increment
}
/**
* 获取所有哈希表中的字段
*/
public Set<Object> hKeys(String key) {
return stringRedisTemplate.opsForHash().keys(key); //HKEYS key
}
/**
* 获取哈希表中字段的数量
*/
public Long hSize(String key) {
return stringRedisTemplate.opsForHash().size(key); //HLEN key
}
/**
* 获取哈希表中所有值
*/
public List<Object> hValues(String key) {
return stringRedisTemplate.opsForHash().values(key); //HVALS key
}
/**
* 迭代哈希表中的键值对
*/
public Cursor<Entry<Object, Object>> hScan(String key, ScanOptions options) {
Cursor<Entry<Object, Object>> scan = stringRedisTemplate.opsForHash().scan(key, options); //HSCAN key cursor [MATCH pattern] [COUNT count]
return scan;
}
//**********************************************list相关操作
/**
* 通过索引获取列表中的元素
*/
public String lIndex(String key, long index) {
return stringRedisTemplate.opsForList().index(key, index); //LINDEX key index
}
/**
* 获取列表指定范围内的元素
*/
public List<String> lRange(String key, long start, long end) {
return stringRedisTemplate.opsForList().range(key, start, end); //LRANGE key start end
}
/**
* 存储在list头部
*/
public Long lLeftPush(String key, String value) {
return stringRedisTemplate.opsForList().leftPush(key, value); //LPUSH key value
}
/**
* 存储在list头部
*/
public Long lLeftPushAll(String key, String... value) {
return stringRedisTemplate.opsForList().leftPushAll(key, value); //LPUSH key value1 value2 ...
}
/**
* 存储在list头部
*/
public Long lLeftPushAll(String key, Collection<String> value) {
return stringRedisTemplate.opsForList().leftPushAll(key, value); //LPUSH key value1 value2 ...
}
/**
* 当list存在的时候才加入
*/
public Long lLeftPushIfPresent(String key, String value) {
return stringRedisTemplate.opsForList().leftPushIfPresent(key, value); //LPUSHX key value
}
/**
* 如果pivot存在,再pivot前面添加
*/
public Long lLeftPush(String key, String pivot, String value) {
return stringRedisTemplate.opsForList().leftPush(key, pivot, value); //LINSERT key BEFORE|AFTER pivot value
}
/**
* 存储在list尾部
*/
public Long lRightPush(String key, String value) {
return stringRedisTemplate.opsForList().rightPush(key, value); //RPUSH key value
}
/**
* 存储在list尾部
*/
public Long lRightPushAll(String key, String... value) {
return stringRedisTemplate.opsForList().rightPushAll(key, value); //RPUSH key value1 value2 ...
}
/**
* 存储在list尾部
*/
public Long lRightPushAll(String key, Collection<String> value) {
return stringRedisTemplate.opsForList().rightPushAll(key, value); //RPUSH key value1 value2 ...
}
/**
* 为已存在的列表添加值
*/
public Long lRightPushIfPresent(String key, String value) {
return stringRedisTemplate.opsForList().rightPushIfPresent(key, value); //RPUSHX key value1
}
/**
* 在pivot元素的右边添加值
*/
public Long lRightPush(String key, String pivot, String value) {
return stringRedisTemplate.opsForList().rightPush(key, pivot, value); //RINSERT key BEFORE|AFTER pivot value
}
/**
* 通过索引设置列表元素的值
*/
public void lSet(String key, long index, String value) {
stringRedisTemplate.opsForList().set(key, index, value); //LSET key index value
}
/**
* 移出并获取列表的第一个元素
*/
public String lLeftPop(String key) {
return stringRedisTemplate.opsForList().leftPop(key); //LPOP key
}
/**
* 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
*/
public String lBLeftPop(String key, long timeout, TimeUnit unit) {
return stringRedisTemplate.opsForList().leftPop(key, timeout, unit); //BLPOP key timeout
}
/**
* 移除并获取列表最后一个元素
*/
public String lRightPop(String key) {
return stringRedisTemplate.opsForList().rightPop(key); //RPOP key
}
/**
* 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
*/
public String lBRightPop(String key, long timeout, TimeUnit unit) {
return stringRedisTemplate.opsForList().rightPop(key, timeout, unit); //RLPOP key timeout
}
/**
* 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
*/
public String lRightPopAndLeftPush(String sourceKey, String destinationKey) {
return stringRedisTemplate.opsForList().rightPopAndLeftPush(sourceKey, //RPOPLPUSH sourceKey destinationKey
destinationKey);
}
/**
* 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
*/
public String lBRightPopAndLeftPush(String sourceKey, String destinationKey,
long timeout, TimeUnit unit) {
return stringRedisTemplate.opsForList().rightPopAndLeftPush(sourceKey, //BRPOPLPUSH sourceKey destinationKey timeout
destinationKey, timeout, unit);
}
/**
* 删除集合中值等于value得元素
*/
public Long lRemove(String key, long index, String value) {
return stringRedisTemplate.opsForList().remove(key, index, value); //LREM key count value
}
/**
* 裁剪list
*/
public void lTrim(String key, long start, long end) {
stringRedisTemplate.opsForList().trim(key, start, end); //LTRIM key start stop
}
/**
* 获取列表长度
*/
public Long lLen(String key) {
return stringRedisTemplate.opsForList().size(key); //LLEN key
}
/** --------------------set相关操作-------------------------- */
/**
* set添加元素
*/
public Long sAdd(String key, String... values) {
return stringRedisTemplate.opsForSet().add(key, values); //SADD key value1 value2 ...
}
/**
* set移除元素
*/
public Long sRemove(String key, Object... values) {
return stringRedisTemplate.opsForSet().remove(key, values); //SREM key member1 member2 ...
}
/**
* 移除并返回集合的一个随机元素
*/
public String sPop(String key) {
return stringRedisTemplate.opsForSet().pop(key); //SPOP key
}
/**
* 将元素value从一个集合移到另一个集合
*/
public Boolean sMove(String key, String value, String destKey) {
return stringRedisTemplate.opsForSet().move(key, value, destKey); //SMOVE source destination member
}
/**
* 获取集合的大小
*/
public Long sSize(String key) {
return stringRedisTemplate.opsForSet().size(key); //SCARD key
}
/**
* 判断集合是否包含value
*/
public Boolean sIsMember(String key, Object value) {
return stringRedisTemplate.opsForSet().isMember(key, value); //SISMEMBER key member
}
/**
* 获取两个集合的交集
*/
public Set<String> sIntersect(String key, String otherKey) {
return stringRedisTemplate.opsForSet().intersect(key, otherKey); //SINTER key otherKey
}
/**
* 获取key集合与多个集合的交集
*/
public Set<String> sIntersect(String key, Collection<String> otherKeys) {
return stringRedisTemplate.opsForSet().intersect(key, otherKeys); //SINTER key otherKey
}
/**
* key集合与otherKey集合的交集存储到destKey集合中
*/
public Long sIntersectAndStore(String key, String otherKey, String destKey) {
return stringRedisTemplate.opsForSet().intersectAndStore(key, otherKey, //SINTERSTORE destKey key otherKey 比较key和otherkey并保存key到destkey中
destKey);
}
/**
* key集合与多个集合的交集存储到destKey集合中
*/
public Long sIntersectAndStore(String key, Collection<String> otherKeys,
String destKey) {
return stringRedisTemplate.opsForSet().intersectAndStore(key, otherKeys, //SINTERSTORE destKey key1 key2 ... keyN
destKey);
}
/**
* 获取两个集合的并集
*/
public Set<String> sUnion(String key, String otherKeys) {
return stringRedisTemplate.opsForSet().union(key, otherKeys); //SUNIONSTORE destination key [key ...]
}
/**
* 获取key集合与多个集合的并集
*/
public Set<String> sUnion(String key, Collection<String> otherKeys) {
return stringRedisTemplate.opsForSet().union(key, otherKeys); //SUNION key1 key2 ... keyN
}
/**
* key集合与otherKey集合的并集存储到destKey中
*/
public Long sUnionAndStore(String key, String otherKey, String destKey) {
return stringRedisTemplate.opsForSet().unionAndStore(key, otherKey, destKey); //SUNIONSTORE destKey key otherKey
}
/**
* key集合与多个集合的并集存储到destKey中
*/
public Long sUnionAndStore(String key, Collection<String> otherKeys,
String destKey) {
return stringRedisTemplate.opsForSet().unionAndStore(key, otherKeys, destKey); //SUNIONSTORE destKey key otherKey
}
/**
* 获取两个集合的差集
*/
public Set<String> sDifference(String key, String otherKey) {
return stringRedisTemplate.opsForSet().difference(key, otherKey); //SDIFF key otherKey
}
/**
* 获取key集合与多个集合的差集
*/
public Set<String> sDifference(String key, Collection<String> otherKeys) {
return stringRedisTemplate.opsForSet().difference(key, otherKeys); //SDIFF key1 key2 ... keyN
}
/**
* key集合与otherKey集合的差集存储到destKey中
*/
public Long sDifference(String key, String otherKey, String destKey) {
return stringRedisTemplate.opsForSet().differenceAndStore(key, otherKey, //SDIFFSTORE destKey key otherKey
destKey);
}
/**
* key集合与多个集合的差集存储到destKey中
*/
public Long sDifference(String key, Collection<String> otherKeys,
String destKey) {
return stringRedisTemplate.opsForSet().differenceAndStore(key, otherKeys, //SDIFFSTORE destKey key1 key2 ... keyN
destKey);
}
/**
* 获取集合所有元素
*/
public Set<String> setMembers(String key) {
return stringRedisTemplate.opsForSet().members(key); //SMEMBERS key
}
/**
* 随机获取集合中的一个元素
*/
public String sRandomMember(String key) {
return stringRedisTemplate.opsForSet().randomMember(key); //SRANDMEMBER key
}
/**
* 随机获取集合中count个元素
*/
public List<String> sRandomMembers(String key, long count) {
return stringRedisTemplate.opsForSet().randomMembers(key, count); //SRANDMEMBER key count
}
/**
* 随机获取集合中count个元素并且去除重复的
*/
public Set<String> sDistinctRandomMembers(String key, long count) {
return stringRedisTemplate.opsForSet().distinctRandomMembers(key, count); //SRANDMEMBER key count
}
/**
* 使用迭代器获取元素
*/
public Cursor<String> sScan(String key, ScanOptions options) {
return stringRedisTemplate.opsForSet().scan(key, options); //SSCAN key cursor [MATCH pattern] [COUNT count]
}
//******************************************************zSet相关操作
/**
* 添加元素,有序集合是按照元素的score值由小到大排列
*/
public Boolean zAdd(String key, String value, double score) {
return stringRedisTemplate.opsForZSet().add(key, value, score); //ZADD key score member
}
/**
* 添加元素,zSet按score由小到大排列
*/
public Long zAdd(String key, Set<TypedTuple<String>> values) {
return stringRedisTemplate.opsForZSet().add(key, values); //ZADD key score1 member1 score2 member2 ...
}
/**
* 移除
*/
public Long zRemove(String key, Object... values) {
return stringRedisTemplate.opsForZSet().remove(key, values); //ZREM key member1 member2 ...
}
/**
* 增加元素的score值,并返回增加后的值
*/
public Double zIncrementScore(String key, String value, double delta) {
return stringRedisTemplate.opsForZSet().incrementScore(key, value, delta); //ZINCRBY key increment member
}
/**
* 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列
*/
public Long zRank(String key, Object value) {
return stringRedisTemplate.opsForZSet().rank(key, value); //ZRANK key value
}
/**
* 返回元素在集合的排名,按元素的score值由大到小排列
*/
public Long zReverseRank(String key, Object value) {
return stringRedisTemplate.opsForZSet().reverseRank(key, value); //ZREVRANK key value
}
/**
* 获取集合的元素, 从小到大排序
*/
public Set<String> zRange(String key, long start, long end) {
return stringRedisTemplate.opsForZSet().range(key, start, end); //ZRANGE key start end
}
/**
* 获取集合元素, 并且把score值也获取
*/
public Set<TypedTuple<String>> zRangeWithScores(String key, long start, long end) {
return stringRedisTemplate.opsForZSet().rangeWithScores(key, start, end); //ZRANGE key start end WITHSCORES
}
/**
* 根据Score值查询集合元素
*/
public Set<String> zRangeByScore(String key, double min, double max) {
return stringRedisTemplate.opsForZSet().rangeByScore(key, min, max); //ZRANGEBYSCORE key min max
}
/**
* 根据Score值查询集合元素, 从小到大排序
*/
public Set<TypedTuple<String>> zRangeByScoreWithScores(String key, double min, double max) {
return stringRedisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max); //ZRANGEBYSCORE key min max WITHSCORES
}
/**
* 根据score查询元素,s开始e结束位置
*/
public Set<TypedTuple<String>> zRangeByScoreWithScores(String key, double min, double max, long start, long end) {
return stringRedisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max, start, end); //ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
}
/**
* 获取集合的元素, 从大到小排序
*/
public Set<String> zReverseRange(String key, long start, long end) {
return stringRedisTemplate.opsForZSet().reverseRange(key, start, end); //ZREVRANGE key start end
}
/**
* 获取集合的元素, 从大到小排序, 并返回score值
*/
public Set<TypedTuple<String>> zReverseRangeWithScores(String key, long start, long end) {
return stringRedisTemplate.opsForZSet().reverseRangeWithScores(key, start, end); //ZREVRANGE key start end WITHSCORES
}
/**
* 根据Score值查询集合元素, 从大到小排序
*/
public Set<String> zReverseRangeByScore(String key, double min, double max) {
return stringRedisTemplate.opsForZSet().reverseRangeByScore(key, min, max); //ZREVRANGEBYSCORE key max min
}
/**
* 根据Score值查询集合元素, 从大到小排序
*/
public Set<TypedTuple<String>> zReverseRangeByScoreWithScores(String key, double min, double max) {
return stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max); //ZREVRANGEBYSCORE key max min WITHSCORES
}
/**
* 根据score查询,大到小,s开始e结束
*/
public Set<String> zReverseRangeByScore(String key, double min, double max, long start, long end) {
return stringRedisTemplate.opsForZSet().reverseRangeByScore(key, min, max, start, end); //ZREVRANGEBYSCORE key max min [LIMIT offset count]
}
/**
* 根据score值获取集合元素数量
*/
public Long zCount(String key, double min, double max) {
return stringRedisTemplate.opsForZSet().count(key, min, max); //ZCOUNT key min max
}
/**
* 获取集合大小
*/
public Long zSize(String key) {
return stringRedisTemplate.opsForZSet().size(key); //ZCARD key
}
/**
* 获取集合大小
*/
public Long zZCard(String key) {
return stringRedisTemplate.opsForZSet().zCard(key); //ZCARD key
}
/**
* 获取集合中value元素的score值
*/
public Double zScore(String key, Object value) {
return stringRedisTemplate.opsForZSet().score(key, value); //ZSCORE key value
}
/**
* 移除指定索引位置的成员
*/
public Long zRemoveRange(String key, long start, long end) {
return stringRedisTemplate.opsForZSet().removeRange(key, start, end); //ZREM key start end
}
/**
* 根据指定的score值的范围来移除成员
*/
public Long zRemoveRangeByScore(String key, double min, double max) {
return stringRedisTemplate.opsForZSet().removeRangeByScore(key, min, max); //ZREMRANGEBYSCORE key min max
}
/**
* 获取key和otherKey的并集并存储在destKey中
*/
public Long zUnionAndStore(String key, String otherKey, String destKey) {
return stringRedisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey); //ZUNIONSTORE destKey numkeys key1 key2 ... keyN [AGGREGATE SUM|MIN|MAX]
}
/**
* 获取key和多个集合并集并存在dKey中
*/
public Long zUnionAndStore(String key, Collection<String> otherKeys, String destKey) {
return stringRedisTemplate.opsForZSet().unionAndStore(key, otherKeys, destKey); //ZUNIONSTORE destKey numkeys key1 key2 ... keyN [AGGREGATE SUM|MIN|MAX]
}
/**
* 交集
*/
public Long zIntersectAndStore(String key, String otherKey, String destKey) {
return stringRedisTemplate.opsForZSet().intersectAndStore(key, otherKey, destKey); //ZINTERSTORE destKey numkeys key1 key2 ... keyN WEIGHTS weight1 weight2 ... weightN AGGREGATE SUM|MIN|MAX
}
/**
* 交集
*/
public Long zIntersectAndStore(String key, Collection<String> otherKeys, String destKey) {
return stringRedisTemplate.opsForZSet().intersectAndStore(key, otherKeys, destKey); //ZINTERSTORE destKey numkeys key1 key2 ... keyN WEIGHTS weight1 weight2 ... weightN AGGREGATE SUM|MIN|MAX
}
/**
* 使用迭代器获取
*/
public Cursor<TypedTuple<String>> zScan(String key, ScanOptions options) {
return stringRedisTemplate.opsForZSet().scan(key, options); //ZSCAN key cursor [MATCH pattern] [COUNT count] key 是有序集合的键名。
}
//*************************************************HyperLogLog相关操作
/**
* HyperLogLog添加 这个就是和set很像,不断的去添加元素,重复的不用计入,保存元素后,只能知道所有存的数据有不重复的个数是多少
* 如{1,2,3,3,3,5} 存入之后,这个种类型就只能去获取到有有4个不重复的元素,返回值就是4这个数而已
* @param key
* @param value
* @return
*/
// Redis在2.8.9版本中添加了HyperLogLog数据结构
public Long pfAdd(String key, String value) {
return this.stringRedisTemplate.opsForHyperLogLog().add(key, value); //PFADD key element
}
/**
* HyperLogLog统计
* @param key
* @return
*/
public Long pfCount(String key) {
return this.stringRedisTemplate.opsForHyperLogLog().size(key); //PFCOUNT key
}
}
四、redisson锁
pom文件
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.13.4</version>
</dependency>
package com.springboottest.springboottest.config;
import lombok.Data;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "spring.redis")
@Data
//@EnableConfigurationProperties(RedissionConfig.class)
public class RedissionConfig {
private String host;
private String port;
private String password;
@Bean
public RedissonClient getRedisson(){
Config config = new Config();
config.useSingleServer()
.setAddress("redis://" + host + ":" + port + "")
//.setPassword(password)
.setRetryInterval(50000)
.setTimeout(100000)
.setConnectTimeout(100000);
return Redisson.create(config);
}
}
@Service
public class GoodServiceImpl extends ServiceImpl<GoodMapper, Good> implements GoodService {
@Resource
private GoodMapper goodMapper;
@Resource
private RedissonClient redissonClient;
public void addOrder(int id){
//获取锁
RLock lock = redissonClient.getLock("id:" + id);
try {
//尝试加锁
boolean b = lock.tryLock(5, TimeUnit.SECONDS);
if(!b){
return;
}
Good good = goodMapper.selectById(id);
if (good.getNum() > 0) {
baseMapper.setNum(id, good.getNum() - 1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//释放锁
lock.unlock();
}
}
}