缓存数据库的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 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里
选择zset数据结构是因为:1.检索结果需要排序;2.检索结果需要分页。

真实环境中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";
	}

}

猜你喜欢

转载自blog.csdn.net/xiao__jia__jia/article/details/86497392