Spring 引导 - 创建泛型存储库
Spring Boot - Create Generics Repositories
我的 Web 应用程序中有许多服务执行 classic CRUD 操作,这些是参数部分。为了避免为每个实体 class 创建存储库接口,我想创建一个通用存储库。我尝试了下面的代码,但只有在我有一个控制器时才有效。
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 无法使用它们。所以首先你应该创建回购接口(
public interface UserRepo extends JpaRepository<User, Long> {}
public interface PersonRepo extends JpaRepository<Person, Long> {}
但有个好消息——你可以只在抽象控制器中实现所有典型的 (CRUD) 方法,例如:
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());
}
}
然后只需注册您的具体控制器即可与您的所有实体一起工作:
@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。因为此代码具有演示目的。在实际项目中,您应该将业务逻辑移至事务服务层。
我的 Web 应用程序中有许多服务执行 classic CRUD 操作,这些是参数部分。为了避免为每个实体 class 创建存储库接口,我想创建一个通用存储库。我尝试了下面的代码,但只有在我有一个控制器时才有效。
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 无法使用它们。所以首先你应该创建回购接口(
public interface UserRepo extends JpaRepository<User, Long> {}
public interface PersonRepo extends JpaRepository<Person, Long> {}
但有个好消息——你可以只在抽象控制器中实现所有典型的 (CRUD) 方法,例如:
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());
}
}
然后只需注册您的具体控制器即可与您的所有实体一起工作:
@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。因为此代码具有演示目的。在实际项目中,您应该将业务逻辑移至事务服务层。