商务网站开发实验,wordpress 恶意代码,在线crm系统功能模块分析,做视频投稿赚钱的网站公共字段自动填充
需求分析
对于之前的开发中#xff0c;有创建时间、创建人、修改时间、修改人等字段#xff0c;在其他功能中也会有出现#xff0c;属于公共字段#xff0c;对于这些公共字段最好是在某个地方统一处理以简化开发#xff0c;使用Mybatis Plus提供的公共…公共字段自动填充
需求分析
对于之前的开发中有创建时间、创建人、修改时间、修改人等字段在其他功能中也会有出现属于公共字段对于这些公共字段最好是在某个地方统一处理以简化开发使用Mybatis Plus提供的公共字段自动填充功能
代码实现
在实体类的属性上加入TableField注解指定自动填充的策略按照框架要求编写元数据对象处理器在此类中统一为公共字段赋值此类需要实现MetaObjectHandler接口
修改步骤
先在实体类中的公共字段加上自动填充的注释 private Integer status;TableField(fill FieldFill.INSERT)//插入时填充字段private LocalDateTime createTime;TableField(fill FieldFill.INSERT_UPDATE)//插入和更新时填充字段private LocalDateTime updateTime;TableField(fill FieldFill.INSERT)//插入时填充字段private Long createUser;TableField(fill FieldFill.INSERT_UPDATE)//插入和更新时填充字段private Long updateUser;修改控制类中的一些代码 将这些属性的值统一的在insertFill方法中实现。
package com.springboot.reggie.common;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;Component
Slf4j
/*** 自定义元数据处理器*//*** 插入操作自动填充* param metaObject*/public class MyMetaObjecthandler implements MetaObjectHandler {Overridepublic void insertFill(MetaObject metaObject) {log.info(公共字段自动填充[insert]...);log.info(metaObject.toString());metaObject.setValue(createTime, LocalDateTime.now());metaObject.setValue(updateTime,LocalDateTime.now());metaObject.setValue(createUser,new Long(1));metaObject.setValue(updateUser,new Long(1));}
/*** 更新操作自动填充* param metaObject*/Overridepublic void updateFill(MetaObject metaObject) {log.info(公共字段自动填充[update]...);log.info(metaObject.toString());metaObject.setValue(updateTime,LocalDateTime.now());metaObject.setValue(updateUser,new Long(1));}
}问题自动填充时设置的用户id是固定值目的是要动态获取当前登录用户的id 解决办法使用ThreadLocal用户登录成功我们将用户id存在了HttpSession中但是在MyMetaObjectHandler类中是不能获取HttpSession对象的
关于ThreadLocal
客户端每次发送的http请求对于的服务端都会分配一个新的线程来处理 LoginCheckFilter中的doFilter方法、EmployeeController中的update方法、MyMetaObjectHandler的updateFill方法都属于相同的一个线程 即一次请求对应的线程id都是相同的所以可以得到相同的值
package com.springboot.reggie.common;
/*** 基于ThreadLocal封装工具类 用于保存和获取当前登录用户的id*/public class BaseContext {private static ThreadLocalLong/*用户id是Long型*/ threadLocal new ThreadLocal();/***设置值* param id*/public static void setCurrentId(Long id)//设置成静态的 因为这是工具方法{threadLocal.set(id);}/*** 获取值* return id*/public static Long getCurrentId(){return threadLocal.get();}
}package com.springboot.reggie.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.springboot.reggie.common.R;
import com.springboot.reggie.entity.Employee;
import com.springboot.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;Slf4j
RestController
RequestMapping(/employee)
public class EmployeeController {Autowiredprivate EmployeeService employeeService;/*** 员工登录* param request* param employee* return*/PostMapping(/login)public REmployee login(HttpServletRequest request,RequestBody Employee employee){//1、将页面提交的密码password进行md5加密处理String password employee.getPassword();password DigestUtils.md5DigestAsHex(password.getBytes());//2、根据页面提交的用户名username查询数据库LambdaQueryWrapperEmployee queryWrapper new LambdaQueryWrapper();queryWrapper.eq(Employee::getUsername,employee.getUsername());Employee emp employeeService.getOne(queryWrapper);//3、如果没有查询到则返回登录失败结果if(emp null){return R.error(登录失败);}//4、密码比对如果不一致则返回登录失败结果if(!emp.getPassword().equals(password)){return R.error(登录失败);}//5、查看员工状态如果为已禁用状态则返回员工已禁用结果if(emp.getStatus() 0){return R.error(账号已禁用);}//6、登录成功将员工id存入Session并返回登录成功结果request.getSession().setAttribute(employee,emp.getId());return R.success(emp);}/*** 员工退出* param request* return*/PostMapping(/logout)public RString logout(HttpServletRequest request){//清理Session中保存的当前登录员工的idrequest.getSession().removeAttribute(employee);return R.success(退出成功);}/*** 新增员工* param employee* return*/PostMappingpublic RString save(HttpServletRequest request,RequestBody Employee employee){log.info(新增员工员工信息{},employee.toString());//设置初始密码123456需要进行md5加密处理employee.setPassword(DigestUtils.md5DigestAsHex(123456.getBytes()));// employee.setCreateTime(LocalDateTime.now());//employee.setUpdateTime(LocalDateTime.now());//获得当前登录用户的id//Long empId (Long) request.getSession().getAttribute(employee);//employee.setCreateUser(empId);//employee.setUpdateUser(empId);employeeService.save(employee);return R.success(新增员工成功);}/*** 员工信息分页查询* param page* param pageSize* param name* return*/GetMapping(/page)public RPage page(int page,int pageSize,String name){log.info(page {},pageSize {},name {} ,page,pageSize,name);//构造分页构造器Page pageInfo new Page(page,pageSize);//构造条件构造器LambdaQueryWrapperEmployee queryWrapper new LambdaQueryWrapper();//添加过滤条件queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);//添加排序条件queryWrapper.orderByDesc(Employee::getUpdateTime);//执行查询employeeService.page(pageInfo,queryWrapper);return R.success(pageInfo);}/*** 根据id修改员工信息* param employee* return*/PutMappingpublic RString update(HttpServletRequest request,RequestBody Employee employee){log.info(employee.toString());//Long empId (Long)request.getSession().getAttribute(employee);// employee.setUpdateTime(LocalDateTime.now());//employee.setUpdateUser(empId);employeeService.updateById(employee);return R.success(员工信息修改成功);}/*** 根据id查询员工信息* param id* return*/GetMapping(/{id})public REmployee getById(PathVariable Long id){log.info(根据id查询员工信息...);Employee employee employeeService.getById(id);if(employee ! null){return R.success(employee);}return R.error(没有查询到对应员工信息);}
}
解决一下之前“玄学报错”的问题原因是启动类中少了ServletComponentScan 下面是引用的某ai的回答没系统学过springboot这些东西也不懂之后还得学。。还有比较长的路要走。 ServletComponentScan是一个Spring Boot注解用于扫描和注册Servlet、Filter和Servlet监听器。 在传统的Java Web应用程序中我们需要在web.xml文件中配置Servlet、Filter和Servlet监听器。但是使用Spring Boot时可以使用注解来代替web.xml的配置。 ServletComponentScan注解可以在Spring Boot的主配置类上使用它会自动扫描指定包及其子包下的所有Servlet、Filter和Servlet监听器并将它们注册到Servlet容器中。 使用ServletComponentScan注解的步骤如下 在Spring Boot的主配置类上添加ServletComponentScan注解。 在指定的包及其子包下创建Servlet、Filter和Servlet监听器。 在创建的Servlet、Filter和Servlet监听器类上使用WebServlet、WebFilter和WebListener等注解进行配置。 通过使用ServletComponentScan注解Servlet、Filter和Servlet监听器就可以通过注解的方式进行配置和注册而不需要再手动编写web.xml文件。 需要注意的是ServletComponentScan注解只在使用嵌入式Servlet容器如Tomcat时有效对于外部部署的WAR包它不会生效。 总结ServletComponentScan是一个Spring Boot注解用于自动扫描和注册Servlet、Filter和Servlet监听器简化了配置和注册的过程。 新增分类
需求分析
菜品分类和套餐分类添加菜品时选择菜品分类添加套餐时选择套餐分类。 通过前端和设计的数据库看
代码设计
实体类
package com.springboot.reggie.entity;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.time.LocalDateTime;/*** 分类*/
Data
public class Category implements Serializable {private static final long serialVersionUID 1L;private Long id;//类型 1 菜品分类 2 套餐分类private Integer type;//分类名称private String name;//顺序private Integer sort;//创建时间TableField(fill FieldFill.INSERT)private LocalDateTime createTime;//更新时间TableField(fill FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;//创建人TableField(fill FieldFill.INSERT)private Long createUser;//修改人TableField(fill FieldFill.INSERT_UPDATE)private Long updateUser;}
页面发送ajax请求将新增分类窗口输入的数据以json形式提交到服务端服务端Controller接收页面提交的数据并调用Service将数据进行保存Service调用Mapper操作数据保存数据
通过前端发送给后台的请求发现新增菜品和新增套餐分类请求的服务端地址和提交的json数据结构相同所以服务端只需要提供一个方法统一处理。
添加淮扬菜成功 代码不放了
分类信息分页查询
package com.springboot.reggie.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.springboot.reggie.common.R;
import com.springboot.reggie.entity.Category;
import com.springboot.reggie.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;/*** 分类管理*/
RestController
RequestMapping(/category)
Slf4j
public class CategoryController {Autowiredprivate CategoryService categoryService;/*** 新增分类* param category* return*/PostMappingpublic RString save(RequestBody Category category){log.info(category{},category);categoryService.save(category);return R.success(新增分类成功);}/*** 分页查询* param page* param pageSize* return*/GetMapping(/page)public RPage page(int page,int pageSize){//分页构造器PageCategory pageInfo new Page(page,pageSize);//条件构造器LambdaQueryWrapperCategory queryWrapper new LambdaQueryWrapper();//添加排序条件 根据sort进行排序queryWrapper.orderByAsc(Category::getSort);//进行分页查询categoryService.page(pageInfo,queryWrapper);return R.success(pageInfo);// return null;}
}
删除分类 页面发送ajax请求将参数id提交到服务端服务端Controller接受页面提交的数据并调用Service删除数据Service调用Mapper操作数据库
简单删除 /***删除分类 根据id删除分类* param id* return*/DeleteMappingpublic RString delete(Long id){log.info(删除分类id为:{},id);categoryService.removeById(id);return R.success(删除分类成功...);//return null;}完善删除功能
上述的删除只是简单的直接删除菜品或者是套餐但是没有检查删除的分类是否关联了菜品或者套餐需要进行完善。 准备好实体类菜品和菜单
尝试删除“湘菜”湘菜是关联了套餐的删除失败。 添加一个无关联的菜品或者套餐然后再删除之前一直是报错原因是没有添加Autowired注解。 Autowired是Spring框架中的一个注解用于自动装配自动注入对象的依赖关系。在Spring容器中使用Autowired注解可以实现自动装配即根据指定的类型自动在容器中查找匹配的bean并将其注入到目标对象中。 Autowired可以用在构造方法、成员变量、方法以及参数上。当用在构造方法上时Spring会自动在容器中查找匹配的bean并将其作为参数传入构造方法中。当用在成员变量上时Spring会自动在容器中查找匹配的bean并将其注入到成员变量中。当用在方法上时Spring会自动在容器中查找匹配的bean并将其作为方法的参数传入。当用在方法参数上时Spring会自动在容器中查找匹配的bean并将其作为方法参数传入。 使用Autowired注解可以简化代码减少手动配置的工作量。它可以减少了因为对象之间的依赖关系而需要手动创建对象和设置依赖关系的繁琐工作。同时它也增加了代码的可读性和可维护性使得代码更加清晰和简洁。 需要注意的是使用Autowired注解时需要先确保Spring容器中存在匹配的bean。如果存在多个匹配的bean可以使用Qualifier注解或者通过指定名称的方式来指定具体要注入的bean。如果没有找到匹配的bean会抛出异常。 package com.springboot.reggie.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.springboot.reggie.common.R;
import com.springboot.reggie.entity.Category;
import com.springboot.reggie.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** 分类管理*/
RestController
RequestMapping(/category)
Slf4j
public class CategoryController {Autowiredprivate CategoryService categoryService;public Long id;/*** 新增分类* param category* return*/PostMappingpublic RString save(RequestBody Category category){log.info(category{},category);categoryService.save(category);return R.success(新增分类成功);}/*** 分页查询* param page* param pageSize* return*/GetMapping(/page)public RPage page(int page,int pageSize){//分页构造器PageCategory pageInfo new Page(page,pageSize);//条件构造器LambdaQueryWrapperCategory queryWrapper new LambdaQueryWrapper();//添加排序条件 根据sort进行排序queryWrapper.orderByAsc(Category::getSort);//进行分页查询categoryService.page(pageInfo,queryWrapper);return R.success(pageInfo);// return null;}/***删除分类 根据id删除分类* param id* return*/DeleteMapping()// RequestParampublic RString delete(Long id){//this.ids ids;log.info(删除分类id为:{},id);categoryService.remove(id);return R.success(删除分类成功...);//return null;}}
package com.springboot.reggie.service.impl;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.springboot.reggie.common.CustomException;
import com.springboot.reggie.entity.Category;import com.springboot.reggie.entity.Dish;
import com.springboot.reggie.entity.Setmeal;
import com.springboot.reggie.mapper.CategoryMapper;import com.springboot.reggie.service.CategoryService;import com.springboot.reggie.service.DishService;
import com.springboot.reggie.service.SetmealService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;Service
public class CategoryServiceImpl extends ServiceImplCategoryMapper,Category implements CategoryService{Autowiredprivate DishService dishService;//录入菜品分类Autowiredprivate SetmealService setmealService;//录入套餐分类/*** 根据id删除分类 删除之前需要进行判断* param id*/Overridepublic void remove (Long id){//调用框架中的查询方法LambdaQueryWrapperDish dishLambdaQueryWrapper new LambdaQueryWrapper();//添加查询条件 根据分类id进行查询dishLambdaQueryWrapper.eq(Dish::getCategoryId,id);//统计当前分类下关联了几个菜品int count dishService.count(dishLambdaQueryWrapper);//如果当前分类下关联的菜品个数大于0 说明有菜品关联 不能删//查询当前分类是否关联了菜品 如果已关联 抛出一个业务异常if(count0){throw new CustomException(当前分类下关联了菜品不能删除);}//查询当前分类是否关联了套餐 如果已关联 抛出一个业务异常LambdaQueryWrapperSetmeal setmealLambdaQueryWrapper new LambdaQueryWrapper();//添加查询条件 根据分类id进行查询setmealLambdaQueryWrapper.eq(Setmeal::getCategoryId,id);int cnt setmealService.count(setmealLambdaQueryWrapper);//如果当前分类下关联的菜品个数大于0 说明有套餐关联 不能删if(cnt0){throw new CustomException(当前分类下关联了套餐不能删除);}//正常删除分类super.removeById(id);}}
修改分类
需求分析
点击修改按钮弹出修改窗口在修改窗口回显分类信息并进行修改最后点击确定按钮完成修改操作
代码 /*** 根据id修改分类信息* param category* return*/PutMappingpublic RString update(RequestBody Category category){log.info(修改分类信息:{},category);categoryService.updateById(category);return R.success(修改分类信息成功...);}