发表于: 2021-09-20 22:58:12
1 1169
一,今天完成的事情
任务六。
我直接写到redis。任务六的代码重头戏在于怎么用缓存。我先把Memcached放一放。Redis本身我希望说的比较多。
Redis市场常用。项目中开启Redis作为缓存,服务MySQL。还是如计划,windows中测试,云Linux上最终交任务展示。
1,感谢 Tomasz Poradowski ,把windows上能用的Redis更新到了5.0.10 。Redis自己是只有tar.gz的,至于tar.gz安装全家桶,这次也会做。
在地址 https://github.com/tporadowski/redis/releases 能够找到现在windows能用的最新release和历史releases。
还做了个我喜欢的msi。port就是传统的6379。安装目录加入PATH。
打开一个 cmd 窗口 使用cd命令切换目录到 C:\redis 运行 redis-server.exe redis.windows.conf 。
cd C:\Program Files\Redis
如果想方便的话,可以把 redis 的路径加到系统的环境变量里,这样就省得再输路径了,后面的那个 redis.windows.conf 可以省略,如果省略,会启用默认的。输入之后,会显示如下界面
2,在Redis启动的情况下,启动我的Intellij代码
我在数据库中有一条记录
访问cotroller一次后,
可以另外启动一个 cmd 窗口,原来的不要关闭,避免无法访问服务端。
切换到 redis 目录下运行: redis-cli.exe -h 127.0.0.1 -p 6379
采用redis desktop manager 这个可视化工具也可以查看redis情况。可以选地址,也直观
写入redis成功。
Springboot中使用的包是
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
使用的包和项目必须涉及的,import的包相关。名字也不乱取。删掉
.boot
删掉
spring-boot-starter-
就是import需要,所以加在pom里的dependency
3,我的含redis的原来的代码是Spring部分用的是Springboot。任务六的要求在于需要用JMeter压力测试。整合任务五的代码,尤其是service层。
原来我自动生成的代码就在entity上都加了序列化的impliments
implements Serializable {
private static final long serialVersionUID = 1L;
和json类似。序列化成对方接受的数据格式。反序列化成自己接受的数据格式。
可以给需要redis操作的加上拦截器。更直接的办法是主要在service层加入有关redis的操作,缓存也是数据库。我这个项目没有比较多的service,没办法抽离什么拦截和不拦截哪些的逻辑,所以直接在service加入操作。
因为原来的tiles_login是SSM(Spring+SpringMVC+MyBatis),我就做适用于SSM的一些改动,加入Redis。
需要加入dependency。也是有org-springframework-data-redis。
Spring Data Redis对Redis底层开发包(Jedis、Lettuce、JRedis、RJC)进行了高度封装。RedisTemplate封装提供了redis各种操作、异常处理及序列化,完全屏蔽里底层实现(使用者面向Spring Data编程即可,可完全不用关心底层到底使用的是Jedis or Lettuce)。
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.9.RELEASE</version>
</dependency>
用2或者以上版本的才能有以下包。不管是在Spring上、JDK上,还是MyBatis,版本意识对你做架构都非常的重要。
package org.springframework.data.redis.cache;
可以用Jedis作为Client操作Redis
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.3</version>
</dependency>
也可以用使用Lettuce作为Client操作Redis。也是我选用的。它有更多操作可以使用。
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
4,2个redis配置文件.properties
redis.properties 。注意password是空,目前没配置密码。只演示。一般配置密码。
hostName = 127.0.0.1
port = 6379
pool.maxIdle = 10000
pool.minIdle = 1000
pool.maxWaitMillis = 5000
pool.maxTotal = 2
spring-mybatis.xml 配置不止扫描service包,还扫描config包,通过config配置。用注解方式,所以有RedisConfig.java类配置。
5,希望提的还有ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue(); 这样来获取ValueOperations;。
redis有五种数据操作类型,所以还有4种。用的时候一定去看。
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作
ValueOperations是java spring系列操作redis的一个关键。get set,加减数额方法比较全面。
package org.springframework.data.redis.core;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public interface ValueOperations<K, V> {
void set(K var1, V var2);
void set(K var1, V var2, long var3, TimeUnit var5);
Boolean setIfAbsent(K var1, V var2);
void multiSet(Map<? extends K, ? extends V> var1);
Boolean multiSetIfAbsent(Map<? extends K, ? extends V> var1);
V get(Object var1);
V getAndSet(K var1, V var2);
List<V> multiGet(Collection<K> var1);
Long increment(K var1, long var2);
Double increment(K var1, double var2);
Integer append(K var1, String var2);
String get(K var1, long var2, long var4);
void set(K var1, V var2, long var3);
Long size(K var1);
RedisOperations<K, V> getOperations();
Boolean setBit(K var1, long var2, boolean var4);
Boolean getBit(K var1, long var2);
}
但是删除一般看到是用
redisTemplate.delete(keys);
配合set,才是增删改查完善。
如果做的比较仔细, redisTemplate是注入到ValueOperations<String, Object>中的。
没有写复杂的管理Redis,让Redis过期的逻辑
6,测试代码成功使用redis。ListOperations使用。
package com.nicole.tileslogin;
import com.nicole.tileslogin.config.RedisConfig;
import com.nicole.tileslogin.entity.ExcellentStudent;
import com.nicole.tileslogin.service.ExcellentStudentService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-mybatis.xml"})
public class RedisConfigTest {
@Autowired
private ExcellentStudentService excellentStudentService;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private ListOperations<String, Object> opsForList;
@Before
public void setUp() throws Exception{
opsForList = redisTemplate.opsForList();
}
@Test
@Transactional
@Rollback(true)
public void getExcStudentTest(){
//只看前4个记录
int offset = 0;
int limit = 4;
String key = "studentList";
List<ExcellentStudent> studentList = new ArrayList<>();
boolean hasKey = redisTemplate.hasKey(key);
if(hasKey){
List<Object> temp= opsForList.range(key,0,-1);
int size = temp.size();
for (int i = 0; i < size; i++) {
studentList.add((ExcellentStudent) temp.get(i));
}
System.out.println("从缓存中获取数据:"+ studentList.get(0).getName());
System.out.println("-----------------------------");
}else{
studentList =
excellentStudentService.queryAllByLimit( offset, limit);
System.out.println("查询数据库获取数据:"+studentList.get(0).getName());
opsForList.leftPushAll("studentList", studentList);
System.out.println("------------写入缓存---------------------");
}
}
}
第一次run,写入缓存
7,对jsp该加的东西要加,Post方法的字符集部分
<form action="${path}/login" method="post" enctype="multipart/form-data" accept-charset="UTF-8">
8,注意一般是用
StringRedisTemplate()
实现
RedisTemplate<String, String>
这2样不同。最终能用什么里面的方法,是一个很好的多态实例。
二,今天问题
Memcached融合java使用的各种方式,3年内的参考少很多。Redis相对好用。
三,今天的收获
Redis使用,真正帮助MySQL。总的来说,就是用NoSQL帮助关系型数据库。
redis和mecached很可能冲突,如果报错,两个都用过,注释掉不用的那个。
四,明天的计划
任务6
评论