day11-【Redis】
学习目标
1.能够理解nosql的概念
2.能够说出redis的常用数据类型
3.能够使用redis的string操作命令
4.能够使用redis的hash操作命令
5.能够使用redis的list操作命令
6.能够使用redis的set操作命令
7.能够说出redis的两种持久化机制
8.能够使用jedis对redis进行操作
关系型数据库和非关系型数据库的区别
学习三个数据库:MySql Redis Oracle
(1)什么是NOSQL
NoSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库。
NOSQL是非关系型数据库
MySql Oracle :关系型数据库
Redis: 就是NOSQL 非关系型数据库
关系型数据库和非关系型数据库的区别:
(1) 关系型数据库特点(Mysql Oracle SqlServer)
》 1:数据是由一张张的表组成,而且这些表与表之间有关系(一对一,一对多,多对多)
》 2:数据是存在硬盘上,每次访问时,是将数据从硬盘读取到内存中
(2)非关系型数据库(NOSQL)特点 (Redis )
》1: 数据是有一个个的键值对:键 值 键 值
》2:数据是存在内存中,在满足需要的时候,也可以将数据存在硬盘上(Redis的持久化)
**为什么需要NOSQL?
**
(1) 所有的关系型数据库,都有三高问题
》》1 高并发
1秒内访问量
》》2 高效率
读写速度
》》3 高扩展
不能随意修改表
NOSQL数据库(Redis)可以全部解决三高问题
(2)案例:12306
Redis的介绍***
(1)什么是Redis?
Redis(Remote Dictionary Server ) 远程字典服务,是一个非关系型数据库,非关系型数据库被称为NOSQL数据库
(2)Redis有什么用?
有了redis是否可以不使用Mysql,Oralce?
不是
Redis一般用来存储经常访问的,但有不经常改变的数据
Redis特点
(1)Redis有什么特点?
》》1 使用C语言开发 指针 内存地址 new Object()
c语言速度比Java快
(2)Redis有什么哪些应用场景?
》》1 缓存 处理一些临时数据
》》2 聊天室的在线好友列表
》》3 网站访问统计
Redis软件下载
(1)Linux版的Redis(Linux做服务器稳定些)
官方提倡使用Linux版的Redis,所以官网值提供了Linux版的Redis下载
(2)我们可以从GitHub上下载window版的
Redis,具体链接地址如下:
官网下载地址:http://redis.io/download
github下载地址:https://github.com/MSOpenTech/redis/tags
Redis软件目录
(1)redis的目录结构
redis.windows.conf 配置文件
redis-server.exe 服务器执行程序
redis-cli.exe 客户端执行程序
startup.bat 服务器启动脚本(用该脚本启动服务器)
(2)Redis端口是: 6379
Tomcat端口是:8080
MySql端口是: 3306
(3)window版Redis的启动与关闭
启动:运行startup.bat
关闭:关闭窗口
Redis数据类型
(1)Redis与Map类比
Redis是以键和值的形式存储数据 Redis可以理解成Map集合
1:键:都是字符串
2:值:有五种数据类型 字符串 json串
字符串(String)!!! 键----值 Map<String,String>
哈希(hash) 大键—小键–值 Map<String,Map<String,String>>
字符串列表(list) 键----值1,值2,值3 Map<String,LinkedList>
(LinkedList值可以重复)
字符串集合(set) 键----值1,值2,值3 Map<String,HashSet>
(HashSet值不可以重复)
有序字符串集合(sorted set) 键----值1,值2,值3 Map<String,LinkedHashSet>
(2)为什么只需要掌握值为字符串类型就够了?
其他四种集合可以转成json字符串,不需要掌握
Redis的指令-字符串类型***
1)字符串类型string(重点)
set name baoqiang //添加一个键值对 如果键存在,则修改 set()
get name //根据键获取值
del name //根据键删除键值对
mget name age //根据多个键查看值
Redis的指令-Hash类型
(1)哈希(hash)
hset myhash username haohao //添加数据
hset 北京 111 冰冰
hget myhash username //根据大键和小键获取值
hdel myhash username //根据大键和小键删除值,删除后键也不存在了
Redis的指令-列表类型List
(1)列表类型list
这里的值可以重复
栈:先进后出
lpush mylist a b c //压栈 添加数据,键为mylist 值为:a b c
lpop mylist //从左边弹栈 删除操作,删除的顺序和添加的顺序相反
rpop mylist //从右边弹栈
Redis的指令-集合类型set
(1)集合类型set
这里的值不能重复,存入数据无序
sadd myset a b c //添加数据
smembers myset //获取数据
srem myset a b //删除数据
Redis的指令-通用指令***
(1)Redis通用指令
所有的数据类型都可以使用的指令
keys * //查看Redis中所有的键
del myset //删除指定的键值对
exists key //判断键是否存在 0表示不存在, 1表示存在
type myset //测试你的键是什么类型
REdis持久化-RDB
(1)Redis持久化
就是将Redis的数据从内存中保存到硬盘(磁盘)上
持久化之后,会在解压后的文件夹中生成一个dump.rdb文件,该文件中就保存你内存中的数据
1)RDB持久化是什么(重点)
指定频率将Redis数据持久化
Redis默认就支持该方式,你什么都不用做,Redis会自动的将内存的数据存储到硬盘中
save 900 1 //900秒以内 ,如果至少有一个键的值发生变化, 则Redis自动持久化
save 300 10 //300秒以内 ,如果至少有10个键的值发生变化, 则Redis自动持久化
save 60 10000 //60秒以内 ,如果至少有10000个键的值发生变化, 则Redis自动持久化
频率可以自己设置
REdis持久化-AOF
(1)AOF持久化(了解)
》》什么是AOF
每次操作立即持久化
该机制可以带来更高的数据安全性,即数据持久性
数据多时速度慢
》》 Redis默认不支持该方式
1)所以我们需要修改配置文件,让Redis支持
2)修改配置文件:
392: appendonly no 将no改为yes
3)重启服务器
不能直接双击: redis-server.exe 而是打开startup.bat脚本文件(手动指定配置文件)
4) Redis会在解压后的文件夹中自动生成一个文件:appendonly.aof文件
5)默认情况下,AOF是一秒钟持久化一次
appendfsync everysec
Jedis介绍
(1)什么是Jedis?
操作Redis的工具类:Jedis
》》Redis:数据库的名字
》》Jedis:工具类的名字
Jedis同样也是托管在github上,地址: https://github.com/xetorthio/jedis。
(2)如何搭建Jedis?
使用Jedis操作redis需要导入jar包如下
Jedis的操作
(1)Jedis如何使用?
操作步骤:
》》1:创建一个Jedis对象
》》 2:执行Redis指令
public void test1(){
//1:创建一个Jedis对象
Jedis jedis = new Jedis("localhost", 6379);//创建一个连接,参1 ip 参2 端口
//2:执行Redis指令
//写
jedis.set("name1","jack1");//添加 string-string
jedis.sadd("set1","hello","word","jedis","jedis");//添加string-set
//读
System.out.println(jedis.get("name1"));
jedis.close();
}
Jdbc连接池原理
(1)什么时候接触连接池?
Jdbc连接池
(2)连接池原理
频繁创建与销毁链接比较消耗性能
创建集合初始化多个Connection
需要时调getConnection()申请
使用完时调用close()放回(放回连接池,而不是销毁)
(3)连接池的意义
重用连接,提高性能
Jedis连接池基本实现1
(1)Jedis连接池原理
基本类似
(2)代码实现步骤
1:创建连接池的配置对象
2:创建连接池
3:从连接池中获取一个连接
4:执行Redis执行 Map<String,String> set get
5:释放连接
@Test
public void test02(){
// 1:创建连接池的配置对象
JedisPoolConfig config = new JedisPoolConfig();
//设置最大链接数
config.setMaxTotal(20);
//设置空闲连接数
config.setMaxIdle(10);
// 2:创建连接池
JedisPool pool = new JedisPool(config, "localhost", 6379);
// 3:从连接池中获取一个连接
Jedis jedis = pool.getResource();//获取一个连接
// 4:执行Redis执行 Map<String,String> set get
jedis.set("name2","pool2");
String value = jedis.get("name2");
System.out.println(value);
// 5:释放连接
jedis.close();
}
Jedis连接池基本实现2-Jedis连接池实现优化
(1)硬编码
配置参数写在java代码,编译成class,将来必须修改java代码才能改配置
项目中,使用配置文件来配置参数
(2)改成工具类加配置文件
@Test
public void test03(){
//1:从连接池获取连接
Jedis jedis = JedisUtils.getRedis();
//2: 进行读写操作
jedis.set("name3","jack3");
String value = jedis.get("name3");
System.out.println(value);
//3: 关闭连接
JedisUtils.close(jedis);
}
package comm.rh.pack01;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class JedisUtils {
private static JedisPool pool;
static {//静态代码在项目中,如果被使用只会加载一次
InputStream inputStream= JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
Properties properties = new Properties();
try {
properties.load(inputStream);//将流中的数据读成map
} catch (IOException e) {
e.printStackTrace();
}
// 1:创建连接池的配置对象
JedisPoolConfig config = new JedisPoolConfig();
//设置最大链接数
config.setMaxTotal(Integer.parseInt(properties.getProperty("maxTotal")));
//设置空闲连接数 "3"
config.setMaxIdle(Integer.parseInt(properties.getProperty("maxIdle")));
//2:创建连接池
pool = new JedisPool(config, properties.getProperty("url"), Integer.parseInt(properties.getProperty("port")));
}
public static Jedis getRedis() {
// 3:从连接池中获取一个连接
Jedis jedis = pool.getResource();//获取一个连接
return jedis;
}
public static void close(Jedis jedis) {
if(jedis!=null){
jedis.close();
}
}
}
在整个项目中,建立一个,properties文件,不是java文件,以后就可以改
,properties文件里面放变量,通常放键值对
maxTotal=30
maxIdle=10
url=localhost
port=6379
Properties properties = new Properties();
try {
properties.load(inputStream);//将流中的数据读成map
专门读取.properties文件的工具,读成一个map,一定要是.properties文件,因为有专门的工具类去读取数据
.properties文件配置参数,然后再有程序读进这些配置参数给对象使用,以后可以直接修改这个文件,而不是修改代码,这是JAVAEE经常采用的方式
一个类中,成员变量可以被所有变量访问
工具类另一种设计:
src\com.wzx.pack01_redis\Demo3JedisPool.java
public class Demo3JedisPool {
@Test
public void test01() {
Jedis jedis = JedisUtils.getJedis();
jedis.set("xxx", "yyyyy");
jedis.close();
}
}
src\jedis.properties
maxTotal=30
maxIdle=10
url=localhost
port=6379
src\com.wzx.pack01_redis\JedisUtils.java
public class JedisUtils {
private static JedisPool pool = null;
//1:创建一个连接池
static{
//1.1 解析properties文件
ResourceBundle bundle = ResourceBundle.getBundle("jedis");
//获取参数
String maxTotal = bundle.getString("maxTotal");
String maxIdle = bundle.getString("maxIdle");
String url = bundle.getString("url");
String port = bundle.getString("port");
//1.2创建连接池
//1:创建连接池的配置对象
JedisPoolConfig config = new JedisPoolConfig();
//1.1 设置最大连接数
config.setMaxTotal(Integer.parseInt(maxTotal));
//1.2 设置空闲连接数
config.setMaxIdle(Integer.parseInt(maxIdle));
//2:创建连接池
pool = new JedisPool(config, url, Integer.parseInt(port));
}
//2:对外提供一个获取连接的方法
public static Jedis getJedis(){
return pool.getResource();
}
//3:提供释放资源的方法
public static void close(Jedis jedis){
if(jedis != null) {
jedis.close();
}
}
}
读.properties文件可以先使用类加载器去加载成流,再使用Properties类来读。也可以使用 ResourceBundle