基本概念
简介
redis是一款高性能的NOSQL(Not Only SQL)系列的非关系型数据库
非关系型数据库(NOSQL)有:redis、hbase…
特点:
- 数据之间没有关联关系
- 数据存储在内存中
优点:
对于服务器,如果经常查询一些不太经常发生变化的数据,操作关系型数据库非常耗时,这时使用缓存思想解决这个问题。
开辟一个内存区域,把缓存放在内存区域中。
- 从缓存中获取数据
- 有数据:直接返回
- 没有数据:
- 从数据库查询
- 将数据库放入缓存
- 返回数据
一般使用redis做缓存
- nosql数据库将数据存储与缓存中,关系型数据库将数据存储在硬盘中
- nosql的存储结构:key,value形式、文档形式、图片形式等等
- 关系型数据库与NoSQL数据库并非对立而是互补的关系,即通常情况下使用关系型数据库,在适合使用NoSQL的时候使用NoSQL数据库
Redis支持的键值数据类型如下:
- 字符串类型 string
- 哈希类型 hash
- 列表类型 list
- 集合类型 set
- 有序集合类型 sortedset
redis的应用场景:
- 缓存(数据查询、短连接、新闻内容、商品内容等等)
- 聊天室的在线好友列表
- 任务队列。(秒杀、抢购、12306等等)
- 应用排行榜
- 网站访问统计
- 数据过期处理(可以精确到毫秒)
- 分布式集群架构中的session分离
redis主要文件:
- redis.windows.conf:配置文件
- redis-cli.exe:redis的客户端
- redis-server.exe:redis服务器端
命令操作
redis的数据结构
redis存储的是:key,value格式的数据,其中key都是字符串,value有五种不同的数据结构
- 字符串类型 string
- 哈希类型 hash:map格式
- 列表类型 list:linkedlist格式
- 集合类型 set
- 有序集合类型 sortedset
字符串类型 string
存储:set key value
获取:get key
删除:del key
哈希类型 hash
存储:hset key field value
获取:hget key field
获取指定field的全部:hgetall key field
获取全部:hgetall key
删除:hdel key field
hset myhash username lisi
hset myhash password 123
hget myhash username
hget myhash password
hgetall myhash
hdel myhash username
列表类型 list
可以添加一个元素到列表的头部(左边)或者尾部(右边)
将元素添加到列表左边:lpush key value
将元素添加到列表右边:rpush key value
范围获取:lrange key start end
- 获取所有:lrange key 0 -1
删除最左边的元素并返回:lpop key
删除最右边的元素并返回:rpop key
lpush mylist a
lpush mylist b
rpush mylist c
lrange mylist 0 -1
lpop mylist
集合类型 set
不允许重复元素
存储:sadd key value
获取set集合中所有元素:smembers key
删除set集合中的某个元素:srem key value
sadd myset a
smembers myset
-- 添加多个
sadd myset a b c
srem myset a
有序集合 sortedset
不允许重复元素,且元素有序
为每个value添加一个score(double),利用score排序
存储:zadd key score value
获取:zrange key start end
删除:zrem key value
zadd mysort 60 zhangsan
zadd mysort 50 lisi
zrange mysort 0 -1
-- 带着分数
zrange mysort 0 -1 withscore
zrem mysort lisi
通用命令
查询所有的键:**keys **
获取键对应的value类型:type key
删除指定的key value:del key
持久化
redis是一个内存数据库,当redis服务器重启,或者电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
redis持久化机制:
-
RDB:默认方式,不需要进行配置,默认就使用这种机制
-
在一定的间隔时间中,检测key的变化情况,然后持久化数据
-
编辑redis.windwos.conf文件
-
# after 900 sec (15 min) if at least 1 key changed save 900 1 # after 300 sec (5 min) if at least 10 keys changed save 300 10 # after 60 sec if at least 10000 keys changed save 60 10000
-
重新启动redis服务器,并指定配置文件名称
-
D:\redis-2.8.9>redis-server.exe redis.windows.conf
-
-
AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据
-
编辑redis.windwos.conf文件
-
appendonly no(关闭aof) --> appendonly yes (开启aof)
-
# appendfsync always : 每一次操作都进行持久化 appendfsync everysec : 每隔一秒进行一次持久化 # appendfsync no : 不进行持久化
-
Java客户端 Jedis
Jedis:一款Java操作redis数据库的工具
使用:
- 下载jedis的jar包
public class JedisTest {
@Test
public void test() {
//1. 获取连接
Jedis jedis = new Jedis("localhost", 6379);
//Jedis jedis = new Jedis();
//如果使用空参构造,默认值"localhost",6379端口
//2. 操作
jedis.set("username", "zhangsan");
//3. 释放资源
jedis.close();
}
}
Jedis操作字符串类型
//存储
jedis.set("username","zhangsan");
//获取
String username = jedis.get("username");
System.out.println(username);
//可以使用setex()方法存储可以指定过期时间的 key value
jedis.setex("activecode",20,"hehe"); //将activecode:hehe键值对存入redis,并且20秒后自动删除该键值对
Jedis操作哈希类型
// 存储hash
jedis.hset("user", "name", "lisi");
jedis.hset("user", "age", "23");
jedis.hset("user", "gender", "female");
// 获取hash
String name = jedis.hget("user", "name");
System.out.println(name);
// 获取hash的所有map中的数据
Map<String, String> user = jedis.hgetAll("user");
// keyset
Set<String> keySet = user.keySet();
for (String key : keySet) {
//获取value
String value = user.get(key);
System.out.println(key + ":" + value);
}
Jedis操作列表类型
// list 存储
jedis.lpush("mylist", "a", "b", "c");//从左边存
jedis.rpush("mylist", "a", "b", "c");//从右边存
// list 范围获取
List<String> mylist = jedis.lrange("mylist", 0, -1);
System.out.println(mylist);
// list 弹出
String element1 = jedis.lpop("mylist");//c
System.out.println(element1);
String element2 = jedis.rpop("mylist");//c
System.out.println(element2);
// list 范围获取
List<String> mylist2 = jedis.lrange("mylist", 0, -1);
System.out.println(mylist2);
Jedis操作集合类型
// set 存储
jedis.sadd("myset","java","php","c++");
// set 获取
Set<String> myset = jedis.smembers("myset");
System.out.println(myset);
Jedis操作有序集合类型
// sortedset 存储
jedis.zadd("mysortedset",3,"亚瑟");
jedis.zadd("mysortedset",30,"后裔");
jedis.zadd("mysortedset",55,"孙悟空");
// sortedset 获取
Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1);
System.out.println(mysortedset);
Jedis连接池:JedisPool
使用:
- 创建JedisPool连接池对象
- 调用方法:getResource(),获取连接
@Test
public void test2() {
//创建一个配置对象
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(50);
config.setMaxIdle(10);
// 创建连接池对象
JedisPool jedisPool = new JedisPool(config);
//获取连接
Jedis jedis = jedisPool.getResource();
jedis.set("1", "nihao");
//关闭,归还到连接池中
jedis.close();
}
JedisPool工具类:JedisPoolUtils
作用:加载配置文件,配置连接池的参数;提供获取连接的方法
public class JedisPoolUtils {
private static JedisPool jedisPool;
//加载配置文件
static {
//读取配置文件
InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
//创建Properties对象
Properties properties = new Properties();
//关联文件
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//获取数据,设置到JedisPoolConfig中
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(properties.getProperty("maxTotal")));
config.setMaxIdle(Integer.parseInt(properties.getProperty("maxIdle")));
//初始化JedisPool
jedisPool = new JedisPool(config, properties.getProperty("host"), Integer.parseInt(properties.getProperty("port")));
}
/**
* 获取连接方法
*/
public static Jedis getJedis() {
return jedisPool.getResource();
}
}
配置文件
host=localhost
port=6379
maxTotal=50
maxIdle=10
测试类
@Test
public void test3() {
//通过连接池工具类获取
Jedis jedis = JedisPoolUtils.getJedis();
jedis.set("hello", "world");
//关闭,归还到连接池中
jedis.close();
}
案例:加载省份
需求
- 提供index.html页面,页面中有一个省份 下拉列表
- 当页面加载完成后 发送ajax请求,加载所有省份
这里不使用关系型数据库进行查询显示,使用redis缓存。
注意:使用redis缓存一些不经常发生变化的数据。
原因:数据库的数据一旦发生改变,则需要更新缓存。(数据库的表执行增删改的相关操作,需要将redis缓存数据情况,再次存入)
更新缓存:在service对应的增删改方法中,将redis数据删除。