版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiao__jia__jia/article/details/86497392
缓存数据库的使用
常见的缓存数据库:redis,solr.
redis
1 redis可以存储用户信息(session)
2 redis可以存储购物车数据
3 redis可以存储条件检索的商品数据(k:v)
通过分类获取商品列表
1 用分类id作为key 2 用商品sku对象集合作为value 3 将商品缓存数据放入到redis中的zset里 |
真实环境中redis使用
1 每次使用一个key时,都需要对该key是否存在进行判断 Key生成的规则:key要体现出检索条件 交叉检索,每次检索时,需要先判断key是否存在,如果已经存在,直接返回
2 redis查询排序和分页 Zrangebyscore Zrevrangebyscore zrangebyscore k1 0 10 withscores limit 3 3
3 交叉检索时,需要注意 对score进行处理,排序关键字(乘法因子相乘后相加) Zinterstore weights 乘法因子1 乘法因子2
4 redis数据结构 所有条件检索的key,存储的是sku的id Sku的具体信息,skuid为key,sku内容为value的集合 Hash Key:value Key:value
5 如果需要更新redis 先删除后添加 Zrem + zadd
|
实战:
pom添加依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
读取Properties文件的工具类
package com.atguigu.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class MyPropertyUtil {
public static String getProperty(String pro, String key) {
Properties properties = new Properties();
InputStream resourceAsStream = MyPropertyUtil.class.getClassLoader().getResourceAsStream(pro);
try {
properties.load(resourceAsStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String property = properties.getProperty(key);
return property;
}
}
json与object转换的工具类
package com.atguigu.util;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import com.atguigu.bean.T_MALL_SHOPPINGCAR;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import net.sf.json.JSONArray;
public class MyJsonUtil {
public static void main(String[] args) throws UnsupportedEncodingException {
List<T_MALL_SHOPPINGCAR> list_car = new ArrayList<T_MALL_SHOPPINGCAR>();
for (int i = 0; i < 3; i++) {
T_MALL_SHOPPINGCAR t_MALL_SHOPPINGCAR = new T_MALL_SHOPPINGCAR();
t_MALL_SHOPPINGCAR.setSku_mch("商品" + i);
t_MALL_SHOPPINGCAR.setSku_jg(i * 1000);
list_car.add(t_MALL_SHOPPINGCAR);
}
}
public static <T> String object_to_json(T t) {
Gson gson = new Gson();
String json = gson.toJson(t);
try {
json = URLEncoder.encode(json, "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return json;
}
public static <T> T json_to_object(String json, Class<T> t) {
try {
json = URLDecoder.decode(json, "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Gson gson = new Gson();
T fromJson = gson.fromJson(json, t);
return fromJson;
}
public static <T> List<T> json_to_list(String json, Class<T> t) {
String decode = "";
if (StringUtils.isBlank(json)) {
return null;
} else {
try {
decode = URLDecoder.decode(json, "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JSONArray fromObject2 = JSONArray.fromObject(decode);
List<T> list_array = (List<T>) JSONArray.toCollection(fromObject2, t);
return list_array;
}
}
public static <T> String list_to_json(List<T> list) {
Gson gson = new Gson();
String json = gson.toJson(list);
try {
json = URLEncoder.encode(json, "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return json;
}
}
redis.properties
url=192.168.222.11
JedisPool的初始化
package com.atguigu.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisPoolUtils {
public static JedisPoolConfig c = new JedisPoolConfig(); // 连接池配置
public static JedisPool jedisPool = null; // 连接池
static {
// c.setBlockWhenExhausted(true); // 连接耗尽则阻塞
c.setLifo(true); // 后进先出
c.setMaxIdle(10); // 最大空闲连接数为10
c.setMinIdle(0); // 最小空闲连接数为0
c.setMaxTotal(100); // 最大连接数为100
c.setMaxWaitMillis(-1); // 设置最大等待毫秒数:无限制
c.setMinEvictableIdleTimeMillis(180); // 逐出连接的最小空闲时间:30分钟
c.setTestOnBorrow(true); // 获取连接时是否检查连接的有效性:是
c.setTestWhileIdle(true); // 空闲时是否检查连接的有效性:是
jedisPool = new JedisPool(c, MyPropertyUtil.getProperty("redis.properties", "url"), 6379); // 初始化连接池
}
/**
* 获取Jedis连接
*
* @return Jedis连接
*/
public static Jedis getJedis() {
return jedisPool.getResource();
}
}
调用Jredis获取数据的封装类
package com.atguigu.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.atguigu.bean.OBJECT_T_MALL_SKU;
import redis.clients.jedis.Jedis;
public class MyCacheUtil {
public static String interKeys(String... keys) {
Jedis jedis = null;
try {
jedis = JedisPoolUtils.getJedis();
} catch (Exception e) {
return null;
}
// 生成动态的key
String k0 = "combine";
for (int i = 0; i < keys.length; i++) {
k0 = k0 + "_" + keys[i];
}
if (!jedis.exists(k0)) {
jedis.zinterstore(k0, keys);
}
return k0;
}
public static <T> List<T> getList(String key, Class<T> t) {
List<T> list = new ArrayList<T>();
// 第三方数据调用
Jedis jedis = null;
try {
jedis = JedisPoolUtils.getJedis();
} catch (Exception e) {
return null;
}
Set<String> zrange = jedis.zrange(key, 0, -1);
Iterator<String> iterator = zrange.iterator();
while (iterator.hasNext()) {
String skuStr = iterator.next();
T sku = MyJsonUtil.json_to_object(skuStr, t);
list.add(sku);
}
return list;
}
public static <T> void setKey(String key, List<T> list) {
// 第三方数据调用
Jedis jedis = null;
try {
jedis = JedisPoolUtils.getJedis();
} catch (Exception e) {
// 记日志
}
jedis.del(key);
// 同步reids
for (int i = 0; i < list.size(); i++) {
jedis.zadd(key, i, MyJsonUtil.object_to_json(list.get(i)));
}
}
public static boolean if_key(String key) {
// 第三方数据调用
Jedis jedis = null;
try {
jedis = JedisPoolUtils.getJedis();
} catch (Exception e) {
// 记日志
}
Boolean exists = jedis.exists(key);
return exists;
}
}
controller控制层
package com.atguigu.controller;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import com.atguigu.bean.MODEL_T_MALL_SKU_ATTR_VALUE;
import com.atguigu.bean.OBJECT_T_MALL_ATTR;
import com.atguigu.bean.OBJECT_T_MALL_SKU;
import com.atguigu.bean.T_MALL_SKU_ATTR_VALUE;
import com.atguigu.service.AttrServiceInf;
import com.atguigu.service.ListServiceInf;
import com.atguigu.util.JedisPoolUtils;
import com.atguigu.util.MyCacheUtil;
import com.atguigu.util.MyJsonUtil;
import redis.clients.jedis.Jedis;
@Controller
public class ListController {
@Autowired
ListServiceInf listServiceInf;
@Autowired
AttrServiceInf attrServiceInf;
@RequestMapping("goto_list")
public String goto_list(int flbh2, ModelMap map) {
// flbh2属性的集合
List<OBJECT_T_MALL_ATTR> list_attr = attrServiceInf.get_attr_list(flbh2);
// flbh2商品列表
List<OBJECT_T_MALL_SKU> list_sku = new ArrayList<OBJECT_T_MALL_SKU>();
// 缓存检索
String key = "class_2_" + flbh2;
list_sku = MyCacheUtil.getList(key, OBJECT_T_MALL_SKU.class);
if (list_sku == null || list_sku.size() < 1) {
// mysql检索
list_sku = listServiceInf.get_list_by_flbh2(flbh2);
// 将检索结果同步到redis
MyCacheUtil.setKey(key, list_sku);
}
map.put("list_attr", list_attr);
map.put("list_sku", list_sku);
map.put("flbh2", flbh2);
return "list";
}
@RequestMapping("get_list_by_attr")
public String get_list_by_attr(MODEL_T_MALL_SKU_ATTR_VALUE list_attr, int flbh2, ModelMap map) {
// 根据属性查询列表的业务
List<OBJECT_T_MALL_SKU> list_sku = new ArrayList<OBJECT_T_MALL_SKU>();
// 缓存检索
List<T_MALL_SKU_ATTR_VALUE> list_attr2 = list_attr.getList_attr();
String[] keys = new String[list_attr2.size()];
for (int i = 0; i < list_attr2.size(); i++) {
keys[i] = "attr_" + flbh2 + "_" + list_attr2.get(i).getShxm_id() + "_" + list_attr2.get(i).getShxzh_id();
}
// 交叉检索,返回生成的key
String interKeys = MyCacheUtil.interKeys(keys);
list_sku = MyCacheUtil.getList(interKeys, OBJECT_T_MALL_SKU.class);
if (list_sku == null || list_sku.size() < 1) {
// 当前交叉检索结果
list_sku = listServiceInf.get_list_by_attr(list_attr.getList_attr(), flbh2);
// 同步redis
for (int i = 0; i < list_attr2.size(); i++) {
String key = keys[i];// attr_28_1_2
// 判断redis中是否存在
boolean if_key = MyCacheUtil.if_key(key);
if (!if_key) {
// 根据属性id,查询出属性值集合
// 循环属性值,拼接出attr的key
// key对应的sku集合
List<T_MALL_SKU_ATTR_VALUE> list_attr_for_redis = new ArrayList<T_MALL_SKU_ATTR_VALUE>();
List<OBJECT_T_MALL_SKU> list_sku_for_redis = new ArrayList<OBJECT_T_MALL_SKU>();
T_MALL_SKU_ATTR_VALUE attr_value = new T_MALL_SKU_ATTR_VALUE();
attr_value.setShxm_id(list_attr2.get(i).getShxm_id());
attr_value.setShxzh_id(list_attr2.get(i).getShxzh_id());
list_attr_for_redis.add(attr_value);
list_sku_for_redis = listServiceInf.get_list_by_attr(list_attr_for_redis, flbh2);
// 再根据属性和属性值可以查询 出对应的sku集合
// attr的可以和sku的集合循环 插入到redis
MyCacheUtil.setKey(key, list_sku_for_redis);
}
}
}
map.put("list_sku", list_sku);
return "skuList";
}
}