java 项目
一.异常处理
1.做项目的时候有异常怎么办,如果我们不给前端返回一个他能看的懂的类型,那将会报错。
推荐看:03-全局异常处理器_哔哩哔哩_bilibili,看完就懂了。看一半就懂了!
二.报错
Parameter 'name' not found. Available parameters are [id, param1, status, param2]
解决:注意调试的时候传递的参数对不对,还有service穿的的是一个对象接收的时候也要用对象接收
参数写错报错:
嗯,用户发来了一段错误日志,看起来是Spring Boot应用在运行过程中抛出了一个异常。首先,我需要仔细看看错误信息,找出问题所在。根据日志,异常是org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'category' in 'class com.sky.dto.DishPageQueryDTO'。这说明在MyBatis处理某个查询时,试图访问DishPageQueryDTO类中的category属性,但该类没有对应的getter方法。
这是正确的,错误的是categoryId写成category
三.苍穹外卖模糊或不会的知识点
1.注解和请求参数
1.前端传入的数据是json格式,要用@RequestBody注解转换为对象。
一般json格式的数据,我们会用一个DTO类来接收,这个类有属性和集合
2.请求参数是query
请求参数是query是查询参数,通过地址栏问号形式传递,接收时只需要用带有参数属性的对象接收就行
@GetMapping("/page")
@ApiOperation("员工分页查询")
public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO){
log.info("员工分页查询,参数为:{}",employeePageQueryDTO);
PageResult pageResult = employeeService.PageQuery(employeePageQueryDTO);
return Result.success(pageResult);
}
3.路径参数
{status}是路径参数,1为启用,0为禁用。地址栏传参传入员工id。
(@PathVariable Integer status,Long id),接收路径参数要加注解@PathVariable
取的是路径参数,加注解@PathVariable,如果和路径参数不同名,就要加括号双引号指明取的是哪个路径参数@PathVariable("status") ;如果同名,就不用加。
3.1路径参数
路径参数是一个字符串,比如,我们要批量删除菜品,传进来就是这样的ids=1,2,3,4,5
springMVC框架会给我们处理,并把他们处理好封装到一个集合当中,但我们要加一个注解@
RequestParam
2.对象拷贝
public void save(EmployeeDTO employeeDTO){
Employee employee = new Employee();
BeanUtils.copyProperties(employeeDTO,employee);//对象属性拷贝
把对象employeeDTO,里面的属性拷贝到employee中,注意两个对象的属性应该是,employee包含employeeDTO,并且要拷贝的属性名字相同。
3.DigestUtils.md5DigestAsHex
4.动态获取当前登录人的id
我们请求访问后端携带信息里有id,并且后端会有拦截器把携带信息全拦截下来。
解析出来的id怎么传到service动态设置id:
答:1.客户端每发起一次请求,都会对于一个单独的线程
2.通过ThreadLocal,它是Thread的局部变量,为每个线程提供单独一份的存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,在线程外则不能访问。
可以通过在controller、service和拦截器中输出线程的id来看是否单次请求是同一个线程,经实验验证是同一个线程。
后面操作不写了推荐看:Day02-05-新增员工_代码完善2_哔哩哔哩_bilibili
苍穹外卖注意:1.在修改员工的启用禁用时有个动态sql,不是一般的动态。推荐看看
5.日期显示和日期不显示
日期显示格式修改
日期不显示
日期不显示检查一下有没有给日期赋值,和传递参数
例如:
public void save(EmployeeDTO employeeDTO){
Employee employee = new Employee();
BeanUtils.copyProperties(employeeDTO,employee);//对象属性拷贝
employee.setStatus(StatusConstant.ENABLE);
employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
employee.setCreateUser(10L); //TODO 后续需要改为当前登录用户的id
employee.setUpdateUser(10L);
employeeMapper.insert(employee);
}
//mapper
@Insert("insert into employee(name,username,password,phone,sex,id_number,status,create_time,update_time,create_user,update_user)"+
"values"+
"(#(name),#(username),#(password),#(phone),#(sex),#(idNumber),#(status),#(createTime),#(updateTime),#(createUser),#(updateUser))")
void insert(Employee employee);
6.点击登录没反应
查看数据库有没有启动
四.阿里云
bucket:是存储空间,我们上传的数据都存在这里
7.分页查询没有数据有总记录数
封装对象错了例如:
List<PageResult> list=dishMapper.dishSelect(page,dishPageQueryDTO.getPageSize());
List<Dish> list=dishMapper.dishSelect(page,dishPageQueryDTO.getPageSize());
8.报错
在service层中注意这个,如果我们不数据拷贝,在dishDTO中没有createTime,参数,后面找不到这个参数会报错
在用ai生成代码时可能会出错,比如多个符号在sql中更要注意。
9.修改数据
修改数据要注意数据回显,有时候有多个数据回显,比如,菜品的口味,和套餐中的菜品。
还要注意我们传递过来的参数一般用DTO接收,修改数据时候实际上是插入数据,我们插入的数据要映射到entity包的类中这样才不会报错(因为DTO中没有创建时间修改时间等)
@Override
public SetmealVO modifyData(Integer id) {
//查询回显数据,根据套餐id
//先回显菜品
// 根据id查询套餐信息
//为啥要放到setmeal中因为,VO中有套餐菜品的集合,setmeal中有创建时间之类的属性
Setmeal setmeal=setmealMapper.selectSetmeal(id);
// 根据id查询套餐菜品信息
List<SetmealDish> setmealDishList=setmealAndDishesMapper.selectData(id);
// 创建套餐视图对象
SetmealVO setmealVO=new SetmealVO();
// 将套餐信息复制到套餐视图对象中
BeanUtils.copyProperties(setmeal,setmealVO);
// 将套餐菜品信息设置到套餐视图对象中
setmealVO.setSetmealDishes(setmealDishList);
// 返回套餐视图对象
return setmealVO;
}
10.动态sql
MySQL动态sql_mysql 动态sql-CSDN博客
11.公共字段填充
公共字段比如我们执行添加的时候,会有createtime,等执行修改的时候会有updateTime
@Target(ElementType.METHOD)//表示注解只能加在方法上 //表示指定数据库操作类型 update insert OperationType value(); //切点表达式,对哪些类,哪些方法进行拦截增强 //@annotation(com.sky.annotation.AutoFill)表示拦截带有@AutoFill注解的方法 @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)") public void autoFillPointCut(){}
通知:对代码进行增强的那部分
@Before("autoFillPointCut()") public void autoFil(JoinPoint joinPoint)
JoinPoint:可以获取当前哪个方法被拦截到了,以及被拦截到的方法的具体的参数是什么样子的
12.拦截器错误
registry.addInterceptor(jwtTokenAdminInterceptor)改成registry.addInterceptor(jwtTokenUserInterceptor)
要不然获取不到userId
13.小程序登录的时候获取不到id
小程序登录的时候获取不到id,原因是在登录的这个方法里面,
User user=userMapper.getOpenid(openid); 这个查询方法要写对,就能获得了,我的错误原因,写成select openid from user where openid=#{openid},所以查不出来
13.需要返回主键值的情况
比如,用户提交订单,我应该向订单表中添加数据, 然后再向订单明细中添加数据(订单明细中的数据就是订单中菜品,比如多个菜品,等明细),然后会用到订单的主键值,这就需要我们需要返回主键值。
14.运行到sql时候既不报错也不前进,检查sql语句,可能有错误,特别是用ai,会有字母不对应
15.历史订单不显示
有些时候数据不报错也不显示,查看是不是返回的数据有问题,我这个就是返回的日期格式有问题所以才不显示。苍穹外卖day9 订单不显示的问题-CSDN博客,看了这个解决。
16.
你知道苍穹外卖这个项目吗,我今天在做这个项目遇到了问题,今天做的时查询历史订单,和查询历史订单详情这两个接口,查询订单详情的时候,给出的时封装到orderVO当中,但是这里面只有,public class OrderVO extends Orders implements Serializable {
//订单菜品信息
private String orderDishes;
//订单详情
private List<OrderDetail> orderDetailList;
},而我们要返回的有......
,这参数也不对应怎么封装。还有个问题我查询OrderDetail为什么要封装到集合当中,一个订单不是只有一个订单详情吗,直接封装到订单详情这个类中也可以吧
发给ai已解决
17.动态sql,出现问题,多出and和where
解决
详细查看【17-动态sql-if&where标签-哔哩哔哩】 https://b23.tv/AWzAkAJ。17分钟左右
18.测试类要跟主类启动类在同一个包名下面。
19.年月日时分秒
//LocalDateTime.of表示我要获取localDate这一天的,处了年月日,还要时分秒,LocalTime.MIN这一天最小时间 LocalDateTime startDateTime = LocalDateTime.of(localDate, LocalTime.MIN); //这种类型只有年月日 LocalDate localDate
20.>大于号,<小于号
21.LocalDate dateBegin = LocalDate.now().minusDays(30),当前时间向前推30天
22.导出Excel表格必须使用输出流的原因
文件内容需要写入 HTTP 响应体
- 当用户点击“下载”按钮时,服务器需要将 Excel 文件的二进制数据(或生成的字节流)直接写入 HTTP 响应体。
- 例如,如果 Excel 文件是动态生成的(如通过 Apache POI 或其他库生成),必须通过输出流将内存中的字节流传输给客户端。
四.Redis
1.在java中操作Redis
使用Spring Data Redis使用方式:
五.开发的整体思路
1.开发登录功能,要实现登录的,JWT令牌,统一拦截器
六.webSocket
重点webSocket的步骤。看苍穹外卖的p131
七.ApacheECharts是干什么的,怎么工作的
Day11-02-Apache ECharts_入门案例_哔哩哔哩_bilibili
八.接收日期,处理日期
Day11-04-营业额统计_代码开发_1_哔哩哔哩_bilibili
九.可以用POI来操作读取Excel表格,写入Excel表格,读取Excel表格
Day12-05-Apache POI_介绍_哔哩哔哩_bilibili
导出表格的步骤:
1.查询需要绑定的数据
2.通过POI向表格里面写数据
2.1.获取一个流
文件内容需要写入 HTTP 响应体
-
当用户点击“下载”按钮时,服务器需要将 Excel 文件的二进制数据(或生成的字节流)直接写入 HTTP 响应体。
-
例如,如果 Excel 文件是动态生成的(如通过 Apache POI 或其他库生成),必须通过输出流将内存中的字节流传输给客户端
//2.通过POI把数据写入到Excel文件中
//获取一个流
InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
//基于模板文件创建一个Excel
XSSFWorkbook excel = new XSSFWorkbook(in);
//现在我的模板文件就在第一页名Sheet1
XSSFSheet sheet1 = excel.getSheet("Sheet1");
//填充时间数据
sheet1.getRow(1).getCell(1).setCellValue("时间:" + dateBegin + "至" + dateEnd);
//填充营业额数据
XSSFRow row = sheet1.getRow(3);
row.getCell(2).setCellValue(turnover);
row.getCell(4).setCellValue(orderCompletionRate);
3.通过输出流下载文件
//3.通过输出流将Excel文件下载到客户端浏览器
ServletOutputStream outputStream = response.getOutputStream();
excel.write(outputStream);
outputStream.close();
excel.close();
十.SQL中count 和 sum的区别
总结:count 统计行数一样 。sum:统计总和
count:
sum:
常见误区
十一.参数传递,参数对应,MyBatis参数传递
mybatis中动态sql我们经常用到 #{},这个大括号里面的名字一定要和前端传递的相同
<if test="begin != null"> 这里的test后面的也是。
Map map = new HashMap();
map.put("begin", startDateTime);
map.put("end", endDateTime);
这里要写 user.create_time > #{begin} 和 <if test="begin != null">