实用型实战开发笔记

2021-08-19 14:41:06 浏览数 (1)

开发笔记

  • 1. 分页查询
  • 2. 条件查询
  • 3. 文件上传
  • 4. 缓存理论
  • 5. 静态渲染概念
  • 6. 数据表通用字段动态映射方法(如两个必备时间)
  • 7. 定时任务调度
  • 8. 支付
  • 9. elasticSearch

1. 分页查询

依赖:PageHelper

新建一个分页实体对象

Service中

startPage起到拦截作用,仅对其后的第一条查询语句有效。

若依分页原理: 通过

代码语言:javascript复制
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getParameter("pageNum")

得到pageNum=5,将其封装到一个PageDomain实体中 然后调用PageHelper.startPage(page,size…)进行分页。

注意:Request.getParameter只能获取到url中的显式参数

联想:

  • getParameter()获取的是客户端设置的数据。
  • getAttribute()获取的是服务器设置的数据。
  • getParameter()永远返回字符串
  • getAttribute()返回值是任意类型

疑问: HttpServletRequest好像可以通过Autowired注入直接使用,为什么若依要用这么复杂的方式拿到request? 结论:

  1. HttpServletRequest可以注入使用,但只能在控制器中使用,service层等其他地方(以及静态方法中)是不能使用的
  2. 可以通过线程上下文拿到当前的request,SpringMVC提供了RequestContextHolder保存当前的request,ruoyi就是使用这个在service拿到request

2. 条件查询

依赖:通用mapper

1、service接口中提供条件查询服务

2、实现查询服务接口

Example是通用mapper中的对象,用于构造查询条件。

3、控制器中

可以直接通过一个Map接收前端的查询参数。

若依条件查询原理: 前端直接传递查询对象(比如查询对象是user,则传递想要查询的user字段),然后利用mybatis的if实现条件选择。(详情可进入任意一个mapper,进入注释所标注的条件分页查询代码)

优缺点:若依没有使用通用mapper,条件构造是通过sql语句;利用通用mapper构造条件查询利于移植。

3. 文件上传

代码语言:javascript复制
控制器中编写以下代码:
	方法参数接收文件数据
		(@RequestParam(“file”) MultipartFile file)
	方法体中
		创建本地目标文件desFile
	方法体中将文件数据保存到本地文件中
		file.transfTo(desFile);

若依文件上传工具:FileUploadUtils

单点存储可以使用本地存储,但是一般来说都是用云存储(阿里云OSS) 使用OSS存储:

阿里云OSS入门案例:https://www.bilibili.com/video/BV1Ft411c7P1?p=56 注意:同名文件在云空间会被覆盖,因此可以使用时间戳或者UUID来命名;此外,还可以加上OSS中自定义的文件夹名称。

4. 缓存理论

代码语言:javascript复制
缓存穿透:通过重复查询不存在的数据,导致数据库压力过大。
	例子:发起无数次查询:查询id为-1的用户  --> 先到缓存中查询,不存在  --> 再到数据库查询  --> 使得数据库承受无数次查询压力。
	解决方案:查询id为-1的用户  --> 如果缓存中不存在且数据库中也不存在,则在缓存中加入key=查询id,value=0的缓存  --> 第二次查询id为-1  --> 返回0;

缓存击穿:缓存中没有,但是数据库有,当并发量较大的时候,瞬间大批量查询数据库,导致压力较大。
	解决方案:
		1.高并发查询通一个数据,一般是因为该数据是热点数据,因此设置热点数据永不过期。
		2.缓存预热

缓存预热:一开始就将数据库的所有数据存为缓存,用户只允许查询缓存;如果缓存中没有,则说明没有,不必查询数据库(也能防止缓存穿透);当且仅当数据发生变更,再统一更新数据库与缓存。
	实现方法:
		1.存:实现InitializingBean接口,会在启动时调用(或者其他项目初始化方法),在其中查询数据库,并将数据加到缓存中。
		2.取:查询在缓存中查,若不存在,则返回为空
		3.改:修改数据后,更新对应缓存

缓存雪崩:“雪崩”,顾名思义即缓存崩溃;当缓存的过期时间接近导致同一时间大批量缓存过期,瞬间使得缓存类似失效的状态,且数据库在此时接收大批查询,压力大。
	解决方案:
		1.过期时间设置随机(或其他方案),避免同一时间过多缓存过期。
		2.热点数据不过期
		3.缓存预热

5. 静态渲染概念

概念: 对于长期不变动的页面(或者只有部分信息会改变的页面),服务端先生成静态页面,然后前端访问的时候,直接访问静态页面,这样防止每次访问页面,都去数据库查询数据再渲染。

实现思路: 初始化时(或者专门调用静态页面创建接口),生成静态页面。 在静态页面中,对于会发生变动的数据,使用ajax进行动态查询并渲染。

6. 数据表通用字段动态映射方法(如两个必备时间)

必备时间:create_time、update_time

代码语言:javascript复制
1.BaseEntity定义了两个时间等多个通用字段(相当于每个实体都有这些字段),其他实体继承BaseEntity
2.在哪里使用?
	a)在每个实体中的toString打印了这些通用字段
	b)在数据库中这些字段都是存在的
	c)在mapper.xml中有这些字段的操作
3.在哪里插值的?
	在xml中调用sysdate()(数据库函数,得到当前时间)进行设置

7. 定时任务调度

使用SpringTask:

代码语言:javascript复制
Task只能用于简单的定时,他是单线程的。
在SpringBoot中使用步骤:
	1.启动类上添加@EnableScheduling注解,开启Spring的定时任务功能
	2.创建定时任务类,用@Component标注类
	3.创建定时任务方法,返回值必须为void,不允许有参数、用@Scheduled标注
	
@Scheduled可以标注fixedRate和cron表达式,详情百度。

Quartz 核心: Job——任务,执行单元 Trigger——触发器,什么时候执行 Scheduler——任务调度,控制器

代码语言:javascript复制
基本使用(JSEE)
使用步骤:
	1.定义任务类JobDemo,继承Job接口,实现execute方法。
	2.在main方法(或其他执行处)
		a)创建Job对象
		JobDetail job = JobBuilder.newJob(JobDemo.class).build();
		b)创建Trigger对象
		Trigger trigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule(“corn表达式”));
		c)创建Scheduler对象
		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
		d)组合Scheduler和Trigger
		Scheduler.scheduleJob(job,trigger);
		e)启动
		Scheduler.start();

整合SpringBoot:
	通过一个Quartz配置类,注入三个核心组件,并关联自定义的Job对象,然后在启动类中开启Quartz注解。
	注意:Job对象在Quartz配置类中关联的方式,是通过工厂反射注入的,而非Spring注入,因此,当我们在Job对象中使用Autowired注入service等IOC容器时会失败。
	解决方案:重写AdaptableJobFactory中的createJobInstance,在返回Job之前,使用AutowireCapableBeanFactory将其加入到IOC容器中
(参考https://www.bilibili.com/video/BV1mE411F7NJ?p=6)


Quartz持久化:生成官方的12张表,这些表都不用管、然后完成配置类编写;
若依是另外写了一个sys_job表保存job的信息,并且所有的增删查改都是在其上操作。Quartz的表都是框架自动使用。


若依quartz解析:
	1.生成官方的10张表 (没有qrtz_job_listeners、qrtz_paused_trigger_graps、qrtz_trigger_listeners)、完成QuartzConfig
	2.创建自己的sys_job表,用于存储任务,对应实体SysJob只是简单的Javabean,没有实现Job接口
	3.在controller中都是对sys_job的增删改查
	4.自已有一套utils操作quartz
	5.在service层调用mapper对SysJob操作,同时通过utils使sys_job与Quartz相关联(这个工具包的具体操作我看不懂)

8. 支付

alipay

代码语言:javascript复制
逻辑:
	1.根据公钥密钥APPID等字段生成支付端口
	2.用户下单生成订单(状态:未支付)等一系列准备工作
	3.将订单信息发送到支付端口
	4.支付端口返回支付页面,用户扫码支付
	5.支付端口回调支付成功页面(状态:完成支付)
	6.订单入库等一系列收尾工作
代码语言:javascript复制
注意事项:
	1.将生成的公钥填入RSA2(SHA256)应用密钥即可,他会自动生成支付宝公钥,对应我们生成的密钥
	2.在配置文件中,公钥填写网站自动生成的支付宝公钥,密钥填我们工具生成的密钥

9. elasticSearch

提供RestFul接口服务,安装运行之后,通过HTTP请求进行操纵。

协作包:IK分词器、高级rest客户端(在Java项目中通过代码操纵,而不使用HTTP请求)

使用逻辑(以商城为例):

  • 插入商品的同时,构建索引,插到elasticSearch中
  • 发起搜索请求时,使用elasticSearch

未完待续

0 人点赞