京淘后端商品管理-Day11

1.课程准备

1.1 关闭无效服务

1).关闭Linux数据库服务器 systemctl stop mariadb
2).关闭Linux中的tomcat服务器
在这里插入图片描述
3).关闭Linux中的Nginx服务器

	[root@localhost sbin]# ./nginx  -s   stop

4).修改windows Hosts文件
在这里插入图片描述

5).修改数据库链接地址

spring:
  datasource:
    #引入druid数据源
    #type: com.alibaba.druid.pool.DruidDataSource
    #driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

6).修改图片上传的路径

image.localDir=D:/JT-SOFT/images
#image.localDir=/usr/local/src/images
image.imageUrl=http://image.jt.com
image.imageTypes=.jpg,.png,.gif,.jpeg

7).修改nginx配置文件
在这里插入图片描述

2.Redis缓存

2.1 为什么需要使用缓存

说明:使用缓存可以有效的降低用户访问物理设备的频次,有效的减少并发的压力。保护后端真实的服务器。
在这里插入图片描述

2.2 缓存应该如何设计

1.缓存应该使用什么样的数据结构. K-V KEY必须唯一
2.如果需要缓存进行快速的读取,首先开发语言如何选择? C语言 软件的运行环境如何选择. 内存中
3.如何防止内存数据丢失! 缺点: 断电即擦除 内存数据的持久化操作(内存数据保存到磁盘中)
4.缓存的空间大小如何维护. 不能一直存,有时也会删除数据 如何操作? 内存优化算法: LRU算法/LFU算法
5.缓存使用如何防止宕机带来的影响 (HA)高可用 部署redis集群.

2.3 Redis介绍

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)

nosql: 非关系型数据库 redis ,mongdb,hbase;
消息中间件: 主要的作用是为了实现数据的平滑过渡,让程序调用更加流畅(润滑剂)
在这里插入图片描述
性能问题: 读速度 11.2万次/秒 写 8.6万次/秒 平均 10万次/秒

2.4 Redis安装

2.4.1上传redis安装包

上传安装包,之后解压
在这里插入图片描述
在这里插入图片描述

2.4.2 安装redis

说明:在redis的根目录中执行
1). make
2). make install
在这里插入图片描述

扫描二维码关注公众号,回复: 11398939 查看本文章

2.5修改配置文件

2.5.1 知识补充

1).补充知识
如果修改配置文件时,出现了.swp文件,则表示上一次改文件没有正确的保存,生成了保护性文件.所以一般删除改文件即可
方式1: 如果提示按D删除,则按D
方式2: 如果没有按D提示,则 采用 rm -rf .xxxxx.swp
在这里插入图片描述

2.5.2 编辑redis.conf

1).命令 vim redis.conf
2).修改ip绑定
在这里插入图片描述
3).修改保护模式
在这里插入图片描述
4).开启后台启动
在这里插入图片描述

2.5.3 关于redis服务器命令

1.启动redis redis-server redis.conf
2.进入客户端 redis-cli -p 6379
3.关闭redis redis-cli -p 6379 shutdown
简化操作: 如果操作的redis是默认的端口 则可以省略不写.

redis-cli    & redis-cli   shutdown

2.6 Redis入门案例

2.6.1 导入jar包

		<!--spring整合redis -->
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
		</dependency>

2.6.2 编辑测试类

	package com.jt.test;

import org.junit.jupiter.api.Test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.params.SetParams;

public class TestRedis {
	
	/**
	 * 1.spring整合redis
	 * 报错说明:
	 * 	1).如果测试过程中报错 则检查redis配置文件  改3处
	 *  2).检查redis启动方式   redis-server redis.conf
	 *  3).检查Linux的防火墙
	 * 	做完的 测试其他命令.
	 */
	@Test
	public void testString01() {
		
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		//2.操作redis
		jedis.set("a", "redis入门案例");
		String value = jedis.get("a");
		System.out.println(value);
	}
	
	@Test
	public void testString02() {
		
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		//2.判断当前数据是否存在
		if(jedis.exists("a")) {
			System.out.println(jedis.get("a"));
		}else {
			
			jedis.set("a", "测试是否存在的方法");
		}
		
	}
	
	/**
	 * 1.能否简化是否存在的判断
	 * 2.如果该数据不存在时修改数据,否则不修改
	 * setnx方法:  只有当数据不存在时赋值.
	 */
	@Test
	public void testString03() {
	
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		jedis.setnx("a", "测试setnx方法1");
		jedis.setnx("a", "测试setnx方法2");
		System.out.println(jedis.get("a"));
	}
	
	/**
	 * 为数据添加超时时间
	 * @throws InterruptedException 
	 * setex方法  保证赋值操作和添加超时时间的操作的原子性
	 * 原子性: 要么同时成功,要么同时失败(类似事务)
	 */
	@Test
	public void testString04() throws InterruptedException {
	
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		
		jedis.set("a", "aaaa"); //如果程序报错,则超时方法将不会执行,改数据将永不超时
		//程序报错,意外终止!!!!!!!
		jedis.expire("a", 20);	//添加超时时间    不是原子性操作
		Thread.sleep(2000);
		System.out.println("剩余存活时间:"+jedis.ttl("a"));
		
		//2.实现原子性操作
		jedis.setex("b", 20, "原子性测试");
		System.out.println(jedis.get("b"));
		
	}
	
	
	/**
	 *
	 * 1.只有数据不存在时允许修改
	 * 2.要求实现添加超时时间,并且是原子性操作
	 * SetParams 参数说明:
	 * 	1.NX   只有key不存在时才能修改
	 * 	2.XX   只有key存在时,才能修改
	 *  3.PX   添加的时间单位是毫秒
	 *  4.EX   添加的时间单位是秒
	 */
	@Test
	public void testString05(){
	
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		SetParams params = new SetParams();
		params.xx().ex(20);
		jedis.set("aa", "测试A", params);	
		jedis.set("aa", "测试B", params);	
		System.out.println(jedis.get("aa"));
	}
	
	
	
	/**
	 * 存储一类数据时,可以使用hash.
	 */
	@Test
	public void testHASH(){
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		jedis.hset("user", "name", "tomcat");
		jedis.hset("user", "id", "100");
		System.out.println(jedis.hgetAll("user"));
	}
	
	
	@Test
	public void testList(){
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		jedis.lpush("list", "1","2","3","4");
		System.out.println(jedis.rpop("list"));
		
	}
	
	//控制事务
	@Test
	public void testTx(){
		//1.创建jedis对象
		Jedis jedis = new Jedis("192.168.126.129", 6379);
		jedis.flushAll(); //清空所有的redis缓存
		
		Transaction transaction = jedis.multi();		//2.开启事务
		try {
			transaction.set("aaa", "aaa");
			transaction.set("bbb", "bbbbb");
			transaction.set("ccc", "cccccc");
			transaction.exec();			//事务提交
		} catch (Exception e) {
			e.printStackTrace();
			transaction.discard();		//事务回滚
		}
	}
}
	
	

2.7 Spring整合Redis

2.7.1 整合思路

说明:将jedis对象交给spring容器进行管理.之后哪里需要直接注入即可.
步骤:
1.编辑redis.properties文件,指定redis节点的ip:port
2.由于redis比较重要,很多业务系统都需要调用,所以将redis整合写入common
3.通过配置类(配置文件)形式整合redis.

2.7.2 编辑redis.properties文件

1).配置文件位置
在这里插入图片描述
2.编辑配置文件

	redis.host=192.168.126.129
	redis.port=6379

2.7.3 编辑配置类

	@Configuration 	//我是一个配置类    一般都会与@Bean联用
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
	
	@Value("${redis.host}")
	private String host;
	@Value("${redis.port}")
	private Integer port;
	
	//将返回值的结果交给spring容器进行管理,如果以后想要使用该对象则可以直接注入.
	@Bean
	public Jedis jedis() {
		
		return new Jedis(host, port);
	}
	
}

2.8.json格式转化问题

2.8.1 json转化API

package com.jt.test;

import java.util.Date;

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.pojo.ItemDesc;

public class TestObjectMapper {
	
	//改对象就是工具api  有且只有一份即可.并且不允许别人修改.
	private static final ObjectMapper MAPPER = new ObjectMapper();
	/**
	 * 目的: 实现对象与json串之间的转化
	 * 步骤1:  将对象转化为json
	 * 步骤2:  将json转化为对象 
	 * 利用ObjectMapper 工具API实现
	 * @throws JsonProcessingException 
	 */
	@Test
	public void test01() throws JsonProcessingException {
		
		ItemDesc itemDesc = new ItemDesc();
		itemDesc.setItemId(101L).setItemDesc("json转化测试")
		.setCreated(new Date()).setUpdated(itemDesc.getCreated());
		
		//1.将对象转化为JSON   调用的是对象的get方法
		String json = MAPPER.writeValueAsString(itemDesc);
		System.out.println(json);
		
		//2.将json转化为对象   传递需要转化之后的class类型   调用是对象的set方法
		ItemDesc itemDesc2 = MAPPER.readValue(json, ItemDesc.class);
		System.out.println(itemDesc2.getItemDesc());
	}
}

2.8.2 封装ObjectMapperUtil

说明:改API主要负责将对象转化为JSON,将JSON转化为对象,同时优化异常处理.

	package com.jt.util;

import org.springframework.util.StringUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ObjectMapperUtil {
	
	//json与对象的转化   优化异常处理
	private static final ObjectMapper MAPPER = new ObjectMapper();
	
	//1.将对象转化为JSON
	public static String toJSON(Object target) {
		
		if(target == null) {
			throw new NullPointerException("taget数据为null");
		}
		
		try {
			return MAPPER.writeValueAsString(target);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
			throw new RuntimeException(e); //如果转化过程中有问题则直接抛出异常
		}
		
	}


	//2. 将json串转化为对象   用户传递什么样的类型,就返回什么样的对象!!!
	// <T>  定义了一个泛型对象  代表任意类型
	public static <T> T toObject(String json,Class<T> targetClass) {
		
		if(StringUtils.isEmpty(json) || targetClass == null) {
			throw new NullPointerException("参数不能为null");
		}
		
		try {
			return MAPPER.readValue(json, targetClass);
		} catch (JsonProcessingException e) {
			
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
}

2.9 商品分类缓存实现

2.9.1 实现策略

在这里插入图片描述
业务说明:商品分类信息可以使用redis缓存实现该功能.
步骤:
1.当用户点击商品分类按钮时开始获取服务端数据.
2.先查询redis缓存是否有数据
3.如果redis中没有数据,则查询数据库.之后将查询的结果保存到redis中
4.如果redis中有数据,则直接返回缓存记录.

数据库存储结构问题:
K-V结构 key=“包含parentId” value= 查询之后的返回值结果 List
String数据类型 redis使用频率最高.
问题: List----JSON—>Stirng

作业

1.试着完成redis缓存 修改源码即可
2.复习AOP 利用aop形式实现redis缓存

猜你喜欢

转载自blog.csdn.net/qq_16804847/article/details/107400965
今日推荐