共计 6309 个字符,预计需要花费 16 分钟才能阅读完成。
整合 Redis
引入 jar 包
<!--spring 整合 redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
入门 API 测试案例
//@SpringBootTest 如果须要在测试类中引入 spring 容器机制才应用此注解
public class TestRedis {
/**
* 测试近程 redis 服务器是否可用
* host: 192.168.126.129
* port: 6379 * 思路: 1. 实例化对象
* 2. 利用对象执行 redis 命令
* 报错调试:1. 查看 redis.conf 的配置文件是否依照要求批改 ip/ 爱护 / 后盾
* 2.redis 启动形式 redis-server redis.conf
* 3. 敞开防火墙 systemctl stop firewalld.service
*/ @Test
public void test01(){Jedis jedis=new Jedis("192.168.126.129", 6379);
jedis.set("redis", "测试 redis 是否可用");
System.out.println(jedis.get("redis"));
}
/**
* String 类型 API 练习
* 需要: 判断 key 是否存在于 redis, 如果存在则赋值, 否则入库
*/
@Test
public void test02(){Jedis jedis=new Jedis("192.168.126.129", 6379);
if(jedis.exists("redis")){System.out.println("数据已存在");
jedis.expire("redis", 10);
}else{jedis.set("redis","aaaa");
}
System.out.println(jedis.get("redis"));
}
/**
* 能够利用优化的 API 实现业务性能
* 业务: 如果数据存在则不赋值
*/
@Test
public void test03(){Jedis jedis=new Jedis("192.168.126.129", 6379);
jedis.flushAll();// 清空 redis 服务器
//jedis.set("redis","111");
// 如果 key 存在则不做任何操作
jedis.setnx("redis", "测试赋值操作!");
System.out.println(jedis.get("redis"));
}
/**
* 测试增加超时工夫的有效性
* 业务: 向 redis 中保留一个数据之后, 要求设定 10s 无效
* 原子性: 要么同时胜利, 要么同时失败
*/
@Test
public void test04(){Jedis jedis=new Jedis("192.168.126.129", 6379);
/*jedis.set("aa","aa");// 数据不删除
int a=1/0; jedis.expire("aa", 10);*/ jedis.setex("aa", 10, "aa");// 单位秒
//jedis.psetex() 单位毫秒}
/**
* 需要: 增加一个数据, 只有数据存在时才会赋值, 并且须要增加超时工夫
* 保障原子性操作
* private static final String XX = "xx"; 有 key 才赋值
* private static final String NX = "nx"; 没有 key 才赋值
* private static final String PX = "px"; 毫秒
* private static final String EX = "ex"; 秒
*
* redis 分布式锁问题
*/
@Test
public void test05(){Jedis jedis=new Jedis("192.168.126.129", 6379);
SetParams setParams=new SetParams();
setParams.xx().ex(10);
jedis.set("aaa", "aaa",setParams);
}
@Test
public void testhash(){Jedis jedis=new Jedis("192.168.126.129", 6379);
jedis.hset("user", "id", "100");
jedis.hset("user", "name", "tomcat");
System.out.println(jedis.hget("user", "id"));
System.out.println(jedis.hget("user", "name"));
if(jedis.hexists("user", "id")&&jedis.hexists("user", "name")){System.out.println("存在");
}else {System.out.println("不存在");
}
System.out.println(jedis.hgetAll("user"));
System.out.println(jedis.hkeys("user"));
jedis.hdel("user", "id","name");
System.out.println(jedis.hgetAll("user"));
}
@Test
public void testlist(){Jedis jedis=new Jedis("192.168.126.129", 6379);
jedis.lpush("list2", "1,2,3,4,5");
System.out.println(jedis.rpop("list2"));
}
/**
* 管制 redis 事务
* 阐明: 操作单台 redis 实用于事务管理, 然而如果多台 redis 则不太实用事务
*/
@Test
public void testTx() {Jedis jedis = new Jedis("192.168.126.129", 6379);
// 开启事务
Transaction transaction = jedis.multi();
try {transaction.set("bb", "bb");
transaction.exec();// 提交事务}catch (Exception e){transaction.discard();// 回滚事务
}
}
}
SpringBoot 整合 Redis
配置类地位
因为 redis 之后会被其余的服务器实用, 所以最好的形式将 Redis 的配置类保留到 common 包下
编辑 redis.properties 配置文件
编辑 JedisConfig 配置类
@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);
}
}
对象与 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);
System.out.println(itemDesc2.getCreated());
} catch (JsonProcessingException e) {e.printStackTrace();
}
}
JSON 转为对象
@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 简化代码的调用.
工具 API 中须要以下内容拍那个:
办法 1: 将任意的对象转化为 JSON.
办法 2: 将任意的 JSON 串转化为对象.
要求实现异样的解决.
编辑工具 API
在 common 包中增加工具 API 对象, 能够对立应用
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);
}
实现商品分类的缓存
业务阐明
步骤:
1. 查问缓存数据
2. 判断缓存中是否咱们所需数据
3. 如果没有数据, 则查询数据库
4. 如果有数据, 则间接返回数据
业务实现
@Autowired
private Jedis jedis;
/**
* 步骤:
* 先查问 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;
}
测试业务是否失常运行
正文完
发表至: springboot
2020-09-10