我正在学习如何使用extend
Spring的CrudRepository
接口来为实体创建存储库。但是我在实现使用非硬编码值的更复杂查询时遇到了麻烦。这是一个人为的例子。 HQL无效,但它显示了我正在尝试做的事情:
import mypackage.DogTypeEnum;
public interface myRepository extends CrudRepository<Dog, Integer> {
int oldAge = 10; // years - old for a dog
@Query(SELECT dog From Dog dog WHERE dog.age > oldAge and dog.type = DogTypeEnum.poodle
public List<Dog> findOldPoodles()
}
所以在上面的例子中,我试图查询超过一定年龄阈值的所有类型贵宾犬的狗。我不想硬编码poodle
或值10
,因为这些值将在代码中的其他地方使用,我想避免重复。我不想要求用户将这些值作为参数传递。
有没有办法做到这一点?
您可以创建一个扩展存储库的接口,如下所示:
//Only complex querys
public interface MyRepositoryCustom {
List<Dog> findOldPoodles()
}
//您的存储库必须扩展到MyRepositoryCustom
public interface MyRepository extends CrudRepository<Dog, Integer>, MyRepositoryCustom {
// Declare query methods
}
//更复杂的查询
public class MyRepositoryImpl implements MyRepositoryCustom {
@PersistenceContext
private EntityManager em;
public List<Dog> findOldPoodles() {
Query query = em.createQuery("SELECT dog From Dog dog WHERE dog.age > :oldAge and dog.type = :type");
query.setParameter("oldAge",10);
query.setParameter("type",DogTypeEnum.poodle.name);
return query.getResultList();
}
}
请记住,所有java类都以大写字母开头。
此链接可以帮助您:Spring repositories
在我的情况下,我永远不会遇到这个问题,如果您按照下一个包架构显示构建项目,则不会出现此问题:
View(Angular,JSP,JSF ...) - APP
控制器 - APP
服务 - 主要核心
DAO - 主要核心
实体 - 主要核心
通过这种方式,您可以实现更加模块化,可升级,可维护和全面的应用程
您在视图中使用的技术无关紧要,您只需在服务上调用正确的方法即可。
在这里,在服务包上你可以有一个服务,例如:
@Service
public class ServiceDog extends Serializable {
@Autowired
private MyRepository myRepository;
int oldAge = 10;
public List<Dog> findOldPoodles() throws ServicioException {
return myRepository.findAllByAgeGreaterThanAndType(oldAge, DogTypeEnum.poodle);
}
}
现在,您可以使用从spring-data-jpa reference获得的所有优势,或者使用更简单的JPQL查询。
这是一个简单的例子,但是这样你就可以确保每个DAO只与一个实体对话(它只有这个实体所需的方法,如save,delete ..与其他DAO没有依赖关系),服务就是那些调用不同的DAO并对它们进行必要的操作。
希望这可以帮助。