搭建springboot项目
application.yml
server:
port: 9001
spring:
redis:
host: 127.0.0.1
port: 6379
jedis:
pool:
max-wait: 30000 #连接池最大阻塞等待时间,使用负值表示没有限制
max-active: 100 #连接池最大连接数,使用负值表示没有限制
max-idle: 20 #连接池中的最大空闲连接
min-idle: 0 #连接池中的最小空闲连接
timeout: 3000 #连接超时
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.touch</groupId>
<artifactId>springtest</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
RedisConfig.java
@Configuration
public class RedisConfig extends CachingConfigurerSupport{
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(redisConnectionFactory);
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);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
RedisUtils.java
@Component
public class RedisUtils {
@Autowired
private RedisTemplate redisTemplate;
public RedisUtils(RedisTemplate<String, Object> redisTemplate) {
this.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);
}
/**
* 设置key字段第offset位bit数值
*
* @param key 字段
* @param offset 位置
* @param value 数值
*/
public void setBit(String key, long offset, boolean value) {
redisTemplate.execute((RedisCallback) con -> con.setBit(key.getBytes(), offset, value));
}
/**
* 判断该key字段offset位否为1
*
* @param key 字段
* @param offset 位置
* @return 结果
*/
public boolean getBit(String key, long offset) {
return (boolean) redisTemplate.execute((RedisCallback) con -> con.getBit(key.getBytes(), offset));
}
/**
* 统计key字段value为1的总数
*
* @param key 字段
* @return 总数
*/
public Long bitCount(String key) {
return (Long) redisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
}
/**
* 统计key字段value为1的总数,从start开始到end结束
*
* @param key 字段
* @param start 起始
* @param end 结束
* @return 总数
*/
public Long bitCount(String key, Long start, Long end) {
return (Long) redisTemplate.execute((RedisCallback) con -> con.bitCount(key.getBytes(), start, end));
}
/**
* 取多个key并集并计算总数
*
* @param key key
* @return 总数
*/
public Long OpOrCount(String... key) {
byte[][] keys = new byte[key.length][];
for (int i = 0; i < key.length; i++) {
keys[i] = key[i].getBytes();
}
redisTemplate.execute((RedisCallback) con -> con.bitOp(RedisStringCommands.BitOperation.OR, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
redisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
return bitCount(key[0] + "To" + key[key.length - 1]);
}
/**
* 取多个key的交集并计算总数
*
* @param key key
* @return 总数
*/
public Long OpAndCount(String... key) {
byte[][] keys = new byte[key.length][];
for (int i = 0; i < key.length; i++) {
keys[i] = key[i].getBytes();
}
redisTemplate.execute((RedisCallback) con -> con.bitOp(RedisStringCommands.BitOperation.AND, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
redisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
return bitCount(key[0] + "To" + key[key.length - 1]);
}
/**
* 取多个key的补集并计算总数
*
* @param key key
* @return 总数
*/
public Long OpXorCount(String... key) {
byte[][] keys = new byte[key.length][];
for (int i = 0; i < key.length; i++) {
keys[i] = key[i].getBytes();
}
redisTemplate.execute((RedisCallback) con -> con.bitOp(RedisStringCommands.BitOperation.XOR, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
redisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
return bitCount(key[0] + "To" + key[key.length - 1]);
}
/**
* 取多个key的否集并计算总数
*
* @param key key
* @return 总数
*/
public Long OpNotCount(String... key) {
byte[][] keys = new byte[key.length][];
for (int i = 0; i < key.length; i++) {
keys[i] = key[i].getBytes();
}
redisTemplate.execute((RedisCallback) con -> con.bitOp(RedisStringCommands.BitOperation.NOT, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
redisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
return bitCount(key[0] + "To" + key[key.length - 1]);
}
public List<Long> bitField(String buildSignKey,int limit,int offset){
return (List<Long>)redisTemplate.execute((RedisCallback<List<Long>>) con ->
con.bitField(buildSignKey.getBytes(),
BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(limit)).valueAt(offset)));
}
public Long setHyperLogLog(String key,Object...values){
return redisTemplate.opsForHyperLogLog().add(key,values);
}
public Long getHyperLogLog(Object...keys){
return redisTemplate.opsForHyperLogLog().size(keys);
}
public BoundGeoOperations setGeo(Object key){
return redisTemplate.boundGeoOps(key);
}
}
RedisController.java
@RestController
@RequestMapping("/redis")
@Slf4j
public class RedisController {
@Resource
private RedisUtils redisUtils;
@RequestMapping("/set")
public void redisSet(){
//String
redisUtils.set("String","中文");
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
redisUtils.set("list",list);
redisUtils.set("user2",new User("210123","阿丹",25));
//hash
redisUtils.hmSet("user1","userhash",new User("210123","阿丹",25));
User user = (User)redisUtils.hmGet("user1","userhash");
log.info("hash-object:{}",user);
//列表添加
redisUtils.lPush("list1","a");
redisUtils.lPush("list1","b");
List<Object> listValue = redisUtils.lRange("list1",0,list.size());
log.info("listValue-object:{}",listValue);
//集合添加
Map<String,User> map = new HashMap<>();
map.put("adan",new User("210123","阿丹",25));
map.put("adana",new User("210123","阿丹a",18));
redisUtils.add("collection",map);
Set<Object> set = redisUtils.setMembers("collection");
log.info("setValue-object:{}",set);
//有序集合
redisUtils.zAdd("collection-order","18",1);
redisUtils.zAdd("collection-order","12",2);
redisUtils.zAdd("collection-order","14",4);
redisUtils.zAdd("collection-order","123",3);
Set<Object> zset = redisUtils.rangeByScore("collection-order",1,5);
log.info("zsetValue-object:{}",zset);
//bitmap
redisUtils.setBit("bitmap",1,true);
redisUtils.setBit("bitmap",0,true);
boolean bit = redisUtils.getBit("bitmap",1);
log.info("bitmapValue-boolean:{}",bit);
long count = redisUtils.bitCount("bitmap");
log.info("bitmapValue-count:{}",count);
long start = 0;
long end = 7;
long count2 = redisUtils.bitCount("bitmap",start,end);
log.info("bitmapValue-count2:{}",count2);
List<Long> bitFiledLong = redisUtils.bitField("bitmap",2,0);
log.info("bitmapValue-bitFiledLong:{}",bitFiledLong);
// 在线用户
String onlineKey = "online:";
for (int i = 0; i < 100; i++) {
redisUtils.setBit(onlineKey, i, i % 2 == 0);
}
for (int i = 0; i < 10; i++) {
log.info("{}={}" ,i, redisUtils.getBit(onlineKey, i));
}
log.info("online:{}",redisUtils.bitCount(onlineKey));
// IP去重复统计
final String logLogKey = "loglog:";
String[] arr = new String[100];
for (int i = 0; i < 100;i++) {
arr[i] = "A" + new Random().nextInt(10) + 1;
}
redisUtils.setHyperLogLog(logLogKey, arr);
log.info("arr:{}",arr);
log.info("logLog:{}",redisUtils.getHyperLogLog(logLogKey));
BoundGeoOperations boundGeoOperations = redisUtils.setGeo("CHINA:CITY");
Point nanjing = new Point(118.803805, 32.060168);
boundGeoOperations.add(nanjing, "南京市");
Point beijing = new Point(116.397039, 39.9077);
boundGeoOperations.add(beijing, "北京市");
Point shanghai = new Point(120.52, 30.40);
boundGeoOperations.add(shanghai, "上海市");
//geodist:获取两个地理位置的距离
Distance distance = boundGeoOperations.distance("南京市","北京市", Metrics.KILOMETERS);
log.info("南京市到北京市之间的距离是:{}km" ,distance.getValue());
Distance distance2 = boundGeoOperations.distance("南京市", "上海市", Metrics.KILOMETERS);
log.info("南京市到上海市之间的距离是:{}km", distance2.getValue());
//geohash:获取某个地理位置的geohash值
List<String> list2 = boundGeoOperations.hash("南京市");
log.info("南京市的geoHash = {}", list2.get(0));
//geopos:获取某个地理位置的坐标
List<Point> pointList = boundGeoOperations.position("南京市");
log.info("南京市的经纬度为 = {} ", pointList.get(0));
//georadius:根据给定地理位置坐标获取指定范围内的地理位置集合
// 查询南京市1000KM范围内的城市
Circle within = new Circle(nanjing, 1000000);
//设置geo查询参数
RedisGeoCommands.GeoRadiusCommandArgs geoRadiusArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
//查询返回结果包括距离和坐标
geoRadiusArgs = geoRadiusArgs.includeCoordinates().includeDistance();
//按查询出的坐标距离中心坐标的距离进行排序
geoRadiusArgs.sortAscending();
//限制查询返回的数量
geoRadiusArgs.limit(2);
GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = boundGeoOperations.radius(within, geoRadiusArgs);
List<GeoResult<RedisGeoCommands.GeoLocation<String>>> geoResultList = geoResults.getContent();
for (GeoResult geoResult : geoResultList) {
log.info("geoRadius {} " , geoResult.getContent());
}
//georadiusbymember:根据给定地理位置获取指定范围内的地理位置集合
geoRadiusArgs.limit(1); geoResults = boundGeoOperations.radius("南京市", new Distance(1000000), geoRadiusArgs);
geoResultList = geoResults.getContent();
for (GeoResult geoResult : geoResultList) {
log.info("geoRadiusByMember {}" , geoResult.getContent());
} //删除位置信息,此命令不是geo提供的,是使用zrem命令删除的
boundGeoOperations.remove("南京市");
}
}
log
hash-object:User(account=210123, name=阿丹, age=25)
listValue-object:[a, b, a, b]
setValue-object:[{adana=User(account=210123, name=阿丹a, age=18), adan=User(account=210123, name=阿丹, age=25)}]
zsetValue-object:[18, 12, 123, 14]
bitmapValue-boolean:true
bitmapValue-count:2
bitmapValue-count2:2
bitmapValue-bitFiledLong:[3]
0=true
1=false
...
online:50
arr:A61
logLog:10
南京市到北京市之间的距离是:899.2222km
南京市到上海市之间的距离是:246.4453km
南京市的geoHash = wtsqrkqk120
南京市的经纬度为 = Point [x=118.803805, y=32.060168]
geoRadius RedisGeoCommands.GeoLocation(name=南京市, point=Point [x=118.803805, y=32.060168])
geoRadius RedisGeoCommands.GeoLocation(name=上海市, point=Point [x=120.520001, y=30.400000])
geoRadiusByMember RedisGeoCommands.GeoLocation(name=南京市, point=Point [x=118.803805, y=32.060168])
虽然总结了,但是理解还不是很透彻!!!
菜了菜了!!!
参考:
https://www.sohu.com/a/300039010_114877
https://www.matools.com/blog/190329767
https://blog.csdn.net/weixin_39765695/article/details/110726589
https://www.jianshu.com/p/5596c3a4978d