持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情
前言
ok,通过咱们一段时间的努力,咱们终于把大部分的前端做好了,但是这还没有完毕,因为咱们的后端才开始真正复杂的业务,其实纵观咱们的整个的WhiteHole项目,其实它的业务逻辑并不是很复杂,其实业务的难度顶多和xx商城的难度类似,只是说咱们的中间将调用到一些第三方服务。本质上来说,他其实还是一个curd 的项目,只是说它可能使用到的第三方组件,中间键比较多。然后里面的聊天好友功能可能是和单纯的CURD有了那么一点点区别。之后的话是我们的一些推荐算法,当前版本的话,还是一个大体的架构版本,个性推荐算法是暂时没有的,但是做咱们是一定要做的,毕竟咱们不能只做一个CURD程序员。还是要做算法的,而且说实话作为一个pythoner兼修Java,不在自己的项目里面放点python的东西真说不过去,做web python确实和Java差一点,那么咱们就用这个做算法。在完成我们主要的第一阶段开发之后,咱们的第二阶段就是上算法,一个个性推介算法,这个可能还是打算用最简单的KNN来做,之后是聊天+检索机器人,也就是咱们主页的那个小姐姐,不过这个功能主要是给PC端用的,移动端还是得等等,但愿小叶,毕业的时候可以做出来吧,还有1年左右吧。
那么今天要做的就是使用SpringBoot去整合咱们的Redis.
然后咱们做的主要就是两点。 1.导入redis依赖,并且将对象以json格式去报错至redis服务器当中。 2.对咱们的这个redistemplete进行简单封装,方便使用,这个封装的话,咱们其实还有对于Http的封装,主要是用来做Auto的,这个咱们明天再说。当然不保证更新哈,最近忙着练车+论文(大二暑假欠下的债)。
导入依赖
这个老规矩了。首先是导入咱们的依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
之后是配置
spring.redis.host=localhost
spring.redis.port=6379
#spring.redis.password=123456
配置对象Json序列化
这个其实很重要的,虽然Java自己也可以序列号,但是这个是二进制字节码啥的,反之很不优化,而且还大,这个咱们先前在使用rabbitmq的时候也是要进行json序列化的,不用Java自带的那套的。用的也是阿里的fastjson
不过这里要导入的依赖稍微多一点。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.0</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.74</version>
</dependency>
之后是配置类:
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfiguration {
/**
* 采用FastJson进行key/value序列化
*
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
final RedisTemplate<String, Object> template = new RedisTemplate<>();
final FastJsonRedisSerializer<?> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setEnableTransactionSupport(true);
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
封装
RedisTelempent封装
咱们使用的话,一般直接使用那个RedisTelempent 。但是比较麻烦,所以这里有个封装,可以拿过来用。
@Component
public class RedisUtils {
@Autowired
private RedisTemplate<String,Object> redisTemplate;
public boolean expire(String key, long time) {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
return true;
} else {
throw new RuntimeException("超时时间小于0");
}
}
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
public boolean hasKey(String key) {
return redisTemplate.hasKey(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(CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
public boolean set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
return true;
}
public boolean set(String key, Object value, long time) {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
this.set(key, value);
}
return true;
}
public boolean set(String key, Object value, long time,TimeUnit tiemtype) {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, tiemtype);
} else {
this.set(key, value);
}
return true;
}
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
public boolean hmset(String key, Map<String, Object> map) {
redisTemplate.opsForHash().putAll(key, map);
return true;
}
public boolean hmset(String key, Map<String, Object> map, long time) {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
}
public boolean hset(String key, String item, Object value) {
redisTemplate.opsForHash().put(key, item, value);
return true;
}
public boolean hset(String key, String item, Object value, long time) {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
}
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
// ============================set=============================
public Set<Object> sGet(String key) {
return redisTemplate.opsForSet().members(key);
}
public boolean sHasKey(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
}
public long sSet(String key, Object... values) {
return redisTemplate.opsForSet().add(key, values);
}
public long sSetAndTime(String key, long time, Object... values) {
final Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0)
expire(key, time);
return count;
}
public long sGetSetSize(String key) {
return redisTemplate.opsForSet().size(key);
}
public long setRemove(String key, Object... values) {
final Long count = redisTemplate.opsForSet().remove(key, values);
return count;
}
// ===============================list=================================
public List<Object> lGet(String key, long start, long end) {
return redisTemplate.opsForList().range(key, start, end);
}
public long lGetListSize(String key) {
return redisTemplate.opsForList().size(key);
}
public Object lGetIndex(String key, long index) {
return redisTemplate.opsForList().index(key, index);
}
public boolean lSet(String key, Object value) {
redisTemplate.opsForList().rightPush(key, value);
return true;
}
public boolean lSet(String key, Object value, long time) {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
}
public boolean lSetList(String key, List<Object> value) {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
}
public boolean lSetList(String key, List<Object> value, long time) {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) {
expire(key, time);
}
return true;
}
public boolean lUpdateIndex(String key, long index, Object value) {
redisTemplate.opsForList().set(key, index, value);
return true;
}
}
不用管那么多,我知道对你们有用的就4个方法
get(key)
set(key,object)
set(key,object,Secends)
set(key,object,time,timeType)自己设定时间的类型,是秒还是啥
del(key,...)
其他的东西我相信,你们都是直接封装一个对象的,然转json转object让操作。
FastJson封装
之后的话还有对这个FastJson的封装。
/**
* FastJson工具类
* 支持Object --> JSON(String)
* 也支持 JSON(String) --> Object
* 支持集合和JSON的变化
* 支持自定义日期转化格式等
* 这是一个静态的工具类
*/
public class FastJsonUtils {
private static final SerializeConfig config;
private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
static {
config = new SerializeConfig();
// 使用和json-lib兼容的日期输出格式
config.put(java.util.Date.class, new JSONLibDataFormatSerializer());
// 使用和json-lib兼容的日期输出格式
config.put(java.sql.Date.class, new JSONLibDataFormatSerializer());
config.put(java.sql.Timestamp.class, new JSONLibDataFormatSerializer());
}
private static final SerializerFeature[] features = {
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.WriteNullNumberAsZero,
SerializerFeature.WriteNullBooleanAsFalse,
SerializerFeature.WriteNullStringAsEmpty
};
/**
* 将json转换成字符串(带序列化Feature)
*
* 输出空置字段
*
* list字段如果为null,输出为[],而不是null
*
* 数值字段如果为null,输出为0,而不是null
*
* Boolean字段如果为null,输出为false,而不是null
*
* 字符类型字段如果为null,输出为"",而不是null
*
* @param object
* @return
*/
public static String toJsonWithFeatures(Object object) {
return JSON.toJSONString(object, config, features);
}
/**
* 经json转换成字符串,按实际情况
*
* @param object
* @return
*/
public static String toJson(Object object) {
if (object == null) {
return null;
}
return JSON.toJSONString(object, config);
}
/**
* 将json转成object
*
* @param json
* @return
*/
public static Object fromJson(String json) {
return JSON.parse(json);
}
/**
* 将json转成对应的对象
*
* @param json
* @param clazz
* @return
*/
public static <T> T fromJson(String json, Class<T> clazz) {
return JSON.parseObject(json, clazz);
}
/**
* 按类型转化
*
* @param json
* @param type 例: new TypeReference<Map<String, Object>>() {}
* @return
*/
public static <T> T fromJson(String json, TypeReference<T> type) {
return JSON.parseObject(json, type.getType());
}
/**
* 将json转成数组
*
* @param json
* @return
*/
public static <T> Object[] toArray(String json) {
return toArray(json, null);
}
/**
* 转换为数组
*
* @param json
* @param clazz
* @return
*/
public static <T> Object[] toArray(String json, Class<T> clazz) {
return JSON.parseArray(json, clazz).toArray();
}
/**
* 转换为List
*
* @param json
* @param clazz
* @return
*/
public static <T> List<T> toList(String json, Class<T> clazz) {
return JSON.parseArray(json, clazz);
}
/**
* 将javabean转化为序列化的json字符串
*
* @param keyvalue
* @return
*/
public static Object beanToJson(Object keyvalue) {
String textJson = JSON.toJSONString(keyvalue);
Object objectJson = JSON.parse(textJson);
return objectJson;
}
/**
* 将string转化为序列化的json字符串
*
* @param json
* @return
*/
public static Object textToJson(String json) {
Object objectJson = JSON.parse(json);
return objectJson;
}
/**
* json字符串转化为map
*
* @param json
* @return
*/
public static Map<String, Object> stringToCollect(String json) {
return JSONObject.parseObject(json);
}
/**
* 指定时间格式 的json转换
*
* @param object
* @param dateFormat
* @return
*/
public static String toJSONStringWithDateFormat(Object object, String dateFormat) {
return JSON.toJSONStringWithDateFormat(object, dateFormat);
}
/**
* 默认时间格式 的json转换
*
* @param object
* @return
*/
public static String toJSONStringWithDefaultDateFormat(Object object) {
return JSON.toJSONStringWithDateFormat(object, DEFAULT_DATE_FORMAT);
}
}
测试
这里有一个测试的pojo类
@Data
@ToString
public class User {
private String name;
private int age;
private double height;
}
@Test
public void redisSave(){
User user = new User();
user.setAge(18);
user.setHeight(17.5);
user.setName("s");
boolean huterox = redisUtils.set("huterox", user,100, TimeUnit.SECONDS);
System.out.println("存储成功");
}
总结
这个就是咱们对于redis的一个简单操作,后面咱们很多骚操作都要用这个来实现。