В моем веб-приложении много сервисов, которые выполняют классические операции CRUD, это раздел «Параметры». Чтобы избежать создания для каждого класса сущности интерфейса репозитория, я хочу создать общий репозиторий. Я попробовал приведенный ниже код, но он работает, только если у меня один контроллер.
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));
}
}
Моя цель - создать общий репозиторий или контроллер вместо того, чтобы создавать для каждого класса сущностей интерфейс репозитория. У меня есть эти исключения. Описание: Поле dao в com.simba.controllers.BaseController требовало bean-компонента типа org.springframework.data.jpa.repository.JpaRepository, который не удалось найти. Действие: Рассмотрите возможность определения bean-компонента типа org.springframework.data.jpa.repository.JpaRepository в вашей конфигурации.




Если вы не зарегистрируете свои репозитории как Spring beans, 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-дженерик-контроллер-демонстрация.
P.S. Конечно, у этого кода есть демонстрационная цель. В реальном проекте вы должны переместить свою бизнес-логику на уровень транзакционного сервиса.
Привет @ Cepr0, спасибо за это решение, поэтому мне обязательно нужно создавать интерфейсы. Спасибо
@podisto, пожалуйста, но не забудьте принять / проголосовать за ответ, если он вам помог)
как это сделать, но с jdbc?
А какова ваша цель и что происходит? какие-то исключения?