2

我的 Web 应用程序中有许多服务执行经典的 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));
    }
}
4

1 回答 1

7

除非您将您的存储库注册为 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

PS 当然,此代码具有演示目的。在实际项目中,您应该将业务逻辑移至事务服务层。

于 2018-08-05T13:53:11.403 回答