首先我想说的是redis是一个基于内存,可持久化,支持网络,key-value形式的缓存型的非关系型数据库,它由C语言编写。它的数据类型有:string、list、hash、set、zset,可用于的场景是:排行榜,分布式消息订阅,计数器,投票,会话,session.
redis的缺点:单线程命令慢,容易造成阻塞,线程上下文切换消耗资源。
redis的优点:采用io多路复用,它安装在磁盘,运行在内存。
那么接下来我想分享的是有关于:
从jedis到spring整合redis以及springboot整合redis以及它们之间的区别:
jedis:
首先引入依赖:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
接下来我们创建一个测试类,进行测试,并且开启redis客户端:
@Test
public void test() {
//构造函数里面的参数代表:主机名称,端口号
Jedis jedis=new Jedis("192.168.181.3",6379);
//这里是代表选择哪个数据库
jedis.select(6);
try {
jedis.flushDB();
//如果存在该键,则返回0,否则返回1,表示有存在该键,否则表示创建该键。
jedis.setnx("zhangsan","123123");
//System.out.println(jedis.incr("zhangsan"));
jedis.mset("name","zhangsan01","age","22");
System.out.println(jedis.mget("name","age"));
jedis.set("张三","123123");
System.out.println(jedis.get("张三"));
//System.out.println(jedis.keys("*"));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
jedis.close();
}
}
第二:引入jedis的池配置,再进行测试:
@Test
public void test1() {
GenericObjectPoolConfig poolConfig=new JedisPoolConfig();
poolConfig.setMaxTotal(100); //设置连接池的最大连接数量
poolConfig.setMaxIdle(100); //设置允许的最大等待廉价而
poolConfig.setMinIdle(10); //设置允许的最小等待连接
poolConfig.setTestOnBorrow(false); //借出连接是否校验连接的有效性(true,false)
poolConfig.setTestOnReturn(false); //归还连接是否校验连接的有效性
poolConfig.setTestOnCreate(false); //创建连接时是否校验连接的有效性
poolConfig.setBlockWhenExhausted(true); //当redis连接池无可用资源时,是否等待(true,false)
poolConfig.setMaxWaitMillis(1000);//设置最大等待超时时间
JedisPool pool=new JedisPool(poolConfig,"192.168.181.3",6379);
Jedis jedis=null;
try {
//通过jedis池对象获取jedis对象
jedis=pool.getResource();
jedis.flushDB();
jedis.set("hello","hello");
System.out.println(jedis.get("hello"));
} catch (Exception e) {
// TODO: handle exception
}finally {
if(jedis!=null) {
jedis.close();
}
}
}
2.接下来我们再看spring整合redis的流程:(主要是引入spring的依赖和redis的依赖)
依赖:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
2.我们还得进行redis连接池配置以及序列化的配置:因为我们保存中文到redis中,会出现乱码:
如下:另外还得说明一下:@RunWith和@ContextConfiguration搭配使用,引入spring配置文件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class TestRedis {
//注入RedisTemplate类,它用来进行数据的持久化
@Autowired
private RedisTemplate<String, Emp> redisTemplate;
@Test
public void test() {
/*
* redisTemplate.opsForValue().set("zhangsan","123123");
*
* System.out.println(redisTemplate.opsForValue().get("zhangsan"));
*/
Emp emp=new Emp("zhang","123456");
//可以持久化实体类,将一个实体作为键值进行持久化
redisTemplate.opsForValue().set("emp",emp);
Emp e=redisTemplate.opsForValue().get("emp");
System.out.println(e);
}
@Test
public void test1() {
/*
* redisTemplate.opsForHash().put("user:1:info","username","zhangsan");
* redisTemplate.opsForHash().put("user:1:info","password","123.com"); Object
* o1=redisTemplate.opsForHash().get("user:1:info","username"); Object
* o2=redisTemplate.opsForHash().get("user:1:info","password");
* System.out.println(o1); System.out.println(o2);
*/
/*
* Emp emp=new Emp(); emp.setUsername("张杰"); emp.setPassword("李四");
* redisTemplate.opsForHash().put("emp:2:info","emp",emp);
* System.out.println(redisTemplate.opsForHash().get("emp:2:info","emp"));
*/
Map maps=redisTemplate.opsForHash().entries("emp:3:info");
Iterator<Entry<String,Emp>> iterator=maps.entrySet().iterator();
while(iterator.hasNext()) { Entry<String,Emp> emp=iterator.next();
System.out.println(emp); }
/*
* List<Emp> emps=redisTemplate.opsForHash().values("emp:2:info");
* System.out.println(emps);
*/
}
}
以上操作都很简单,都有注解说明,这里我就不再说明,哪里有问题,大家可以指正
3.接下来就是springboot整合redis,这个就更简单了,因为它自定义的依赖以及帮我
们封装了一些配置,所以用起来更简单方便。
引入依赖:一个spring的缓存,还有springboot的start的redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
1.在主启动类上启动springCache缓存:
@SpringBootApplication
@EnableCaching//开启springCache缓存
public class SpringbootRedisApplication {
2.在yaml文件中配置redis连接池的属性:
spring:
redis:
host: 192.168.181.3
port: 6379
database: 0
timeout: 0
jedis:
pool:
max-idle: 8
min-idle: 0
max-active: 8
max-wait: -1
3.创建实体,和dao,service进行测试,dao层是直接从mysql数据库中取得的值,
我这儿就没写,直接模拟了从数据库中查数据的操作.
service层的操作:一般也是在service做缓存,下面代码也有解释:
@Service
public class EmpServiceImpl implements EmpService {
//key中的#empno代表实体类中的属性字段。
@Override
@Cacheable(value="emp",key="#empno",condition="#empno !=1003")
public Emp findEmpById(Integer empno) throws Exception {
System.out.println("进入了service方法查询了Emp对象:"+empno);
//模拟从数据库查询出来的一个对象
Emp emp=new Emp(1005,"张三","123123");
return emp;
}
//查询全部的员工信息
@Override
@Cacheable(value="emp:emps")
public List<Emp> findAllEmp() throws Exception {
List<Emp> emps=new ArrayList<>();
for(int i=0;i<5;i++) {
Emp emp=new Emp(1001+i,"username"+i,"password"+i);
emps.add(emp);
}
return emps;
}
//添加员工
@Override
@CachePut(value="emp",key="#emp.id")
public Emp create(Emp emp) throws Exception {
System.out.println("正在创建员工,员工编号为:"+emp.getId());
//数据库进行添加
return emp;
}
@Override
@CachePut(value="emp",key="#emp.id")
public Emp update(Emp emp) throws Exception {
System.out.println("正在修改员工信息,员工的编号:"+emp.getId());
//数据库进行修改
return emp;
}
@Override
@CacheEvict(value="emp",key="#empno")
public void delEmp(Integer empno) throws Exception {
System.out.println("删除编号为:"+empno+"的员工");
//直接自己进行数据库的删除操作
}
1.然后我们进行测试:模拟进行查询缓存
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringredisBootApplicationTests {
@Autowired
private EmpService empService;
@Autowired
private RedisTemplate<String, ?> template;
@Test
public void test() {
Emp emp = empService.findById(1005);
System.out.println(emp);
}
@Test
@Ignore
public void test1() {
List<Emp> list = empService.findEmpAll();
System.out.println(list);
}
//redis的list集合的进行的查询,
@Test
@Ignore
public void test2() {
List<Object> range = (List<Object>) template.opsForList().range("emp:list::SimpleKey []", 0, -1);
System.out.println(range);
}
综上,我们的从jedis到springredis到springbootredis的整合过程,以及区别,在上面以及展示的很清楚了,如果觉得有啥问题,欢迎大家指正。下篇分享关于forkjoin框架的工作原理,希望大家能够在我的分享中有一丝收获。