typora基础用法
- 有序列表:数字 + .
- 无序列表:- +
- ctrl + 1 ~6 标题1~6
- **加粗:**ctrl + B
- ctrl + T 表格
- 插入图片:ctrl + shift + i
- ```+回车 代码块
- 插入连接:ctrl + k
- 表情为:单词:😄
int i = 0;
String name = "张杰";
system.out.println("这是一个语法");
1 | 1 |
---|---|
2 | 2 |
3 | 4 |
5 | 6 |
– 年龄小于30
例子:
-- 根据性别分组
select count(*) from group
注意事项
- 执行顺序: where > 聚合函数 > having
表情大全
-
😄:smile
-
😘:kissing_heart
-
😰:cold_sweat
-
😡:tage
-
❓:question
-
😊:blush
-
😳 :flushed
-
😇:innocent
-
😕:confused
-
😞:disappointed
-
😭:sob
-
😂:joy
-
❤️:heart
-
🔥:fire
redis基础篇
初识redis
基本介绍:
redis是一个Nosql非关系型数据库😄
SQL | Nosql | |
---|---|---|
数据结构 | 结构化 | 非结构化 |
数据关联 | 关联的(例如多表关联) | 非关联(例如json格式) |
查询方式 | SQL查询 | 非SQL |
事务特性 | ACID | BASE |
存储方法 | 磁盘 | 内存(速度更快) |
扩展性 | 垂直 | 水平 |
使用场景 | 1. 数据结构固定 2.相关业务对数据安全性 | 数据结构不固定 |
redis特征:😸
- 键值型,value支持多种不同的数据结构,如json
- 单线程,每一个命令具备原子性
- 低延迟,速度快(基于内存、io多路)
- 支持数据持久化
- 支持主从集群,分片集群
- 支持多语言客户端
安装redis
安装说明
大多数企业都是基于Linux服务器来部署项目,而且Redis官方也没有提供Windows版本的安装包。因此课程中我们会基于Linux系统来安装Redis.
此处选择的Linux版本为CentOS 7.
Redis的官方网站地址:https://redis.io/
单机安装redis
1.1安装redis依赖
redis是redis是基于C语言编写的,需要加入gcc
yum install -y gcc tcl
1.2上传安装包并解压
tar -xzf redis-6.2.6.tar.gz
# 加入文件夹之后运行编译命令即安装成功
make && make install
1.3修改redis的一些配置
**注意:**在 /usr/local/src/redis-6.2.6 里面的redis.conf里面修改配置,
修改之前最后备份一下 cp redis.conf redis.conf.bck
# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes
# 密码,设置后访问Redis必须输入密码
requirepass 123321
# 其他配置
# 监听的端口
port 6379
# 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志、持久化等文件会保存在这个目录
dir .
# 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
databases 1
# 设置redis能够使用的最大内存
maxmemory 512mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名
logfile "redis.log"
1.4redis的常用命令
# 启动
redis-server redis.conf
# 停止
redis-cli -u ianzhangjie shutdown
# 查看是否启动redis
ps -ef | grep redis
# 杀死进程
kill -9 进程号
1.5 实现开机自启
我们也可以通过配置来实现开机自启。
首先,新建一个系统服务文件:
vi /etc/systemd/system/redis.service
内容如下:
[Unit]
Description=redis-server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
然后重载系统服务:
systemctl daemon-reload
现在,我们就可以通过指令来管理redis😄
# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis
# 实现开机自启
systemctl enable redis
redis客户端
三种方式操作redis
- 命令行客户端
- 图形化桌面客户端
- 编程客户端
1.命令行客户端
使用方式:
# 启动
redis-cli -h 127.0.0.1 -p 6379 -a ianzhangjie
# 设置和获取值
set name zhangjie get name
# 选择一号库
select 1
**测试:**使用 ping 尝试是否成功
2.图形化客户端
这个仓库可以找到安装包:https://github.com/lework/RedisDesktopManager-Windows/releases
resp
redis命令
Redis是一个key-value的数据库,key一般为String,而value多种多样🔥
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B5m886HQ-1669080113786)(C:\Users\一片海。\AppData\Roaming\Typora\typora-user-images\image-20221119213626431.png)]
1.通用命令
命令 | 用法 |
---|---|
KEYS | 查看符合条件的所有的key |
DEL | 删除一个指定的key |
EXISTS | 判断key是否存在 |
expire | 给一个key设置有效期,到达有效期key会自动删除 |
TTL | 查看一个key的剩余有效期 |
2.String类型命令
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pQIvYEQu-1669080113787)(C:\Users\一片海。\AppData\Roaming\Typora\typora-user-images\image-20221119215707813.png)]
3.Key的层级结构
例如:
set hai:user:1 '{"id":1, "name":"jiejie", "price": 2999}'
4.Hash结构命令
4.1Hash结构与String结构区别:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DDCCsdYX-1669080113788)(C:\Users\一片海。\AppData\Roaming\Typora\typora-user-images\image-20221120101511355.png)]
4.2hash常用命令
例如: hset hai:user:3 name jiejie age 1
😓
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cvFDza8e-1669080113788)(C:\Users\一片海。\AppData\Roaming\Typora\typora-user-images\image-20221120102605097.png)]
5.List类型
注意:Redis中的List可以看做是一个双向链表,既支持正向检索也支持反向检索
特征:
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
常用来存储一个有序数据:例如:朋友圈点赞,评论列表⛵️
常用命令:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fNHOJQJH-1669080113789)(C:\Users\一片海。\AppData\Roaming\Typora\typora-user-images\image-20221120104742315.png)]
注意:
-
存和取在同一边: 栈
-
存和取在不同边: 队列
-
存和取在不同边并用B修饰: 堵塞队列
6.Set类型
**注意:**Redis中的Set与java中的HashSet类似,可以看做是value为空的HashSet,是一个Hash表
特征:
-
无序
-
元素不可重复
-
查找快
-
支持交集,并集,差集
常用命令:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jnZQDJ65-1669080113789)(C:\Users\一片海。\AppData\Roaming\Typora\typora-user-images\image-20221120110514716.png)]
7.SortedSet类型
**注意:**Redis的SortedSet是一个可排序的Set集合,与java中的TreeSet类似,SortedSet的每一个元素都带有一个score属性
特征:
- 可排序
- 元素不重复
- 查询速度快
常用与==排行榜==这样的功能
默认为升序,可以在Z后面加rev变为降序🌵
常用命令:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RKnKLGcT-1669080113789)(C:\Users\一片海。\AppData\Roaming\Typora\typora-user-images\image-20221120134911339.png)]
Redis的java客户端
三大主流客户端对比:
特点 | |
---|---|
Jedis | 常以Redis命令作为方法,学习成本低,但是jedis实例下线程不安全,多线程环境下需要基于连接池来使用 |
lettuce | lettuce是基于netty实现,支持同步、异步和响应式编程,并且线程安全,并且支持Redis的哨兵模式、集群模式和管道模式 |
Redission | 基于Redis实现的分布式,包含诸如map、Queue、Lock、Semaphore等诸多强大功能 |
jedis的基本使用
1.引入jedis依赖😇
<!--jedis依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.0</version>
</dependency>
<!--单元测试-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.7.0</version>
</dependency>
在测试中使用:
public class JedisTest {
private Jedis jedis;
@BeforeEach
void setUp() {
/*建立连接*/
jedis = new Jedis("192.168.23.129", 6379);
jedis.auth("ianzhangjie");
jedis.select(0);
}
@Test
void testString() {
String result = jedis.set("name", "小虎");
System.out.println("redis的值为:" + result);
String name = jedis.get("name");
System.out.println("name的值为:" + name);
}
@AfterEach
void tearDown() {
/*释放连接*/
if (jedis != null) {
jedis.close();
}
}
}
**注意:**爆空指针错误是因为Jedis jedis = new Jedis(“192.168.23.129”, 6379)前面多加了Jedis
Jedis连接池的使用
创建一个连接池
public class JedisConnectFactory {
private static final JedisPool jedispool;
static{
/*配置连接池*/
JedisPoolConfig poolconfig = new JedisPoolConfig();
poolconfig.setMaxTotal(8);
poolconfig.setMaxIdle(8);
poolconfig.setMinIdle(0);
poolconfig.setMaxWaitMillis(1000); //1000毫秒
jedispool = new JedisPool(poolconfig,"192.168.23.129", 6379);
}
public static Jedis getedis(){
return jedispool.getResource();
}
}
之后就可以直接使用了
SpringDataRedis的使用
基本介绍: 这是spring对redis的集成模块😘
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PCSIwyhZ-1669080113790)(C:\Users\一片海。\AppData\Roaming\Typora\typora-user-images\image-20221120171845700.png)]
1.api的介绍😃
API | 返回值类型 | 说明 |
---|---|---|
redisTemplate.opsForValue() | ValueOperation | String |
redisTemplate.opsForHash() | HashOperation | Hash |
redisTemplate.opsForList() | ListOperation | List |
redisTemplate.opsForSet() | SetOperation | Set |
redisTemplate.opsForZSet() | ZSetOperation | SortedSet |
redisTemplate | 通用命令 |
2.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 连接池依赖-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
3.编写redis配置信息
spring:
redis:
host: 192.168.23.129
port: 6379
password: ianzhangjie
4.注入RedisTemplate
@SpringBootTest
class RedisDemoApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
/*写入一条数据*/
redisTemplate.opsForValue().set("name","胡歌");
/*读取到一条数据*/
Object name = redisTemplate.opsForValue().get("name");
System.out.println("name=" + name);
}
}
**注意:**此时注入会发现出现序列化问题,所以需要设置连接工厂设置序列化工具
5:设置连接工厂
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisTemplate){
RedisTemplate<String, Object> template = new RedisTemplate<>();
//设置连接工厂
template.setConnectionFactory(redisTemplate);
//设置json序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//设置key序列化工具
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
//设置value序列化工具
template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer);
//返回
return template;
}
}
**注意:**此时可能发现报错是因为没有引入jackson😢
<!--jackson依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
6.好的,上一节经典白雪😭
不用自己设置连接工厂,此时可以使用spring提供的StringRedisTemplate
手动序列化:
@Autowired
private StringRedisTemplate redisTemplate;
/*springmvc提供的json序列化工具*/
private static final ObjectMapper mapper = new ObjectMapper();
@Test
void testSaveUser() throws JsonProcessingException {
User user = new User("小明", 22);
/*手动序列化*/
String json = mapper.writeValueAsString(user);
/*写入数据*/
redisTemplate.opsForValue().set("user:100",json);
/*获取数据*/
String s = redisTemplate.opsForValue().get("user:100");
/*手动反序列*/
User user1 = mapper.readValue(s, User.class);
System.out.println("user1=" + user1);
}
7.补充一下使用Hash格式
@Test
void testHash() {
redisTemplate.opsForHash().put("user:200","name","小红");
redisTemplate.opsForHash().put("user:200","age","11");
Map<Object, Object> entries = redisTemplate.opsForHash().entries("user:200");
System.out.println("entries=" + entries);
}
其他类型的也是差不多的
终于over了
2022.11.20 22.03
😊
redis实战篇
通过对黑马点评融合自己所学知识
==注意:==前端部署在nginx,后端在tomcat
前期工作
1.1导入后端项目
先导入hmdp数据库然后导入hm-dianping
注意: 这里导入工程发现pom的springboot版本报错
解决途径:文件–>缓存作废–>然后重启成功解决
1.2导入前端项目
项目位于F:\baidu\redis\nginx-1.18.0
注意: 访问http://localhost:8080/然后打开手机模式就可以看到项目启动
短信登录
基于Session实现登录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MwPcCRwG-1669080113790)(C:\Users\一片海。\AppData\Roaming\Typora\typora-user-images\image-20221121115232573.png)]
1.发送短信验证码
编写cotroller层接口🍶
@PostMapping("code")
public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {
// TODO 发送短信验证码并保存验证码
return userService.sendCode(phone, session);
}
然后编写service业务
@Override
public Result sendCode(String phone, HttpSession session) {
// 1.校验手机号
if (RegexUtils.isPhoneInvalid(phone)) {
return Result.fail("手机格式错误");
}
// 2.符合 生成验证码
String code = RandomUtil.randomNumbers(6);
// 3.保存验证码到session
session.setAttribute("code", code);
// 4.发送验证码
log.debug("发送验证码成功,验证码为: {}",code);
return Result.ok();
}
注意:这里的log.debug(“发送验证码成功,验证码为: {}”,code);报错是因为没有加入@Slf4j注解
2.实现短信验证码登录和注册功能
这里不需要判断登录凭证,是因为基于session,session基于cookie,访问我们tomcat的时候sessionid会自动的写入我们cookie,这个时候就带着sessionId就可以找到我们的User了😃
编写cotroller层接口🍶
@PostMapping("/login")
public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){
// TODO 实现登录功能
return userService.login(loginForm, session);
}
然后是service业务
@Override
public Result login(LoginFormDTO loginForm, HttpSession session) {
// 1.校验手机号
String phone = loginForm.getPhone();
if (RegexUtils.isPhoneInvalid(phone)) {
return Result.fail("手机格式错误");
}
// 2.校验验证码
String cacheCode = loginForm.getCode();
// 3.不一致,报错
if (cacheCode == null || !session.getAttribute("code").toString().equals(cacheCode)) {
return Result.fail("验证码错误");
}
// 4.一致 根据手机号查询用户
User user = query().eq("phone", phone).one();
// 5.判断用户是否存在,用户不存在,创建一个用户
if (user == null) {
user = createUserWithPhone(phone);
}
// 6.用户存在,直接保存到session
session.setAttribute("user",user);
return Result.ok();
}
//创建用户
private User createUserWithPhone(String phone) {
// 1创建用户
User user = new User();
user.setPhone(phone);
/*随机生成一个用户名*/
user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));
/*保存用户*/
save(user);
return user;
}
时间:2022.11.21 23:30
商户查询缓存
达人探店
优惠券秒杀
好友关注
附近的商户
6.用户存在,直接保存到session
session.setAttribute(“user”,user);
return Result.ok();
}
//创建用户
private User createUserWithPhone(String phone) {
// 1创建用户
User user = new User();
user.setPhone(phone);
/*随机生成一个用户名*/
user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));
/*保存用户*/
save(user);
return user;
}
时间:2022.11.21 23:30
## 商户查询缓存
## 达人探店
## 优惠券秒杀
## 好友关注
## 附近的商户