驴のSpringBoot学习笔记(二)

部分笔记来自于黑马教育

1.NoSQL

1.1Redis数据库

Redis和MySQL一样,也是一种数据库类型,但和MySQL相比有着一些不同:

  1. MySQL是关系型数据库,而Redis是非关系型数据库(NoSQL)。
  2. MySQL用于持久化存储数据到硬盘,功能强大,但是速度缓慢;而Redis用于存储使用较为频繁的数据到缓存中,读取速度快。
  3. MySQL的数据存放在磁盘中;而Redis的数据存放在内存中。

下载地址:https://github.com/tporadowski/redis/releases (科学上网)

1.1.1Redis数据库简单使用

下载完成后文件目录:

在该目录下启动cmd,并输入 redis-cli.exe ,你会看到这玩意

这里先不要操作,先输入shutdown,再exit

执行完上述操作后,再输入 redis-server.exe redis.windows.conf,就可以运行我们的redis了

再重新打开 redis-cli.exe,尝试一次简单的存取

ok,现在你已经会了redis了👍

1.2Mongodb数据库

Mongodb是一个开源文档型数据库,是NoSQL数据库产品的一种,是最像关系型数据库的非关系型数据库

特点:

临时性存储相结合,且修改频率高(类似于游戏道具,直播间在线人数),应用场景数据变化较快

2.SpringBoot整合Redis

2.1创建整合Redis的新项目

屏幕截图 2023-05-09 222955

2.2简单编写一个测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@SpringBootTest
class SpringbootRedisDemoApplicationTests {

//这是redis的操作接口对象
@Autowired
RedisTemplate redisTemplate;//这个玩意儿是面向对象的,但我们在本地cmd执行的是面向字符串,
//StringRedisTemplate redisTemplate;这玩意就是面向字符串的
//这样就可以保证我们idea和cmd操作一致了

@Test
void set() {
ValueOperations ops = redisTemplate.opsForValue();
ops.set("name","hello world!");

}

@Test
void get() {
ValueOperations ops = redisTemplate.opsForValue();
Object name = ops.get("name");
System.out.println(name);
}

}

执行结果:

屏幕截图 2023-05-09 225708

成功get到了

3.常用第三方技术整合

3.1关于缓存

屏幕截图 2023-05-10 174952

3.2使用缓存

1.导入缓存依赖

1
2
3
4
5
<!--        缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2.启用缓存

1
2
3
4
5
6
7
8
9
@SpringBootApplication
@EnableCaching//加入这个注解,启用缓存
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}

}

3.使用缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* @Description: 在需要缓存的方法上加入注解,将方法得到的数据存入缓存
* @Params:
* value = "cacheSpace" cacheSpace给缓存空间起个名
* key = "All" All给缓存的数据起名,方便取(唯一)
* 另外例如以id取数据,就需要以id命名,方便,这种key就可以这样写key=“#id”
* @Return
*/
@Override
@Cacheable(value = "cacheSpace",key = "All")
public List<User> getAll() {
return userDao.getAll();
}

3.3关于缓存的实例:手机验证码模拟

关于在pom里整合cache,还有启动类的注解在上面讲过了,这里就省略

包装类:

1
2
3
4
5
6
7
8
9
10
11
/**
* @Author 林峰
* @Date
* @Version 1.0
*/
@Data
public class SMSCode {

private String tele;//电话
private String code;//验证码
}

service接口

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* @Author 林峰
* @Date
* @Version 1.0
*/
public interface SMSCodeService {

//接受手机号,生成验证码,底层再以手机号为key缓存验证码
public String sendCodeToSMS(String tele);
//检查输入验证码和缓存里的验证码是否一致
public boolean checkCode(SMSCode smsCode);

}

接口实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* @Author 林峰
* @Date
* @Version 1.0
*/
@Service
public class SMSCodeServviceImpl implements SMSCodeService {

@Autowired
private CodeUtil codeUtil;

@Override
//电话号码作为key存储缓存
//CachePut只管向缓存里放,如果缓存里有key相同的,则会覆盖
//@Cacheable 如果缓存里有,就不会更新了
@CachePut(value = "smsCode",key = "#tele")
public String sendCodeToSMS(String tele) {
//调用工具类,生成验证码
String generator = codeUtil.generator(tele);
return generator;
}

@Override
public boolean checkCode(SMSCode smsCode) {
String tele = smsCode.getTele();
//调用工具类,获取缓存里的验证码
String code = codeUtil.get(tele);
//比较
return smsCode.getCode().equals(code);
}
}

工具类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* @Author 林峰
* @Date
* @Version 1.0
*/
@Component
public class CodeUtil {

private String[] patch = {"000000", "00000", "0000", "000", "00", "0", ""};

//该方法用来随机生成验证码,不多做解释
public String generator(String tele) {
int code = tele.hashCode();
int encryption = 2023510;

long result = code ^ encryption;
long now = System.currentTimeMillis();

result = result ^ now;
long pwcode = result % 1000000;
//负变正
pwcode = pwcode < 0 ? -pwcode : pwcode;
//验证码补齐
String codestr = pwcode + "";
int length = codestr.length();

return patch[length] + codestr;
}
//该方法用来根据key获取缓存里的验证码
@Cacheable(value = "smsCode",key = "#tele")
public String get(String tele){
return null;
}



}

control类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* @Author 林峰
* @Date
* @Version 1.0
*/
@RestController
@RequestMapping("/sms")
public class SMSCodeController {

@Autowired
private SMSCodeService smsCodeService;


@GetMapping
public String getCode(String tel){

String code = smsCodeService.sendCodeToSMS(tel);
return code;
}
@PostMapping
public boolean checkCode(SMSCode smsCode){
return smsCodeService.checkCode(smsCode);
}
}

结果实现:

启动咱们的apifox,嘿,发送个get请求,嘿:

嘿,咱再发送个post请求,验证验证我们的手机号和验证码

屏幕截图 2023-05-10 220322

true了😆

4.Quartz触发器

Quartz是一个触发器框架,主要功能就是配置程序的一个触发器,比如(零点秒杀,就需要一个在零点自动启动的程序)

屏幕截图 2023-05-10 225648

步骤:

1.在pom里整合Quartz

1
2
3
4
5
<!--Quartz定时触发器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

2.创建quartz类,注意,该类必须继承 QuartzJobBean才能生效(乌龟的屁股——龟腚)

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* @Author 林峰
* @Date
* @Version 1.0
*/
public class MyQuartz extends QuartzJobBean {
//继承之后重写其中的抽象方法
//该方法就定义了你的工作,上图第一步
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println("quartz is running...");
}
}

3.创建配置类来配置工作明细,触发器

这里面门道有点多,建议各位自己找资料深入了解了解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* @Author 林峰
* @Date
* @Version 1.0
*/
@Configuration
public class QuartzConfig {

@Bean
public JobDetail jobDetail() {
//工作明细,绑定具体工作
//创建该类对应的具体工作
return JobBuilder.newJob(MyQuartz.class).storeDurably().build();
//.storeDurably是用来持久化处理的,因为如果你用不到,java会把他当垃圾处理了,记得加
}

@Bean
public Trigger jobTrigger() {

//这玩意比较深奥,我不懂
CronScheduleBuilder schedule = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");

//绑定对应工作明细
return TriggerBuilder.newTrigger().forJob(jobDetail()).withSchedule(schedule).build();
//forJob:绑定工作明细
//withSchedule:绑定触发时间
}

}

简而言之:工作明细,肯定需要你把具体工作传进来,所以它的作用就是将工作传入Quartz,触发器肯定要知道你的工作明细才知道你做什么,所以它需要你传入工作明细,再把它传入Quartz,触发器肯定也需要一个触发时间,那么就还需要一个CronScheduleBuilder对象来设置时间

工作,工作明细,触发器一环扣一环,也体现出Quartz结构比较严谨

5.spring简化定时任务

上面的步骤比较繁琐,还有更简单的方法

1.首先在启动类上加上开启定时任务功能的注解

1
@EnableScheduling

2.另外编写一个类,专门写定时任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @Author 林峰
* @Date
* @Version 1.0
*/
@Component
public class task {

//这个注解就代替了我们原来的配置类
@Scheduled(cron = "0/1 * * * * ?")
public void print(){
System.out.println("hello world");
}
}

这个要注意加@Component

6.监控

屏幕截图 2023-05-19 214013