提交 e5f932db 编写于 作者: 程序猿小亮's avatar 程序猿小亮

添加 redis cache模块

上级 8ee91957
......@@ -13,6 +13,8 @@
<module>springboot-hello</module>
<module>springboot-jdbc</module>
<module>springboot-mybatis</module>
<module>springboot-redis</module>
<module>springboot-cache</module>
</modules>
......
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot-leaning</artifactId>
<groupId>com.liang.springboot</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springboot-cache</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.liang;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
/**
* @PROJECT_NAME: springboot-leaning
* @USER: yuliang
* @DESCRIPTION:
* @DATE: 2021-06-30 15:47
*/
@SpringBootApplication
public class CacheApplication {
public static void main(String[] args) {
SpringApplication.run(CacheApplication.class, args);
}
}
package com.liang.config;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
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.serializer.*;
/**
* @PROJECT_NAME: springboot-leaning
* @USER: yuliang
* @DESCRIPTION:
* @DATE: 2021-07-01 15:02
*/
@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching
public class CacheConfig {
/**
* 配置文件中的东西没有用上;
* 1、原来文件中的东西没有用上
* @ConfigurationProperties(prefix = "spring.cache")
* public class CacheProperties {
*
* 2、要让他生效
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,CacheProperties cacheProperties){
//缓存配置对象
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration = redisCacheConfiguration
//序列化方式:new GenericJackson2JsonRedisSerializer();
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new FastJsonRedisSerializer<>(Object.class)));
CacheProperties.Redis redisProperties = cacheProperties.getRedis();
if (redisProperties.getTimeToLive() != null) {
redisCacheConfiguration = redisCacheConfiguration.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
redisCacheConfiguration = redisCacheConfiguration.prefixCacheNameWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
redisCacheConfiguration = redisCacheConfiguration.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
redisCacheConfiguration = redisCacheConfiguration.disableKeyPrefix();
}
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration).build();
}
}
package com.liang.dao;
import com.liang.domain.User;
import java.util.List;
public interface IUserDao {
int getTotalCount();
User getUser(Integer userId);
void insertUser(User u);
List<User> getUsers();
void updateUserNameById(Integer userId, String name);
void deleteUser(Integer userId);
User updateUser(User user);
}
package com.liang.dao;
import com.liang.domain.User;
import com.liang.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @PROJECT_NAME: springboot-leaning
* @USER: yuliang
* @DESCRIPTION:
* @DATE: 2021-07-01 14:25
*/
@Repository
@CacheConfig(cacheNames = "users")
public class UserDao implements IUserDao{
@Autowired
private UserMapper userMapper;
@Cacheable(key = "'getTotalCount'")
@Override
public int getTotalCount(){
int totalCount = userMapper.getTotalCount();
return totalCount;
}
@Cacheable(key = "#userId")
@Override
public User getUser(Integer userId){
return userMapper.getUser(userId);
}
@Caching(evict = {
@CacheEvict(key = "'getUsers'"),
@CacheEvict(key = "'getTotalCount'")
})
@Override
public void insertUser(User u){
userMapper.insertUser(u);
}
@Cacheable(key = "'getUsers'")
@Override
public List<User> getUsers(){
return userMapper.getUsers();
}
@Caching(evict = {
@CacheEvict(key = "'getUsers'")
})
@Override
public void updateUserNameById(Integer userId, String name){
userMapper.updateUserNameById(userId, name);
}
@Caching(evict = {
@CacheEvict(key = "'getUsers'"),
@CacheEvict(key = "'getTotalCount'"),
@CacheEvict(key = "#userId")
})
@Override
public void deleteUser(Integer userId){
userMapper.deleteUser(userId);
}
/**
* 调用方法,有更新缓存的数据 修改数据库的数据同时更新新缓存。
*/
@Caching(evict = {
@CacheEvict(key="'getUsers'")
},put = {@CachePut(key = "#result.id")})
@Override
public User updateUser(User user){
userMapper.updateUser(user);
return user;
}
}
package com.liang.domain;
import java.io.Serializable;
/**
* @PROJECT_NAME: springboot-leaning
* @USER: yuliang
* @DESCRIPTION:
* @DATE: 2021-05-21 17:01
*/
public class User implements Serializable {
private Integer id;
private String username;
private Integer age;
private String mobile;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", age=" + age +
", mobile='" + mobile + '\'' +
'}';
}
}
package com.liang.mapper;
import com.liang.domain.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @PROJECT_NAME: springboot-leaning
* @USER: yuliang
* @DESCRIPTION:
* @DATE: 2021-06-30 16:37
*/
@Mapper
public interface UserMapper {
int getTotalCount();
User getUser(Integer userId);
int insertUser(User u);
List<User> getUsers();
int updateUserNameById(Integer userId, String name);
int deleteUser(Integer userId);
int updateUser(User user);
}
server:
port: 8084
spring:
application:
name: springboot-cache
datasource:
url: jdbc:mysql://localhost:3306/user_db_test
username: root
password: admin123
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
# Redis服务器地址
host: localhost
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码(默认为空)
password:
# Redis数据库索引(默认为0)
database: 0
# 连接超时时间(毫秒)
timeout : 300
client-type: lettuce #切换jedis客户端,改成jedis
lettuce: #切换jedis客户端,改成jedis
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 8
# 连接池中的最小空闲连接
min-idle: 0
cache:
type: redis
redis:
#是否缓存空值,防止缓存穿透
cache-null-values: true
#缓存过期时间
time-to-live: 100000
#缓存前缀,用于区分其他缓存,不指定前缀,默认使用缓存的名字作为前缀
# key-prefix: CACHE_
#是否使用缓存前缀,false不使用任何缓存前缀
# use-key-prefix: false
# 配置mybatis规则
mybatis:
config-location: classpath:mybatis/mybatis-config.xml #全局配置文件位置
mapper-locations: classpath:mybatis/mapper/*.xml #sql映射文件位置
logging:
level:
com.liang.mapper : debug
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liang.mapper.UserMapper">
<select id="getTotalCount" resultType="int">
select count(*) from t_user
</select>
<sql id="Base_Column_List">
id,username,age,mobile
</sql>
<resultMap id="BaseResultMap" type="com.liang.domain.User">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="username" jdbcType="VARCHAR" property="username"/>
<result column="age" jdbcType="INTEGER" property="age"/>
<result column="mobile" jdbcType="VARCHAR" property="mobile"/>
</resultMap>
<select id="getUser" parameterType="int" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_user where id = #{userId,jdbcType=INTEGER}
</select>
<insert id="insertUser" parameterType="com.liang.domain.User">
insert into t_user (username,age,mobile) values(#{username,jdbcType=VARCHAR},#{age,jdbcType=INTEGER},#{mobile,jdbcType=VARCHAR})
</insert>
<update id="updateUserNameById">
update t_user set username= #{name,jdbcType=VARCHAR} where id = #{userId,jdbcType=INTEGER}
</update>
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from t_user where id = #{userId,jdbcType=INTEGER}
</delete>
<select id="getUsers" resultType="com.liang.domain.User">
select <include refid="Base_Column_List" />
from t_user
</select>
<update id="updateUser" parameterType="com.liang.domain.User">
update t_user
<set>
<if test="username != null">
username = #{username},
</if>
<if test="age != null">
age = #{age},
</if>
<if test="mobile != null">
mobile = #{mobile}
</if>
</set>
where id = #{id}
</update>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--打印SQL语句-->
<setting name="logImpl" value="STDOUT_LOGGING" />
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
\ No newline at end of file
CREATE DATABASE IF NOT EXISTS user_db_test;
DROP TABLE IF EXISTS t_user;
CREATE TABLE `t_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`username` varchar(64) NOT NULL COMMENT '用户姓名',
`age` int(11) NOT NULL COMMENT '用户年龄',
`mobile` varchar(11) DEFAULT NULL COMMENT '手机号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
\ No newline at end of file
package com.liang.mapper;
import com.liang.dao.IUserDao;
import com.liang.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cache.CacheManager;
import org.springframework.util.Assert;
import java.util.List;
/**
* @PROJECT_NAME: springboot-leaning
* @USER: yuliang
* @DESCRIPTION:
* @DATE: 2021-06-30 16:41
*/
@SpringBootTest
public class UserDaoTest {
private static final String CACHE_NAME_USER = "users";
@Autowired
private IUserDao userDao;
@Autowired
private CacheManager cacheManager;
@Test
public void testCacheManager() {
System.out.println(cacheManager);
}
@Test
public void testGetTotalCount(){
int totalCount = userDao.getTotalCount();
System.out.println(totalCount);
}
@Test
public void testGetUserById() {
// 这里,事先插入一条 id = 1 的记录。
Integer id = 1;
// 查询 id = 1 的记录,从数据库查询会打印SQL
User user = userDao.getUser(id);
System.out.println("第一次查询,user:" + user);
// 判断缓存中,是不是存在
Assert.notNull(cacheManager.getCache(CACHE_NAME_USER).get(user.getId(), User.class), "缓存为空");
// 查询 id = 1 的记录,从缓冲获取,不打印SQL
user = userDao.getUser(id);
System.out.println("第二次查询,user:" + user);
}
@Test
public void testInsertUser(){
User user = new User();
user.setAge(18);
user.setMobile("13601482796");
user.setUsername("xiaoliang");
userDao.insertUser(user);
}
@Test
public void testGetUsers(){
List<User> users = userDao.getUsers();
System.out.println(users);
}
@Test
public void testUpdateUserNameById(){
Integer id = 7;
userDao.updateUserNameById(id, "test");
}
@Test
public void testDeleteUser(){
Integer id = 1;
userDao.deleteUser(id);
// 查询 id = 1 的记录
User user = userDao.getUser(id);
System.out.println("查询,user:" + user);
}
@Test
public void testUpdateUser(){
User user = new User();
user.setId(2);
user.setAge(10);
user.setUsername("yuliang");
user.setMobile("12310046789");
userDao.updateUser(user);
}
}
public class Main {
public static void main(String[] args) {
foo();
method();
}
static void foo() {
System.out.println("Inside foo");
}
static void method(){
foo();
}
}
\ No newline at end of file
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot-leaning</artifactId>
<groupId>com.liang.springboot</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springboot-redis</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- 导入jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.liang;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @PROJECT_NAME: springboot-leaning
* @USER: yuliang
* @DESCRIPTION:
* @DATE: 2021-06-30 09:58
*/
@SpringBootApplication
public class RedisApplication {
public static void main(String[] args) {
SpringApplication.run(RedisApplication.class, args);
}
}
package com.liang.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
/**
* @PROJECT_NAME: springboot-leaning
* @USER: yuliang
* @DESCRIPTION:
* @DATE: 2021-06-30 10:39
*/
@Configuration
public class RedisConfig {
/**
* 默认是JDK的序列化策略,这里配置redisTemplate采用的是Jackson2JsonRedisSerializer的序列化策略
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 配置连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
//使用StringRedisSerializer来序列化和反序列化redis的key值
//redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
// 值采用json序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/***
* stringRedisTemplate默认采用的是String的序列化策略
* @param redisConnectionFactory
* @return
*/
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
return stringRedisTemplate;
}
}
server:
port: 8083
spring:
application:
name: springboot-redis
redis:
# Redis服务器地址
host: localhost
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码(默认为空)
password:
# Redis数据库索引(默认为0)
database: 0
# 连接超时时间(毫秒)
timeout : 300
client-type: lettuce #切换jedis客户端,改成jedis
lettuce: #切换jedis客户端,改成jedis
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 8
# 连接池中的最小空闲连接
min-idle: 0
\ No newline at end of file
package com.liang;
import com.alibaba.fastjson.JSON;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.util.Assert;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @PROJECT_NAME: springboot-leaning
* @USER: yuliang
* @DESCRIPTION:
* @DATE: 2021-06-30 10:23
*/
@SpringBootTest
public class RedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
void testRedis(){
ValueOperations<String, String> operations = redisTemplate.opsForValue();
operations.set("hello","world");
String hello = operations.get("hello");
System.out.println(hello);
}
/**
* 操作字符串
*/
@Test
public void testString() {
//设置值
stringRedisTemplate.opsForValue().set("String", "Mao");
//获取值
String string = stringRedisTemplate.opsForValue().get("String");
System.out.println(string);
//设置值且设置超时时间
stringRedisTemplate.opsForValue().set("Middle", "Yu", 3, TimeUnit.MINUTES);
String middle = stringRedisTemplate.opsForValue().get("Middle");
System.out.println(middle);
//删除数据
Boolean isDelete = stringRedisTemplate.delete("String");
Assert.isTrue(isDelete, "删除失败");
}
/**
* 操作列表
*/
@Test
public void testList() {
ListOperations listOp = redisTemplate.opsForList();
//往 List 左侧插入一个元素
listOp.leftPush("nameList", "mike");
listOp.leftPush("nameList", "kim");
//往 List 右侧插入一个元素
listOp.rightPush("nameList", "jimmy");
listOp.rightPush("nameList", "chuck");
//List 大小
Long size = listOp.size("nameList");
//遍历整个List
List nameList1 = listOp.range("nameList", 0, size);
System.out.println(JSON.toJSONString(nameList1));
//遍历整个List,-1表示倒数第一个即最后一个
List nameList = listOp.range("nameList", 0, -1);
System.out.println(JSON.toJSONString(nameList));
//从 List 左侧取出第一个元素,并移除
Object name1 = listOp.leftPop("nameList", 200, TimeUnit.MILLISECONDS);
System.out.println("is kim:" + name1.equals("kim"));
//从 List 右侧取出第一个元素,并移除
Object name2 = listOp.rightPop("nameList");
System.out.println("is chuck:" + name2.equals("chuck"));
}
/**
* 操作 Hash
*/
@Test
public void testHash() {
//添加泛型方便操作和返回想要的具体类型
HashOperations<String, String, Integer> hashOp = redisTemplate.opsForHash();
//Hash 中新增元素。
hashOp.put("score", "Mike", 10);
hashOp.put("score", "Jimmy", 9);
hashOp.put("score", "Kim", 8);
//判断指定 key 对应的 Hash 中是否存在指定的 map 键
Assert.isTrue(hashOp.hasKey("score", "Kim"));
//获取指定 key 对应的 Hash 中指定键的值
Integer kim = hashOp.get("score", "Kim");
System.out.println("kim score:" + kim);
//获取hash表所有的key集合
Set<String> name = hashOp.keys("score");
System.out.println(JSON.toJSONString(name));
//获取hash表所有的values集合
List<Integer> score = hashOp.values("score");
System.out.println(JSON.toJSONString(score));
//获取"score"对应的hash表Map
Map<String, Integer> map = hashOp.entries("score");
System.out.println(JSON.toJSONString(map));
//删除指定 key 对应 Hash 中指定键的键值对
hashOp.delete("score", "Mike");
//如果要删除整个hash表,要用redisTemplate.delete("score")方法,否则报错:Fields must not be empty
// hashOp.delete("score");
//删除整个hash表
redisTemplate.delete("score");
Map<String, Integer> map1 = hashOp.entries("score");
System.out.println(JSON.toJSONString(map1));
}
/**
* 操作集合
*/
@Test
public void testSet() {
SetOperations<String, String> setOp = redisTemplate.opsForSet();
//向集合中添加元素,set元素具有唯一性
setOp.add("city", "quanzhou", "newyork", "paris", "hongkong", "hongkong");
Long size = setOp.size("city");
System.out.println("city size:" + size);
//获取集合中的元素
Set city = setOp.members("city");
System.out.println(JSON.toJSONString(city));
//移除集合中的元素,可以一个或多个
setOp.remove("city", "paris");
//判断是否是集合中的元素
Boolean isMember = setOp.isMember("city", "paris");
System.out.println("paris is in city:" + isMember);
//移除并返回集合中的一个随机元素
String city1 = setOp.pop("city");
System.out.println(city1);
}
/**
* 操作有序集合
*/
@Test
public void testZSet() {
ZSetOperations<String, String> zSetOp = redisTemplate.opsForZSet();
zSetOp.add("zcity", "beijing", 100);
zSetOp.add("zcity", "shanghai", 95);
zSetOp.add("zcity", "guangzhou", 75);
zSetOp.add("zcity", "shenzhen", 85);
//获取变量指定区间的元素。0, -1表示全部
Set<String> zcity = zSetOp.range("zcity", 0, -1);
System.out.println(JSON.toJSONString(zcity));
//通过分数返回有序集合指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列
Set<String> byScore = zSetOp.rangeByScore("zcity", 85, 100);
System.out.println(JSON.toJSONString(byScore));
//获取有序集合的成员数
Long aLong = zSetOp.zCard("zcity");
System.out.println("zcity size: " + aLong);
ZSetOperations<String, Integer> zSetOp1 = redisTemplate.opsForZSet();
zSetOp1.add("board", 1, 100);
zSetOp1.add("board", 2, 100);
zSetOp1.add("board", 3, 100);
zSetOp1.add("board", 4, 100);
Set<Integer> board = zSetOp1.range("board", 0, -1);
System.out.println(JSON.toJSONString(board));
RedisZSetCommands.Range range = new RedisZSetCommands.Range();
//less than
range.lt("3");
//用于获取满足非 score 的排序取值。这个排序只有在有相同分数的情况下才能使用,如果有不同的分数则返回值不确定。
//rangeByLex应用在数值上比较
Set<Integer> set = zSetOp1.rangeByLex("board", range);
System.out.println(JSON.toJSONString(set));
RedisZSetCommands.Limit limit = new RedisZSetCommands.Limit();
limit.count(1);
limit.offset(1);
//用于获取满足非 score 的设置下标开始的长度排序取值。
Set<Integer> setlmt = zSetOp1.rangeByLex("board", range, limit);
System.out.println(JSON.toJSONString(setlmt));
}
/**
* 分布式锁
*/
@Test
public void testLock() {
String value = UUID.randomUUID().toString();
Boolean lock = lock("buy", value,12L, TimeUnit.SECONDS);
if (!lock) {
System.out.println("can't lock buy");
}
System.out.println("lock success");
try {
Thread.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
Boolean unLock = unLock("buy",value);
Assert.isTrue(unLock, "can't unlock buy");
}
}
public Boolean lock(String key,String value, Long timeout, TimeUnit timeUnit) {
Boolean lockStat = stringRedisTemplate.execute((RedisCallback<Boolean>) connection ->
connection.set(key.getBytes(Charset.forName("UTF-8")), value.getBytes(Charset.forName("UTF-8")),
Expiration.from(timeout, timeUnit), RedisStringCommands.SetOption.SET_IF_ABSENT));
return lockStat;
}
public Boolean unLock(String key,String value) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
boolean unLockStat = stringRedisTemplate.execute((RedisCallback<Boolean>) connection ->
connection.eval(script.getBytes(), ReturnType.BOOLEAN, 1,
key.getBytes(Charset.forName("UTF-8")), value.getBytes(Charset.forName("UTF-8"))));
return unLockStat;
}
/**
* 提供了对key的“bound”(绑定)便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作而无须“显式”的再次指定Key,即BoundKeyOperations;
*/
@Test
public void boundTest(){
BoundListOperations bound = redisTemplate.boundListOps("bound");
bound.leftPush("haha");
bound.rightPush("hehe");
List list = bound.range(0, -1);
System.out.println(JSON.toJSONString(list));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册