1
读的多 从库多 负载均衡 读写分离去解决 性能更高
考虑容灾性
双机热备 双主 切换
平峰削谷
上午
今天任务
开启redis
整合 缺 博客
SpringBoot整合Redis
切换开发环境
数据源配置
修改properties配置文件
说明:修改图片配置路径的文件 image.properties文件.
修改回windows环境
#properties的作用就是封装key=value 业务数据
image.dirPath=D:/JT-SOFT/images
#image.dirPath=/usr/local/src/images
image.urlPath=http://image.jt.com
修改host
修改nginx配置
先开nginx服务 对应conf的8090 修改yml文件和url 和host 同时 虚拟机还需要开着并需要如下所示 进入端口6379
导入redis jar包
新建一个test类
redis里面怎么敲 api里面就怎么写
如果报错 需要同时配合虚拟机的redis服务
确认下目录
新任务
自我实现
再来测试
自我实现
再来
假设执行完后 redis后台服务器挂了
所以我们要强调代码的原子性 需要一致 要成功一起成功 要失败一起失败
整合
???可以set get的结果不对
List类型
说明:Redis中的List集合是双端循环列表,分别可以从左右两个方向插入数据.
List集合可以当做队列使用,也可以当做栈使用
队列:存入数据的方向和获取数据的方向相反
栈:存入数据的方向和获取数据的方向相同
事务控制案例
查看springboot程序整合redis的现状 每次用都得new实例化 麻烦 建议给spring管理 提取共性
每一次写都得new 最好交给spring容器管理
准备配置类 注解 然后交给spring管理
配置类的位置说明
截图 11.35 缺
11.37 晚上 创建之初
配置类 就要实例化一个jedis出来 new Jedis(host,port);
(实例化代码如左)
之后 return new 一个jedis对象(ip地址加端口)
把端口号一类写死就不利于扩展了 要添加到配置文件中
package com.jt.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import redis.clients.jedis.Jedis;
@Configuration //标识我是一个配置类
@PropertySource("classpath:/properties/redis.properties")
public class JedisConfig {
@Value("${redis.host}")
private String host;
@Value("${redis.port}")
private Integer port;
/**
* 将jedis对象交给spring容器管理
*/
@Bean
public Jedis jedis(){
//由于将代码写死不利于扩展,所以将固定的配置添加到配置文件中
return new Jedis(host,port);
}
}
由配置文件管理
自我实现
放置位置 得对应好 不然和注解有无 如自己打的 就出现错误了
下午
命令不会 对应企业实际 去查http://www.redis.cn/commands.html
return方法直接查询数据库
引入redis后查询机制直接变了
有缓存应该先查询缓存 再查询是否有结果
分页操作不太适合缓存
下午正式学习api和封装数据
14.12博客 少了jsonxxxx标题
对象与JSON之间转化
对象转化为JSON
学习api
江哥测试
自我实现
所以对象只显示两个
调整后
集合形式 对象转化成json
业务接收
ObjectMapper
14.38 网址 晚上
拿到类型后 就可以转化成对象
知识点扩展
Java反射——如何通过Java中的反射调用对象的方法?
只能通过反射机制去 将json数据转化为对象的话
一.Java反射拿到调用对象的方法
1.通过Class.forName(“包名+方法的类名”)拿到方法的对象;
如:Class<?> clazz = Class.forName("ReflectionTest");
也可以通过实例,获取方法的对象类,
如:String str = "test , reflection";
Class<?> clazz = str.getClass();
2.明确反射方法名称 ;
3.明确方法的参数类型,就可以拿到对象的方法。
如:Method method = clazz.getMethod("test",String.class,int.class);
指定对象名称 把itemDesc存进去(拿到类型)
拿到类型之后 可以去实例化一个对象(获得json的类型 初步转化为对象实现ing)
拿到xxxx.class之后------>(可以转化成)空对象(有属性没有值 有key无value)------->
指定下对象得名称
但是对象是空的
对象和json怎么转换的
对象转化成JSON 凭什么有个注解就可以转化成json
对象身上有属性
14.47前 缺一个错误图片
json怎么转化成功的呢
age不是一个属性
竟然把getAge获取到了
总结
其实就是 json和get相关
原理说明:对象转化为json串时调用的是对象的getxxx()方法.
- get 必须是公有的
json 转化成对象 和pojo的set有关
package com.jt.controller;
import com.jt.pojo.JSONPOJO;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class JSONController {
/**
* 获取json数据
* 原理说明: 对象转化为json串时调用的是对象的getxxx()方法.
* 调用步骤: 1.获取所有的getId()
* 2.去掉开头的get之后(Id)将剩余的字母首字母小写(id),当做key
* 3.调用getId()方法,获取属性的值,之后形成数据的拼接.
* {"id":"1","name":"tomcat"}
* json转化为对象:
* json串:{"id":"1","name":"tomcat"}
* 1.传递xxx.class的类型 可以转化为空对象.
* 2.从json串中获取第一个key=id
* 3.之后为id拼接字符串形成set方法setId().
* 4.调用对象身上的set方法完成赋值操作.
*/
@RequestMapping("/getJSON")
public JSONPOJO getJSON(){
return new JSONPOJO();
}
}
自我实现
如果少了get/set 删去lombok
也侧面说明了 少了get
pojo对象就不能转化成string类型(字符串类型)的JSON串输出
继续
实际是根据需求 看要的是json 还是对象数据 一般是json常用
对象转化为JSON
package com.jt.test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.pojo.ItemDesc;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class ObjectMapperTest {
//实现对象与JSON之间的转化
//任务: 对象转化为json
@Test
public void test01(){
ObjectMapper objectMapper = new ObjectMapper();
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(100L).setItemDesc("json测试")
.setCreated(new Date()).setUpdated(new Date());
try {
//1.将对象转化为json
String result = objectMapper.writeValueAsString(itemDesc);
System.out.println(result);
//2.将json数据转化为对象 只能通过反射机制..
//给定xxx.class类型 之后实例化对象.利用对象的get/set方法为属性赋值.
ItemDesc itemDesc2 = objectMapper.readValue(result,ItemDesc.class);
System.out.println(itemDesc2.toString());
System.out.println(itemDesc2.getCreated());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
@Test
public void test02(){
ObjectMapper objectMapper = new ObjectMapper();
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(100L).setItemDesc("json测试")
.setCreated(new Date()).setUpdated(new Date());
List<ItemDesc> list = new ArrayList<>();
list.add(itemDesc);
list.add(itemDesc);
//1.将对象转化为JSON
try {
String json = objectMapper.writeValueAsString(list);
System.out.println(json);
//2.json转化为对象
List<ItemDesc> list2 = objectMapper.readValue(json, list.getClass());
System.out.println(list2);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
继续
封装ObjectMapperUtil
业务说明
为了降低工具API ObjectMapper中的异常处理,需要准备一些工具API简化代码的调用.
方法1: 将任意的对象转化为JSON.
方法2: 将任意的JSON串转化为对象.
要求完成异常的处理.
定义工具API
任意的对象转化成Json
调一个new一个不太好
优化
如上为优化
任意的json转化成对象
扩展
工具api不知道用户要穿什么呢 用泛型去代替
说明:在jt-common中添加工具API对象
package com.jt.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.util.StringUtils;
public class ObjectMapperUtil {
//定义常量对象
// 优势1: 对象独一份节省空间
// 优势2: 对象不允许别人随意篡改
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 1.将任意对象转化为JSON
* 思考1: 任意对象对象应该使用Object对象来接
* 思考2: 返回值是JSON串 所以应该是String
* 思考3: 使用什么方式转化JSON FASTJSON/objectMapper
*/
public static String toJSON(Object object){
try {
if(object == null){
throw new RuntimeException("传递的参数object为null,请认真检查");
}
return MAPPER.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
//应该将检查异常,转化为运行时异常.
throw new RuntimeException("传递的对象不支持json转化/检查是否有get/set方法");
}
}
//2.将任意的JSON串转化为对象 传递什么类型转化什么对象
public static <T> T toObject(String json,Class<T> target){
if(StringUtils.isEmpty(json) || target == null){
throw new RuntimeException("传递的参数不能为null");
}
try {
return MAPPER.readValue(json,target);
} catch (JsonProcessingException e) {
e.printStackTrace();
throw new RuntimeException("json转化异常");
}
}
}
测试工具API是否可用
@Test
public void test03(){
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(100L).setItemDesc("json测试")
.setCreated(new Date()).setUpdated(new Date());
String json = ObjectMapperUtil.toJSON(itemDesc);
ItemDesc itemDesc2 =
ObjectMapperUtil.toObject(json, ItemDesc.class);
System.out.println(json);
System.out.println(itemDesc2);
}
自我实现 晚上理清
继续
再
/**
* 步骤:
* 先查询Redis缓存 K:V
* true 直接返回数据
* false 查询数据库
*
* KEY有什么特点: 1.key应该动态变化 2.key应该标识业务属性
* key=ITEM_CAT_PARENTID::parentId
* @param parentId
* @return
*/
@Override
public List<EasyUITree> findItemCache(Long parentId) {
//0.定义空集合
List<EasyUITree> treeList = new ArrayList<>();
String key = "ITEM_CAT_PARENTID::"+parentId;
//1.从缓存中查询数据
String json = jedis.get(key);
//2.校验JSON中是否有值.
if(StringUtils.isEmpty(json)){
//3.如果缓存中没有数据,则查询数据库
treeList = findItemCatList(parentId);
//4.为了实现缓存处理应该将数据添加到redis中.
//将数据转化为json结构,保存到redis中
json = ObjectMapperUtil.toJSON(treeList);
jedis.set(key, json);
System.out.println("第一次查询数据库!!!!");
}else{
//标识程序有值 将json数据转化为对象即可
treeList =
ObjectMapperUtil.toObject(json,treeList.getClass());
System.out.println("查询Redis缓存服务器成功!!!!");
}
return treeList;
}
自我实现商品分类的缓存
编辑ItemCatController
service层
优化 记录下时间
浏览器机制 第一次和redis建立通信 需要耗时 还要浏览器的css样式也需要耗时
远程链接 把数据传过去
第二次redis查询就不需要链接了
ps 留作问题
自我实现
报错
实现效果
再刷新
第二次调用redis
可见性能之优越
自我尝试
window环境下运行的时候 是否还需要虚拟机对应的192.168.126.129 的redis服务
正常实现
尝试
关闭Redis命令:
方式1. kill -9/15 PID号
方式2. redis-cli -p 6379 shutdown
已关闭端口
关联虚拟机的redis服务关闭后 瞬间需要redis的选择类目模块就查询不到了
证明 还是需要虚拟机上的redis服务 步骤没错
虚拟机还需要开着并需要如下所示 进入端口6379 然后开nginx服务 对应改conf的8091 修改本地服务器里的yml文件和url 和host
重新开启
重启服务器
完美复现