前言
寒假接手一个项目,甲方提出了这样一个功能——需要一个商品有多张图片。可以进行滑动观看。这个需求很简单,前端只要做一个轮播图,后端只要涉及一个商品下有多组照片即可(一对多关系)。
项目后端选型
框架springboot 数据库框架springDataJpa
想要了解什么springDataJpa,可以看这篇文章
bug重现
甲方在后台图片进行图片拖动改变位置,点击进行修改按钮,该商品拖动改变位置的图片依旧没有发生变化。根据排查,前端发过来请求参数,确实改变了图片的位置。因此只能是后端背锅啦!
可以给大家看看之前我写的前一版的代码(update方法)
@PostMapping("/updateModel")@ApiOperation(value = "更新型号", notes = "更新型号信息")public String updateModel(@RequestBody Model model) throws Exception {// 获取目标型号Model byModelId = modelService.findByModelId(model.getModelId());List<Image> targetImgs = byModelId.getImgs();if (byModelId == null) {throw new Exception("noModel");}if (targetImgs != null) {List<Image> imgs = model.getImgs();if(!CollectionUtils.isEmpty(imgs)) {List<String> url = imgs.stream().map(Image::getUrl).collect(Collectors.toList());for (Image image : model.getImgs()) {url.add(image.getUrl());imageService.addImage(image);}int waterMark = 1;// 改变了,要用原图进行添加水印,而不是用已经水印图进行再一次重复水印waterMark = createWaterMarkWithRaw(model.getModelName(), url);if (waterMark != 1) {throw new Exception("添加水印失败");}}}// 更新保存到数据库modelService.updateModel(model);return "success";}
我在网上苦苦搜寻,都是关于对多端实体进行注解的添加,而我这个项目的多端就是商品下多个图片List< Image > imgs
@OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL,orphanRemoval = true)private List<Image> imgs;
cascade=CascadeType.ALL,orphanRemoval = true这两个说白了就是说进行级联操作,会对对应的子实体也会进行相应的改变(删除、插入等)
然后并没有什么卵用,我一直给干到一点中,弥留之际,我发现了问题的关键所在!
解决方案
因为jpa的机制,是可以通过注解@OneMany将实体创建表,也会创建关系表
在我这个项目就是Model 、Image和Model_img三张表。我在前面不断地测试插入,发现Model_img表没有发生改变,关联关系依旧是原来的“配对”。所以!说明咱们得update方法并没有进行修改Model_img表里所维护的数据。
那么我们只要手动干预model_img表中的关系数据,不就可以了吗。这样查出来就是修改后关系的数据了!
提交后的代码
@PostMapping("/updateModel")@ApiOperation(value = "更新型号", notes = "更新型号信息")public String updateModel(@RequestBody Model model) throws Exception {// 获取目标型号Model byModelId = modelService.findByModelId(model.getModelId());if (byModelId == null) {throw new Exception("noModel");}List<Image> newImags = new ArrayList<>();List<Image> imgs = model.getImgs();if(!CollectionUtils.isEmpty(imgs)) {List<String> url = imgs.stream().map(Image::getUrl).collect(Collectors.toList());for (Image image : model.getImgs()) {url.add(image.getUrl());imageService.addImage(image);Image newImage = new Image();newImage.setUrl(image.getUrl());newImags.add(newImage);}int waterMark = 1;// 改变了,要用原图进行添加水印,而不是用已经水印图进行再一次重复水印waterMark = createWaterMarkWithRaw(model.getModelName(), url);if (waterMark != 1) {throw new Exception("添加水印失败");}}// 清理原先数据model.getImgs().clear();// 添加修改位置的图片数据model.getImgs().addAll(newImags);modelService.updateModel(model);return "success";}
ps:多端实体也是需要进行添加相应的注解!即
@OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL,orphanRemoval = true)private List<Image> imgs;
到此,bug解决!时间终止为1点半!赚钱不易【叹气】