亿级流量架构|day09-Redis入门

1 Redis命令

1.Hash类型
说明:可以用散列类型保存对象和属性的值,表现为value部分为一个HashMap。
例子:User对象{id:2, name:小明, age:19}
在这里插入图片描述

2.List类型
说明:Redis中的List集合是双端循环列表(双向列表),分别可以从左右两个方向插入数据。
List集合可以当做队列来使用,也可以当做栈来使用。
队列:先进先出,存/取数据的方向不一致。
栈:先进后出,存/取数据的方向一致。
在这里插入图片描述

3.Redis事务命令
业务需求:

  • redis可以当做数据库使用。
  • 有时插入缓存时,可能多数据一起插入,所以需要事务控制。

说明:redis中操作可以添加事务的支持,一项任务可以由多个redis命令完成,如果有一个命令失败导致入库失败时,需要实现事务回滚。
在这里插入图片描述

2 Redis入门案例

2.1 引入jar包

<!-- jedis -->
<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>${jedis.version}</version>
</dependency>

<!--添加spring-datajar包  -->
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-redis</artifactId>
	<version>1.4.1.RELEASE</version>
</dependency>

2.2 测试字符串

//测试String类型    IP:端口
/**
 * 1.检测防火墙是否关闭了
 * 2.检查IP绑定是否注释了  默认绑定本机(Linux)  #bind ip 关闭后重启
 * 3.保护模式是否关闭  默认值yes   改为no  修改后重启
 * 4.启动方式不对...... redis-server redis.conf
 */
@Test
public void testString(){
	Jedis jedis = new Jedis("192.168.126.166", 6379);
	Long start = System.currentTimeMillis();
	jedis.set("1806","今天星期一困的不行,一周总有那么7天不想上课");
	Long end = System.currentTimeMillis();
	System.out.println(end-start+"毫秒");
	System.out.println
	("获取redis内容:"+jedis.get("1806"));
}

2.3 测试Hash

//测试hash值 读11万/s  写8.1万/s 10万/s
@Test
public void testHash(){
	Jedis jedis = new Jedis("192.168.126.166", 6379);
	jedis.hset("person", "id", "100");
	jedis.hset("person", "name", "1806班");
	jedis.hset("person", "age", "4");
	Map<String,String> map = jedis.hgetAll("person");
	System.out.println(map);
}

2.4 测试List

@Test
public void testList(){
	Jedis jedis = new Jedis("192.168.126.166", 6379);
	//下面代码中是可变参数 使用,号分割
	jedis.lpush("list","1","2","3","4");
	System.out.println(jedis.rpop("list"));
}

2.5 Redis事务控制

/**
 * redis.clients.jedis.exceptions.JedisDataException: Cannot use Jedis when in Multi. Please use JedisTransaction instead.
 * 说明:因为使用redis事务控制需要开启事务/提交事务/回滚事务
 * 这部分代码如果直接写入业务层,则代码的耦合性高
 * 所以可以通过AOP+自定义注解redisTx
 * 抽空说说
 */
@Test
public void testTx(){
	Jedis jedis = new Jedis("192.168.126.166", 6379);
	//开启事务控制
	Transaction tansaction = jedis.multi();
	//执行入库操作
	tansaction.set("aa", "事务测试");
	tansaction.set("bb", "bb");
	//事务提交
	//tansaction.exec();
	//事务回滚
	tansaction.discard();
	System.out.println("获取数据:"+jedis.get("aa"));
}

3 Spring整合Redis

3.1 编辑pro文件

1.新建redis.properties文件

redis.host=192.168.126.166
redis.port=6379

2.导入配置文件

<list>
	<value>classpath:/property/jdbc.properties</value>
	<value>classpath:/property/redis.properties</value>
</list>

3.2 编辑配置文件

<!--spring整合redis 
	Jedis jedis = new Jedis("192.168.126.166", 6379);
	
	关于构造注入的注意事项
	1.name属性:代表构造方法中的参数名称
	注意事项:在使用构造注入时,程序打包部署时最好添加源码!!!!
	如果没有导入源码.那么程序不会维护形参 则名称为arg0,arg1,arg2.
	2.index属性
		表示下标,从0开始.根据参数位置匹配构造方法.
		User(String a,String b)
		User(int a,String b)
		User(Dog dog,String a)
	3.type=""属性
		表示参数类型,一般默认不写.由spring框架内部自动进行强转.
		所以在为参数赋值时,必须严格的规范构造方法.否则
		注入会有问题.		
 -->
<!--  <bean id="jedis" class="redis.clients.jedis.Jedis">
 	<constructor-arg index="0"  value="${redis.host}"  type="Dog"/>
 	<constructor-arg index="1"  value="${redis.port}"  type="int"/>
 </bean> -->
 <bean id="jedis" class="redis.clients.jedis.Jedis">
 	<constructor-arg name="host"  value="${redis.host}"/>
 	<constructor-arg name="port"  value="${redis.port}"/>
 </bean>

4 JSON回顾

4.1 json官网介绍

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。

4.2 object格式

语法:

  • 对象是一个无序的名称/值对集合
  • 一个对象以"{"(左大括号)开始,"}"(右大括号)结束
  • 每个名称后跟一个":"(冒号)
  • 名称/值对之间使用","(逗号)分割

{key:value}
在这里插入图片描述

例子:{“id”:“1”,“name”:“tom”}
简单写法:key和数字可以不加引号

4.3 array格式

说明:通过数组形式保存数据
格式:数组·是·值(value)的有序集合,一个数组以"["(左中括号)开始,"]"(右中括号)结束,值之间用","(逗号)分隔。
[value1,value2,value3]
图例:
在这里插入图片描述

例子:[1,2,3,4,5,“tom”]

4.4 复杂格式

特点:可以将object格式和array格式进行·无限层级嵌套
说明:值(value)可以是双括号括起来的字符串(string)、数值(number)、true、false、null、对象(object)或者数组(array)。这些结构可以嵌套。

图例:
在这里插入图片描述

例子:

{
	id:1,
	name:"tomcat",
	hobby:[
		["早点","午饭","下午茶"],
		"喝",
		{
			where:"沙滩",
			time:"半夜",
			with:"鲨鱼"
		}
	]
}

5 JSON与对象转化

5.1 对象转为JSON串

//将对象转化为JSON
@Test
public void ObjectToJSON() throws JsonProcessingException{
	User user = new User();
	user.setId(1);
	user.setName("tomcat猫");
	user.setAge(19);
	
	ObjectMapper objectMapper = new ObjectMapper();
	//转化时调用对象的getXXX()
	String json = 
			objectMapper.writeValueAsString(user);
	System.out.println(json);
}

5.2 JSON转对象

@Test
public void jsonToObject() throws JsonParseException, JsonMappingException, IOException{
	String json = "{\"id\":\"1\",\"name\":\"tomcat\"}";
	ObjectMapper objectMapper = new ObjectMapper();
	User user = objectMapper.readValue(json,User.class);
	System.out.println(user);
}

5.3 复杂格式转化

@Test
public void jsonOA() throws IOException{
	List<User> userList = new ArrayList<>();
	User user1 = new User();
	user1.setId(1);
	user1.setName("tomcat猫");
	user1.setAge(19);
	user1.setSex("男");
	User user2 = new User();
	user2.setId(2);
	user2.setName("tomcat猫");
	user2.setAge(19);
	user2.setSex("男");
	userList.add(user1);
	userList.add(user2);
	
	ObjectMapper objectMapper = new ObjectMapper();
	String json = objectMapper.writeValueAsString(userList);
	//System.out.println("获取JSON串:"+json);
	
	//2.将复杂格式的JSON转化为对象List
	//List<User> uList = 
			//objectMapper.readValue(json, userList.getClass());
	//System.out.println("获取对象:"+uList);
	
	User[] users = 
			objectMapper.readValue(json,User[].class);
	
	//将数组转化为List集合
	List<User> uList = Arrays.asList(users);
	System.out.println(uList);
}

6 缓存实现商品分类查询

6.1 缓存实现步骤

1.修改业务逻辑,首先用户查询先查询redis缓存
2.如果无缓存数据,表示第一次查询该数据,则先从数据库查找
3.找到数据后,将数据通过API转化为JSON串,将数据k-v写入缓存中
4.如果缓存数据不为null,则将JSON串转化为java对象,直接return返回。

6.2 编辑controller

/**
 * 实现商品分类目录展现
 * @RequestParam
 * 	defaultValue= 如果没有传递参数 默认值为...
 *  required=true/false 默认为false  如果true 那么前台必须传递该参数.
 *  value 需要转化变量的名称
 * @param parentId
 * @return
 */
@RequestMapping("/list")
@ResponseBody
public List<EasyUITree> findItemCatById(
		@RequestParam(value="id",
		defaultValue="0") 
		Long parentId){
	//查询一级商品分类目录
	//Long parentId = 0L;
	//return itemCatService.findItemCatById(parentId);
	return itemCatService.findCacheItemCatById(parentId);
}

6.3 编辑service

1.注入对象
在这里插入图片描述

2.业务代码

//通过redis缓存实现信息查询
@Override
public List<EasyUITree> findCacheItemCatById(Long parentId) {
	List<EasyUITree> treeList = null;
	
	//1.先查询缓存数据
	String key = "ITEM_CAT_"+parentId;
	String resultJSON = jedis.get(key);
	
	try {
		//2.判断缓存中是否有数据
		if(StringUtils.isEmpty(resultJSON)){
			//2.1表示缓存中没有数据,需要查询后台数据库
			treeList = findItemCatById(parentId);
			
			//2.2将java对象转化为JSON串
			String jsonData = objectMapper.writeValueAsString(treeList);
			
			//2.3将数据写入缓存
			jedis.set(key, jsonData);
			System.out.println("第一次查询数据库");
		}else {
			//3.缓存中有数据
			//3.1将JSON串转化为java对象(List)
			EasyUITree[] trees = 
			objectMapper.readValue(resultJSON,EasyUITree[].class);
			treeList = Arrays.asList(trees);
			System.out.println("查询缓存数据");
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
	
	return treeList;
}

6.4 时间比较

1.没有添加缓存时
在这里插入图片描述

2.添加缓存时
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值