回顾内容看:
一、获取请求参数的方法
参考:[JavaWeb]——获取请求参数的方式(全面!!!)_java 获取请求参数-CSDN博客
Json格式的Body | 加备注@RequestBody |
{id}动态路径 | 加备注@PathVariable |
id=?&name=? | 直接接收就好 |
id=?但参数名与方法参数名不一致; | 加备注@RequestParam ; 加备注@RequestParam List<Long> 名字 |
二、构造(Controller—service—mapper)
1、controller
负责请求转发,接受页面过来的参数,传给Service处理,接到返回值,再传给页面。
2、service
主要负责业务模块的应用逻辑应用设计,调用Mapper接口来查询数据库。
3、Mapper(dao)
数据库操作。
4、DTO(数据传输对象)
为了结构清晰,特意创建了用于接收前端传过来的数据的类(供controller层接収数据),后续可以在service层利用BeanUtils.copyProperties(employeeDTO, employee);,将属性拷贝给对象就好。
5、VO(封装前端显示页面的属性)
要返回给前端的数据,如果在已有的类中找不到的数据,创建VO类来封装传给前端的数据。
三、AOP:面向切面编程
简单理解:面向特定方法编程
定义了类RecordTimeApsect
@Aroud("execution(* com.itheima.service.*.*(..))")
1、步骤:
(1)导入AOP依赖
(2)编写AOP程序:针对特定的方法,根据业务需要进行编程
@component是把程序交给Spring管理
@Aspect是声明是AOP类
@Around("execution(* com.itheima.service.impl.*.*(..))"):com.itheima.service.impl包下的所有类的所有方法
2、核心概念
切入点一定是连接点,但连接点不一定是切入点
相当于连接点serviceImpl方法被包含在@Aspect切面类的@Around涉及的切入点范围内,所以在controller层调用这个service方法的时候,会调用这个service方法对应的自动生成的动态代理对象的方法,这个动态代理对象中的方法已经实现了Aspect中定义的公共方法+方法本身。
AOP的底层 ——> 动态代理技术
注意:所谓的动态代理对象其实是虚构的(没有实体),实际上就是切面类的通知方法+实际的目标方法
实际上就是,controller中调用service方法实际上去执行了切面类中的通知方法,并且把真实的service方法同时传递给了切面类的通知方法,在通知方法中可以完成原本方法的调用。
3、通知类型
注:@Around需要自己调用ProceedingJoinPoint.proceed();来执行原始方法,其他的通知不需要自己调用。
这个m的灰色线部分在上面——>前置通知,在下面——>后置通知
把切入点放到注解@pointcut里面,定义一个void方法pt(),则在以后得所有通知中,只需要@Around("pt()")
4、通知顺序
5、切入点表达式
(1)execution
execution(* com.itheima..update.*(..))
第一个*:返回值。修饰符是可以省略的,但返回值不可以省略
第一个..:任意包;
第二个..:任意方法参数
完整的:
可以+
(2)@annotation:自定义注解
步骤:
1、定义一个annotation格式的类
/** * 自定义注解,用于标识某个方法需要进行功能字段自动填充处理 */ @Target(ElementType.METHOD)//Target表示在哪里生效,ElementType.METHOD表示在方法上生效,只能加在方法上 @Retention(RetentionPolicy.RUNTIME)//Rentention表示注解什么时候生效,RUNTIME表示在运行的时候生效 public @interface AutoFill { //通过设置常量的方法在枚举类中设置 // 数据库操作类型:UPDATE INSERT OperationType value(); }
2、在切面类中@Before("@annotation(annotation这个类的reference地址)")
3、在Mapper要匹配的方法加上@annotion的名字
6、连接点
@Around要用ProcedingJoinPoint
其他用JoinPoint
//获取目标对象
Object target = jointPoint.getTarget();
//获取目标类
String className = jointPoint.getTarget().getClass().getName();
//获取目标方法
String name = jointPoint.getSignature().getName();
//获取目标方法参数
Object[] args = jointPoint.getArgs();
四、文件上传
1、前端:
(1)方法method必须是post,因为图片啥的很大。
(2)enctype需要设置为multipart/form-data,否则上传的只是文件的名字。
2、本地存储
//原始文件名
String originalFileName = file.getOriginalFileName();
//保存文件
file.transferTo(new File("D:/image/" + originalFileName));
但是名字可能会重复,所以要重新命名
//截取原始文件名的后缀 dfdfdf.png
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
//构造新文件名称
String objectName = UUID.randomUUID().toString() + extension;
这里面的UUID是自带的类
如果不配置,默认的上传个图片只能上传1Mb以下的。
除非,在application.yml文件中,配置文件上传大小的配置(搜multipart)
3、云存储
要注册阿里云账号啥的,参考官方SDK编写入门程序,集成使用
配置AccessKey:
看 SDK示例
根据OSS Java SDK快速入门OSS Java SDK快速入门_对象存储(OSS)-阿里云帮助中心配置
五、Redis
一个基于内存的key-value结构数据库。
1、下载
利用cmd:
启动redis:打开到redis的文件包,redis-server.exe redis.windows.conf
链接redis:redis-cli.exe
图形界面:下载就行
2、数据类型
3、常用命令
(1)字符串操作命令
(2)哈希操作命令
(3)列表操作命令
(4)集合操作命令
(5)有序集合操作指令
(6)通用操作指令
3、在Java中操作Redis
设置序列化器的目的是为了能够正常显示key的名字
字符串:
六、HttpClient(com.sky.utils.HttpClientUtil)
在Java程序中通过编码的形式发送http请求
post和get的区别是,post要额外处理要接収的JSON格式的数据,所以要httpPost.setEntity(entity)。之后就正常的发送请求httpClient.execute(httpPost)
七、微信小程序开发
个人身份注册不能开放支付权限,必须要企业啥的
微信小程序注册链接
下载开发工具
(没细看)
八、缓存菜品
通过Redis(内存操作)缓存菜品数据,减少数据库查询操作(磁盘IO操作)。
内存操作比磁盘操作性能好很多
如果同时有很多的人利用数据库查,会很累
根据分类展示菜品——>每个分类下的菜品保存一份缓存数据,即key为哪几个分类的id,value为{某个分类下的菜品们}的字符串形式。
Spring Cache
精确清理:key是某个ID
所有的都清理: allEntries
九、Spring Task
cron表达式:任务触发的时间
分为6-7个域,含义分别为:秒,分钟,小时,日,月,周,年(可选)
其中,日和周几一般只能定义一个,另一个写?,*表示每
例如,2022年10月12日上午9点整——>cron = " 0 0 9 12 10 ? 2022 "
还有别的特殊字符,可以在网站找cron的在线生成器
0 * * * * ?——>每分钟
1/5 * * * * ?——>从第1s开始,每隔5秒触发一次
十、WebSocket
浏览器和服务器双向数据传输,且只需要一次握手
十一、ECharts
基于JavaScrip,有各种的统计图
十二、Apache POI
操作Excel文件
写操作:
//创建Excel文件
XSSFWorkbook excel = new XSSFWorkbook();
//创建sheet页
XSSFSheet sheet = excel.createSheet("info");
//在sheet中创建行对象
XSSFRow row = sheet.createRow(0);
//创建单元格并写入文件内容
row.createCell(0).setCellValue("姓名");
//通过输出流将内存中的Excel文件写入到磁盘
FileOutputStream out = new FileOutputStream(new File("D:\\info.xlsx"));
excel.write(out);
//关闭资源
out.close();
excel.close();
读操作:
File file = new File("D://INFO.XSLX");
FileInputStream in = new FileInputStream(file);
XSSFWorkbook excel = new XSSFWorkbook(in);
XSSFSheet sheet = excel.getSheetAt(0);
//最后的行号
sheet.getLastRowNum();
//可以for循环读取每一行
XSSFRow row = sheet.getRow(i);
//读取单元格内容
String value = row.getCell(0).getStringCellValue();
//关闭资源
in.close();
excel.close();
传到页面端http:
在controller层加上参数HttpServletResponse
public void export(HttpServletResponse response){ reportService.exportBusinessData(response); }
在serviceImpl层中,放一个excel文件的模板,直接在里面加数据就好了
读取模板:(存放在本目录的resource下的话,就用
InputStream in = this.getClass().getClassLoader().getResourceAsStream("相对地址.xsxl"));
InputStream inputStream = this.getClass() .getClassLoader(). getResourceAsStream("template/运营数据报表模板.xlsx"); //基于提供好的模板文件创建一个新的Excel表格对象 XSSFWorkbook excel = new XSSFWorkbook(inputStream);
输出到http上:ServletOutputStream out = response.getOutputStream();
excel.write(out);
//通过输出流将文件下载到客户端浏览器中 ServletOutputStream out = response.getOutputStream(); excel.write(out);
public void exportBusinessData(HttpServletResponse response) { LocalDate begin = LocalDate.now().minusDays(30); LocalDate end = LocalDate.now().minusDays(1); //查询概览运营数据,提供给Excel模板文件 BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(begin,LocalTime.MIN), LocalDateTime.of(end, LocalTime.MAX)); InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx"); try { //基于提供好的模板文件创建一个新的Excel表格对象 XSSFWorkbook excel = new XSSFWorkbook(inputStream); //获得Excel文件中的一个Sheet页 XSSFSheet sheet = excel.getSheet("Sheet1"); sheet.getRow(1).getCell(1).setCellValue(begin + "至" + end); //获得第4行 XSSFRow row = sheet.getRow(3); //获取单元格 row.getCell(2).setCellValue(businessData.getTurnover()); row.getCell(4).setCellValue(businessData.getOrderCompletionRate()); row.getCell(6).setCellValue(businessData.getNewUsers()); row = sheet.getRow(4); row.getCell(2).setCellValue(businessData.getValidOrderCount()); row.getCell(4).setCellValue(businessData.getUnitPrice()); for (int i = 0; i < 30; i++) { LocalDate date = begin.plusDays(i); //准备明细数据 businessData = workspaceService.getBusinessData(LocalDateTime.of(date,LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX)); row = sheet.getRow(7 + i); row.getCell(1).setCellValue(date.toString()); row.getCell(2).setCellValue(businessData.getTurnover()); row.getCell(3).setCellValue(businessData.getValidOrderCount()); row.getCell(4).setCellValue(businessData.getOrderCompletionRate()); row.getCell(5).setCellValue(businessData.getUnitPrice()); row.getCell(6).setCellValue(businessData.getNewUsers()); } //通过输出流将文件下载到客户端浏览器中 ServletOutputStream out = response.getOutputStream(); excel.write(out); //关闭资源 out.flush(); out.close(); excel.close(); }catch (IOException e){ e.printStackTrace(); } }