Spring Boot - создание репозиториев Generics

В моем веб-приложении много сервисов, которые выполняют классические операции 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));
    }
}

А какова ваша цель и что происходит? какие-то исключения?

Indivon 04.08.2018 18:03

Моя цель - создать общий репозиторий или контроллер вместо того, чтобы создавать для каждого класса сущностей интерфейс репозитория. У меня есть эти исключения. Описание: Поле dao в com.simba.controllers.BaseController требовало bean-компонента типа org.springframework.data.jpa.repository.JpaRepository, который не удалось найти. Действие: Рассмотрите возможность определения bean-компонента типа org.springframework.data.jpa.repository.JpaRepository в вашей конфигурации.

podisto 04.08.2018 23:53
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
2
2
1 363
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы не зарегистрируете свои репозитории как 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 05.08.2018 17:46

@podisto, пожалуйста, но не забудьте принять / проголосовать за ответ, если он вам помог)

Cepr0 05.08.2018 18:13

как это сделать, но с jdbc?

Victor Marrerp 20.10.2019 17:59

Другие вопросы по теме