1、思路讲解
1.1、添加购物车
当用户点击商品详情,查看商品时,点击了添加购物车,在添加购物的时,需要将商品的相关信息添加到redis数据库中,可以将这些添加到购物车中的信息封装成给实体类,就定义成Cart实体类,而这给实体类中需要存在的属性,需要的是能够在购物车展示时必须要使用到属性,如:商品对象(通过商品对象可以展示出商品的单价,以及商品对应的编号,每个用户只能对应一个商品编号的购物车,当成hashkey)、用户id(用户id是唯一的,需要通过用户id当成存储在Redis中唯一的Hash的Key)、数量。
1.2、查看用户对应的购物车
当用户点击购物车的时候,需要去进行查询用户对应的购物车详细,返回给前端数据,前端绑定数据到界面展示效果,而数据的获取需要通过用户id去到的。所以后端接口需要接收一个用户的id,通过id去获取这个redis中存储的值。
1.3、更改商品数量
当用户在购物车界面点击了加/减/数量输入的操作的时候,redis中数据也要跟着一起改变,这里就要进行ajax处理,对redis中的数据进行操作,如何去操作?通过Key先找到用户对应的购物车,随后根据商品的id找到hashkey中对应的value值,进行value值得更新。
1.4、删除购物车
思路跟1.3中的思路差不多,但是这里它需要的是执行删除操作,需要通过用户的id跟商品的编号去删除,所对应的value值
2、基本配置
2.1、配置pom.xml相关依赖
<!-- redis -->
<properties>
<spring-data-redis.version>1.7.1.RELEASE</spring-data-redis.version>
<jedis.version>2.9.0</jedis.version>
</properties>
<!-- 配置Redis的相关依赖 -->
<!-- redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-pool2</artifactId>
<groupId>org.apache.commons</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Json相关依赖 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.47</version>
</dependency>
2.2、配置redis的连接文件(propreties文件)
#ip地址
redis.hostName=127.0.0.1
#端口号
redis.port=6379
#如果有密码
redis.password=
#客户端超时时间单位是毫秒 默认是2000
redis.timeout=10000
#redis缓存数据过期时间单位秒
redis.expiration=3600
##################### redis连接池配置 ###########################################
#最大空闲数
redis.maxIdle=300
#连接池的最大数据库连接数。设为0表示无限制,如果是jedis 2.4以后用redis.maxTotal
#redis.maxActive=600
#控制一个pool可分配多少个jedis实例,用来替换上面的redis.maxActive,如果是jedis 2.4以后用该属性
redis.maxTotal=1000
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
redis.maxWaitMillis=1000
#连接的最小空闲时间 默认1800000毫秒(30分钟)
redis.minEvictableIdleTimeMillis=300000
#每次释放连接的最大数目,默认3
redis.numTestsPerEvictionRun=1024
#逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
redis.timeBetweenEvictionRunsMillis=30000
#是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
redis.testOnBorrow=true
#在空闲时检查有效性, 默认false
redis.testWhileIdle=true
spring-redis的集成配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:contet="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 1.导入redis配置文件 -->
<!-- <contet:property-placeholder location="redis.properties"/>-->
<!-- 2.创建redis数据库连接池 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--最大空闲数-->
<property name="maxIdle" value="${redis.maxIdle}"/>
<!--连接池的最大数据库连接数 -->
<property name="maxTotal" value="${redis.maxTotal}"/>
<!--最大建立连接等待时间-->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
<!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟)-->
<property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"/>
<!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3-->
<property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"/>
<!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1-->
<property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"/>
<!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->
<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
<!--在空闲时检查有效性, 默认false -->
<property name="testWhileIdle" value="${redis.testWhileIdle}"/>
</bean>
<!-- 3.创建redis连接工厂类 -->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
destroy-method="destroy">
<property name="poolConfig" ref="poolConfig"/>
<!--IP地址 -->
<property name="hostName" value="${redis.hostName}"/>
<!--端口号 -->
<property name="port" value="${redis.port}"/>
<!--如果Redis设置有密码 -->
<property name="password" value="${redis.password}"/>
<!--客户端超时时间单位是毫秒 -->
<property name="timeout" value="${redis.timeout}"/>
</bean>
<!-- 4.创建redistemplate模板类 -->
<!-- redis操作模板,使用该对象可以操作redis -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<!--redis是key-value-->
<property name="connectionFactory" ref="connectionFactory"/>
<!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!! -->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
</property>
<!--开启事务 -->
<property name="enableTransactionSupport" value="false"/>
</bean>
</beans>
2.3、配置json的接收以及json对象的转换(在Spring-MVC中)
<!--配置JSON对象接收-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- json转换器 -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
3、代码实现
实现功能的service包下的接口
package com.zking.fresh.service;
import com.zking.fresh.model.Cart;
import java.util.List;
public interface ICartRedisService {
/**
* 添加购物车方法
* @param cart
*/
Integer addCart(Cart cart);
/**
* 查看购物车方法
* @param uid
*/
List<Cart> listCart(Integer uid);
/**
* 删除单个商品
* @param cart
*/
Boolean delCart(Cart cart);
/**
* 修改购物车商品
* @param cart
*/
void updateCart(Cart cart,String type);
/**
* 删除所有购物车商品
* @param cart
*/
void delAll(Cart cart);
}
实现类
package com.zking.fresh.service.imp;
import com.zking.fresh.model.Cart;
import com.zking.fresh.service.ICartRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Redis实现购物基本功能方法
*/
@Service
public class CartRedisServiceImpl implements ICartRedisService {
@Autowired
private RedisTemplate<String,Object> template;
public HashOperations<String, Object, Object> getOpsHash(){
return template.opsForHash();
}
@Override
public Integer addCart(Cart cart) {
//判断购物车商品是否存在
Cart cart1 = (Cart) getOpsHash().get(cart.getUsersId() + "", cart.getGoodsId() + "");
//判断不为空时候说明用户有购物车存在
if(cart1!=null){
//更新数量
cart1.setCartNum(cart.getCartNum()+cart1.getCartNum());
//更新redis数据
getOpsHash().put(cart1.getUsersId()+"",cart1.getGoodsId()+"",cart1);
//return
return 1;
}else{
//不存在则将数据添加到redis中
getOpsHash().put(cart.getUsersId()+"",cart.getGoodsId()+"",cart);
//return
return 2;
}
}
/**
* 查询购物车
* @param uid
* @return
*/
@Override
public List<Cart> listCart(Integer uid) {
//获取当前用户的所有购物车数量
Map<Object, Object> entries = getOpsHash().entries(uid + "");
Set<Map.Entry<Object, Object>> entries1 = entries.entrySet();
//获取内部所有的值
List<Cart> carts = new ArrayList<>();
for (Map.Entry<Object, Object> objectObjectEntry : entries1) {
carts.add((Cart) objectObjectEntry.getValue());
}
return carts;
}
/***
* 删除购物车商品
* @param cart
* @return
*/
@Override
public Boolean delCart(Cart cart) {
Long delete = getOpsHash().delete(cart.getUsersId() + "", cart.getGoodsId() + "");
if (delete>0)
return true;
else
return false;
}
/**
* 修改商品数量
* @param cart
* @param type
*/
@Override
public void updateCart(Cart cart,String type) {
//获取到对应的商品
Cart o = (Cart) getOpsHash().get(cart.getUsersId() + "", cart.getGoodsId() + "");
//判断类型
if(type.equals("1")){
//加
o.setCartNum(o.getCartNum()+1);
}else if(type.equals("2")){
//减
o.setCartNum(o.getCartNum()-1);
}else{
//输入
o.setCartNum(cart.getCartNum());
}
//更新redis中的数量
getOpsHash().put(cart.getUsersId()+"",cart.getGoodsId()+"",o);
}
@Override
public void delAll(Cart cart) {
Long delete = getOpsHash().delete(cart.getUsersId() + "", "*");
}
}
最后在对应的controller层调用对应的接口方法即可 !