Spring Boot-创建泛型存储库 [英] Spring Boot - Create Generics Repositories
问题描述
我的Web应用程序中有许多服务可以执行经典的CRUD操作,这些是参数"部分.为了避免为每个实体类创建一个存储库接口,我想创建一个通用存储库.我尝试了下面的代码,但是只有在我有一个控制器的情况下,它才有效.
I have many services in my web application that do a classic CRUD operations, theses are Parameters section. In order to avoid creating for each entity class, a repository interface, I want to create a generic repository. I tried the code below but that only works if I have one controller.
public class BaseController<T extends BaseEntity> {
@Autowired
protected JpaRepository<T, Integer> dao;
}
@RestController
@RequestMapping("matieres")
@Api(value = "Matieres", tags = {"Parametrages"})
public class MatiereController extends BaseController<Matiere> {
@GetMapping
public Page<Matiere> find(
@RequestParam(defaultValue = "0", required = false, name="page") Integer page,
@RequestParam(defaultValue = "20", required = false, name="size") Integer size) {
return this.dao.findAll(PageRequest.of(page, size));
}
@PostMapping
public ResponseEntity<Matiere> create(@RequestBody Matiere matiere) {
return ResponseEntity.ok(this.dao.save(matiere));
}
}
推荐答案
除非您将存储库注册为Spring bean,否则Spring无法使用它们.因此,首先您应该创建存储库接口(
Unless you register your repos as Spring beans the Spring couldn't work with them. So first you should create repo interfaces (
public interface UserRepo extends JpaRepository<User, Long> {}
public interface PersonRepo extends JpaRepository<Person, Long> {}
但是有个好消息-您只能在抽象控制器中实现所有典型(CRUD)方法,例如:
But there is a good news - you can implement all typical (CRUD) methods in the abstract controller only, for example:
public abstract class AbstractController<T> {
protected final JpaRepository<T, Long> repo;
public AbstractController(JpaRepository<T, Long> repo) {
this.repo = repo;
}
@GetMapping
public List<T> getAll() {
return repo.findAll();
}
@GetMapping("/{id}")
public ResponseEntity getOne(@PathVariable("id") Long id) {
return repo.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public T create(@RequestBody T entity) {
return repo.save(entity);
}
@PatchMapping("/{id}")
public ResponseEntity update(@PathVariable("id") Long id, @RequestBody T source) {
return repo.findById(id)
.map(target -> { BeanUtils.copyProperties(source, target, "id"); return target; })
.map(repo::save)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@DeleteMapping("/{id}")
public ResponseEntity delete(@PathVariable("id") Long id) {
return repo.findById(id)
.map(entity -> { repo.delete(entity); return entity; })
.map(t -> ResponseEntity.noContent().build())
.orElse(ResponseEntity.notFound().build());
}
}
然后只需注册您的具体控制器即可使用您的所有实体:
Then just register your concrete controllers to get working with all your entities:
@RestController
@RequestMapping("/people")
public class PersonController extends AbstractController<Person> {
public PersonController(PersonRepo repo) {
super(repo);
}
}
@RequestMapping("/users")
public class UserController extends AbstractController<User> {
public UserController(UserRepo repo) {
super(repo);
}
}
演示: sb-generic-controller-demo .
P.S.当然,此代码具有演示目的.在实际项目中,您应该将业务逻辑移至事务服务层.
P.S. Of cause this code has a demo purpose. In the real project you should move your business logic to the transactional service layer.
这篇关于Spring Boot-创建泛型存储库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!