java - Spring:如何将请求发布到多对多关系中
问题描述
我有两个实体,Meal
并且Mealplan
在 @ManyToMany 关系中。每个 Mealplan 包含五个 Meal 对象。
一顿饭:
@Entity
public class Meal {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private BigDecimal price;
private String type;
@ManyToMany(mappedBy = "mealsPerWeek")
private List<Mealplan> mealplan;
}
进食计划:
public class Mealplan {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private int calendarweek;
@ManyToMany
private List<Meal> mealsPerWeek;
例如的 JSON/mealplan/1
如下所示:
{
id: 1,
calendarweek: 10,
mealsPerWeek: [
{
id: 4,
name: "Linsensuppe",
price: 23.5,
art: "vegan"
},
{
id: 3,
name: "Salat",
price: 3,
art: "vegetarisch"
},
现在我想创建一个(自定义?)方法来将膳食添加到膳食计划中。最好的方法是什么?我正在考虑我的存储库中的自定义方法,如下所示:
@RestController
@RequestMapping("/mealplan")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class MealplanController {
@PostMapping
public void addMealToMealplan(@RequestBody Meal meal) {
mealplanRepository.addMealToMealplan(essen);
}
但是如何将此自定义方法添加到存储库中?一个高性能的方法看起来如何?
@Repository
public interface MealplanRepository extends JpaRepository<Mealplan, Integer> {
void addMealToMealplan(Meal meal);
}
不起作用,例如,我不能在接口中声明方法。我需要一个新的班级吗?
解决方案
我会用这样的东西:
确保创建 MealRepository jpa 接口
@Repository
public interface MealRepository extends JpaRepository<Meal, Integer> {
}
然后最好创建 MealPlanService 来处理对象上的任何操作(而不是在控制器中进行实际工作),注入两个存储库。每当我们添加新餐点时,我们都会先将其持久化,然后添加到餐点计划对象上的餐点集合中。自动更新膳食计划的事务性(您可以在膳食计划上手动调用保存)
@Service
public class MealPlanService{
private MealRepository _mealRepository;
private MealPlanRepository _mealPlanRepository;
@Autowire
MealPlanService(MealRepository mealRepository,MealPlanRepository mealPlanRepository)
_mealRepository = mealRepository
_mealPlanRepository = mealPlanRepository
}
@Transactional
public Mealplan addMealToMealplan(int mealPlanId, Meal meal) throws MealNotFoundException{
Mealplan mealplan = _mealPlanRepository.findById(mealPlanId).orElseThrow(MealNotFoundException::new)
meal = _mealRepository.save(meal);
mealplan.getMealsPerWeek().add(meal)
return mealplan;
}
}
并在 Controller 中自动装配服务并执行。如果有人试图改变现有的膳食计划,或者不是他的(在服务中有一些额外的逻辑),你可以额外保护和优雅地捕捉它的好东西
@RestController
@RequestMapping("/mealplan")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class MealplanController {
private MealPlanService _mealPlanService;
@Autowire
MealplanController (MealPlanService mealPlanService){
_mealPlanService = mealPlanService;
}
@PostMapping(path = "/{mealPlanId}/add")
public ResponseEntity<MealPlan> addMealToMealplan(@PathVariable int mealPlanId , @RequestBody Meal meal) {
try{
return ResponseEntity.ok(_mealPlanService.addMealToMealplan(meal));
catch (MealNotFoundException e){
//do some other logic, return error , log it or smth
ResponseEntity.notFound().build();
}
}
POST 请求/mealplan/1/add
与新餐的主体(其中 1 是您mealPlanId
应该添加的餐点)。
控制器将调用服务服务,该服务将尝试首先根据传递的 id 找到膳食计划 _mealPlanRepository.findById(mealPlanId)
这将返回 Optional 并且我们通过调用链接获取值的操作_mealPlanRepository.findById(mealPlanId).orElseThrow(MealNotFoundException::new)
在找到的实体上,我们然后添加我们的新餐(由于 Transactional 它将被持久化,但您可以调用_mealPlanRepository.save()
它而不是
如果一切都正确完成,则服务 retus 更新实体,然后控制器返回带有更新膳食计划的响应实体
推荐阅读
- ios - 如何创建一个字节数组以发送到 BLE 设备并从中获得响应?
- python - 将 3D numpy 数组的切片快速组合为 3D 子数组
- android - 在单个应用程序和 kivy 模拟器中在 kivy 上使用 2 个页面布局
- angular - 在 Angular / Ionic 中发送 HTTPS 请求
- shell - 为什么在没有空文件夹时总是返回找到空文件夹?
- javascript - 使用 XMLHttpRequest 发送数据
- azure - 具有本地访问权限的 Azure 跨区域 VNet 连接
- llvm - LLVM 代码生成器:机器代码表示是否与机器无关?
- redis - Redis 组合键和内存使用命令
- c - 从 C 中的 BST 中删除