在自定义存储库中@Inject存储库是错误的(Spring Data JPA)

时间:2014-05-28 02:11:29

标签: java repository spring-data-jpa querydsl

我想在我的自定义存储库中构建复杂的查询,但由于自定义存储库不扩展“简单”存储库(但反过来),我无法访问存储库的findXxx方法,所以我是@Injecting“简单”的存储库。 它工作得很好,但肯定不好看。 我这样做是因为我不希望在我的存储库前面有另一个“服务”类来处理复杂的查询。我希望它们能够很好地打包在Repository类中。

让我用一些代码解释一下:

PersonRepository.java

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;

public interface PersonRepository extends JpaRepository<Person, Long>, QueryDslPredicateExecutor<Person>, PersonRepositoryCustom {
}

interface PersonRepositoryCustom {
    Page<Person> complexSearch(Person example, Pageable pageable);
}

PersonRepositoryImpl.java

import javax.inject.Inject;
import com.mysema.query.types.expr.BooleanExpression;

public class PersonRepositoryImpl implements PersonRepositoryCustom {

    @Inject
    private PersonRepository repository; // <<<--- This is weird, but works!

    @Override
    public Page<Person> complexSearch(Person example, Pageable pageable) {
        QPerson p = QPerson.person;
        BooleanExpression e = p.id.isNotNull();
        if (example.getName() != null) {
            e = p.name.like("%" + example.getName() + "%");
        }
        if (example.getDob() != null) {
            e = e.and(p.dob.isNotNull()).and(p.dob.after(example.getDob()));
        }
        return repository.findAll(e, pageable); // <<<--- This is weird, but works!
    }

}

那么,我只是直接使用我的存储库,例如来自控制器:

PersonController.java

import javax.inject.Inject;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/")
public class PersonController {

    @Inject
    private PersonRepository personRepository;

    @ResponseBody
    @RequestMapping(value = "/people/search", method = RequestMethod.POST)
    public Page<Person> buscaCampañas(Pageable pageable, @RequestBody Person example) {
        return personRepository.complexSearch(example, pageable);
    }
}

一切都很好,但我不想确保自己不会在脚下射击。

1 个答案:

答案 0 :(得分:0)

从PersonRepositoryImpl和SimpleJpaRepository的技术角度来看,两个不同的spring bean有资格相互正常依赖注入。 从设计的角度来看,我没有看到任何与您的方法有关的严重问题。 Imho,你的方法更像是在同一个对象中自我调用另一个方法。只需将repository替换为this

您还可以引入一个服务层,该服务层将多个存储库或您的查询代码组合到一个更高级别的类中。将来,您可以轻松地通过服务中的真实搜索引擎替换您的关系搜索,而不是修改您的客户端代码。