用户登录
菜单栏展示(Sql数据封装)
用户列表分页展示(limit s, q -> limit (n-1)*q, q s起始下标 q每页展现条数 n页数 “%”#{id}”%” )
增删改注意事物的控制 @Transactional //如果程序运行出现运行时异常,则实现事务回滚
用户状态修改(用户状态tinyint数据类型 ->Boolean 使用RestFul风格)
用户新增(密码需要加密,默认值需要手动设置)
用户数据的修改(name一般不能随意修改, 数据回显->数据更新操作)
用户删除
商品分类列表展现(三级商品分类信息显示)
商品分类新增
商品分类状态修改
商品分类数据修改(不能修改父子关系)
商品分类数据删除(删除该级及其子级)
商品列表
商品列表展现
商品状态修改
商品删除
商品新增(文件上传, 图片回显)
文件(图片)上传
@RestController @CrossOrigin @RequestMapping("/file") public class FileController { @Autowired private FileService fileService; @PostMapping("/upload") public SysResult upload(MultipartFile file){ ImageVO imageVO = fileService.upload(file); if(imageVO == null){ return SysResult.fail(); } return SysResult.success(imageVO); } }@Service public class FileServiceImpl implements FileService{ private String localDir = "F:/JT_SOFT/images"; @Override public ImageVO upload(MultipartFile file) { //1.校验图片的类型 //1.1 获取图片名称 abc.gif ABC.GIF String fileName = file.getOriginalFilename(); //1.2 将字母转化为小写 fileName = fileName.toLowerCase(); //1.3 正则表达式写法 if(!fileName.matches("^.+\.(jpg|png|gif)$")){ return null; } //2.防止木马病毒 图片宽度和高度 try { BufferedImage bufferedImage = ImageIO.read(file.getInputStream()); int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); if(width==0 || height==0){ //说明 不是正经图片 return null; } //3.分目录存储 提交的时间|名称hash abasedhh|type 进行存户 String datePath = new SimpleDateFormat("/yyyy/MM/dd/") .format(new Date()); //3.1 创建图片目录 String dirPath = localDir + datePath; //3.2 创建目录 File dirFile = new File(dirPath); if(!dirFile.exists()){ dirFile.mkdirs(); } //4.要求文件名称不重名 uuid.type String uuid = UUID.randomUUID().toString(); int index = fileName.lastIndexOf("."); //.jpg String type = fileName.substring(index); fileName = uuid + type; //5.实现文件上传 String realFilePath = dirPath + fileName; file.transferTo(new File(realFilePath)); } catch (IOException e) { e.printStackTrace(); //如果出现了异常信息,则返回null即可 return null; } return null; } }
多级目录查询优化策略
由于频繁的链接数据库查询导致性能比较低, 需要将从数据库查询的结果封装到map集合中,每次查询直接从map集合查询即可,查询速度快,但是服务器压力也会相对增加@Service public class ItemCatServiceImpl implements ItemCatService{ @Autowired private ItemCatMapper itemCatMapper; public Map> getMap(){ //基本缓存操作!!! redis缓存服务器 Map > map = new HashMap<>(); //1.查询所有的数据库信息 List list = itemCatMapper.findItemCatList(); //2.遍历数据封装Map for (ItemCat itemCat : list){ int key = itemCat.getParentId(); if(map.containsKey(key)){ map.get(key).add(itemCat); }else{ //key不存在,第一个数据 List tempList = new ArrayList<>(); tempList.add(itemCat); map.put(key,tempList); } } return map; } @Override public List findItemCatList(Integer level) { long startTime = System.currentTimeMillis(); Map > map = getMap(); //level=1 只查询一级数据 if(level == 1) return map.get(0); //level=2 查询一级和二级数据 if(level == 2) return getTwoList(map); //level=3 查询一级和二级和三级数据 List threeList = getThreeList(map); long endTime = System.currentTimeMillis(); System.out.println((endTime - startTime)+"毫秒"); return threeList; } private List getThreeList(Map > map) { //1.先查询一级和二级的数据 List oneList = getTwoList(map); //2.遍历一级集合,获取二级数据 for (ItemCat oneItemCat : oneList){ //2.1 获取二级数据信息, 二级数据可能为null List twoList = oneItemCat.getChildren(); if(twoList == null && twoList.size()==0) continue; for (ItemCat twoItemCat : twoList){ int twoId = twoItemCat.getId(); //2.2获取三级集合信息 List threeList = map.get(twoId); //2.3将三级数据封装到二级对象中 twoItemCat.setChildren(threeList); } } return oneList; } private List getTwoList(Map > map) { //1.查询一级数据 List oneList = map.get(0); for (ItemCat oneItemCat : oneList){ //获取1级Id int id = oneItemCat.getId(); //根据1级Id,查询二级数据 List twoList = map.get(id); oneItemCat.setChildren(twoList); } return oneList; } }
Spring-全局异常处理机制(Controller层利用AOP对异常进行处理)
如果后端服务器发生异常,这时程序终止,则前端服务器无法获取有效的返回值信息. 所以用户看不到操作是否正确. 交互性差,所以需要对该异常进行处理
package com.jt.aop; import com.jt.vo.SysResult; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestControllerAdvice; //@ControllerAdvice //拦截Controller层的异常 //@ResponseBody //返回的数据为JSON串 @RestControllerAdvice public class SystemExceptionAOP { @ExceptionHandler(RuntimeException.class) public SysResult fail(Exception exceptione){ //打印异常信息 exceptione.printStackTrace(); return SysResult.fail(); } }
数组转化为集合
Arrays.asList(ids);
获取业务执行时间,用于测试性能
System.currentTimeMillis();
判断token是否为空或null值
import org.springframework.util.StringUtils;
StringUtils.hasLength(token)
将密码进行md5加密处理
import org.springframework.util.DigestUtils;
DigestUtils.md5DigestAsHex(password.getBytes());
生成唯一的字符串
import java.util.UUID;
UUID.randomUUID().toString();
单点登录项目开发经验总结:属性如果指定了前缀,则剩余的名称可以自动映射
columnPrefix="c_">



