Spring Boot-创建泛型存储库 [英] Spring Boot - Create Generics Repositories

查看:191
本文介绍了Spring Boot-创建泛型存储库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆