我最近一直在学习Spring Boot框架,根据我的研究,我可以
CrudRepository
并添加自定义方法或
EntityManager
执行自定义SQL查询或
@org.springframework.data.jpa.repository.Query
问题
他们是否缓存我查询过的数据?
他们有相同的表现吗?
哪一个是最优雅的自定义SQL查询方式?如果没有,在使用Spring框架(不限于Repository模式)和Hibernate时,还有其他方法可以处理自定义SQL查询吗?
1。存储库方法
@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;
}
}
2。 EntityManager方法
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();
}
}
第3。 @Query
方法
注意:下面的代码段错误,但我无法弄清楚如何正确执行此操作。因此,如果有人可以帮助我使用命名参数和限制子句(mysql)来实现本机查询,那就太好了。
public interface CollectionRepository extends CrudRepository<Collection, Integer> {
@Query(value = "SELECT * FROM `collection` WHERE `season`=%d LIMIT %d", nativeQuery = true)
List<Collection> findCollectionsForSeason(int season, int count) {
}
}
谢谢!
答案 0 :(得分:1)
您可以使用上述每种方法缓存数据。因为这是另一回事。您需要使用例如Ehcache或Redis,并为要缓存的方法提供<ProgressBar
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="10dp"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/form_items_margin"
android:layout_gravity="center"
android:max="100"
android:progress="90"
android:progressDrawable="@drawable/progress_drawable_vertical" />
注释。
非常相似,只要确保你不要搞砸了。我宁愿选择JPARepository和本地查询,但这是个人偏好的问题。您可以查看一些文章,例如:http://wiki.aiwsolutions.net/2014/03/18/spring-data-versus-traditional-jpa-implementation/
对于此:@Cacheable
,您可以创建JPARepository方法而不是本机查询。这样的事情:
@Query(value = "SELECT * FROM collection WHERE season=%d LIMIT %d", nativeQuery = true)
在这里阅读更多内容: http://docs.spring.io/spring-data/jpa/docs/1.4.3.RELEASE/reference/html/jpa.repositories.html
答案 1 :(得分:1)
所有这三种方法都使用底层的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);
}
在实现本机查询时,请记住,如果要将它们转换为实体,则返回的列必须与映射的名称匹配。
每当您需要实现应在运行时处理的更复杂的查询时,请记住,您将能够提供扩展给定接口的自己的存储库实现。
答案 2 :(得分:1)
不要做任何这些事情。而不是扩展CrudRepository
扩展PagingAndSortingRepository
或(当您使用JPA时)JpaRepository
。如何使用它以及如何限制结果在the reference guide中进行了解释。
public interface CollectionRepository extends PagingAndSortingRepository <Collection, Integer> {}
然后添加一个finder方法,该方法接受您的参数和Pageable
参数。
List<Collection> findByReason(String reason, Pageable page);
现在,在您的服务中,您可以执行类似
的操作return collectionRepository.findByReason(reason, new PageRequest(0, count));
如果您需要更灵活的查询,可以始终将分页方法与Specification结合使用。
public interface CollectionRepository
extends CrudRepository<Collection, Integer>,
JpaSpecificationExecutor<Collection> {}
然后在你的服务中
return collectionRepository.findAll(new YourSpecification(), new PageRequest(0, count));
这允许非常灵活的查询生成(我们使用一般实现来提供大多数可搜索的数据表)。
基本上,它归结为使用框架(并理解它)而不是解决它。