Java 使用ORM、EntityManager、@Query的Spring数据存储库,处理自定义SQL查询最优雅的方式是什么?
我最近一直在学习SpringBoot框架,根据我的研究,我可以Java 使用ORM、EntityManager、@Query的Spring数据存储库,处理自定义SQL查询最优雅的方式是什么?,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我最近一直在学习SpringBoot框架,根据我的研究,我可以 在maven依赖项列表中包括Hibernate JPA实现,扩展crudepository并添加自定义方法 或 使用Hibernate中的EntityManager执行自定义SQL查询 或 使用注释@org.springframework.data.jpa.repository.Query 问题 他们是否缓存我查询的数据 他们有相同的表现吗 哪一种是定制SQL查询最优雅的方式?如果它们都不是,那么在使用Spring框架
- 在maven依赖项列表中包括Hibernate JPA实现,扩展
并添加自定义方法crudepository
- 使用Hibernate中的
执行自定义SQL查询EntityManager
- 使用注释
@org.springframework.data.jpa.repository.Query
- 他们是否缓存我查询的数据
- 他们有相同的表现吗
- 哪一种是定制SQL查询最优雅的方式?如果它们都不是,那么在使用Spring框架(不限于存储库模式)和Hibernate时,有没有其他方法来处理自定义SQL查询
@Entity
@Table(name = Collection.TABLE_NAME)
public class Collection {
public final static String TABLE_NAME = "collection";
...
}
public interface CollectionRepository extends CrudRepository<Collection, Integer> {
}
public class CollectionRepositoryImpl {
@Autowired
private CollectionRepository collectionRepository;
public List<Collection> findCollectionsForSeason(int season, int count) {
List<Collection> results = new ArrayList<>();
for (Collection c : collectionRepository.findAll()) {
if (c.getSeason() == season) {
results.add(c);
}
}
return results;
}
}
public class xxx {
private EntityManager em;
...
public List<Collection> findCollectionsForSeason(int season, int count) {
String sqlString = String.format("SELECT * FROM `collection` WHERE `season`=%d LIMIT %d", season, count);
return this.em.createNativeQuery(sqlString).getResultList();
}
}
谢谢
@Cacheable
注释@Query(value=“SELECT*FROM collection WHERE seasure=%d LIMIT%d”,nativeQuery=true)
,您可以创建JPARepository方法而不是本机查询。诸如此类:
findBySeason(对象季节,可分页)代码>
请在此处阅读更多信息:
所有这三种方法都使用底层Hibernate实现来执行本机查询并获取结果(在第一个实现中,您要检索每个实体,因此性能会更差)。请记住,您可以在一个存储库实现中混合使用所有这些功能,而无需为一个存储库遵循相同的模式 就个人而言,我倾向于使用第三种方法,我认为这是最干净的方法,因为它让我们用Spring处理查询,而不需要您的代码处理实体管理器
public interface CollectionRepository extends CrudRepository<Collection, Integer> {
@Query(value = "SELECT * FROM collection WHERE season=:season LIMIT :count", nativeQuery = true)
List<Collection> findCollectionsForSeason(@Param("season") int season, @Param("count") int count);
}
public interface CollectionRepository扩展了crudepository{
@查询(value=“SELECT*FROM collection WHERE seasure=:seasure LIMIT:count”,nativeQuery=true)
列出FindCollectionsForseson(@Param(“seasure”)int season、@Param(“count”)int count);
}
在实现本机查询时请记住,如果要将列转换为实体,则返回的列必须与映射的名称匹配
每当您需要实现一个更复杂的查询(应该在运行时处理)时,请记住,您可以提供自己的存储库实现来扩展给定的接口。不要做任何这些事情。而不是扩展
crudepository
extend或(使用JPA时)JpaRepository
。有关如何处理该问题以及如何限制结果的说明,请参见
现在,在您的服务中,您可以执行以下操作
return collectionRepository.findByReason(reason, new PageRequest(0, count));
如果您的查询需要更大的灵活性,您可以始终将分页方法与
这允许非常灵活的查询生成(我们使用一个通用实现来为大多数可搜索数据表提供服务)
基本上,它归结为使用框架(并理解框架),而不是围绕框架工作
public interface CollectionRepository extends PagingAndSortingRepository <Collection, Integer> {}
List<Collection> findByReason(String reason, Pageable page);
return collectionRepository.findByReason(reason, new PageRequest(0, count));
public interface CollectionRepository
extends CrudRepository<Collection, Integer>,
JpaSpecificationExecutor<Collection> {}
return collectionRepository.findAll(new YourSpecification(), new PageRequest(0, count));