java - Spring Data Repository 与 ORM、EntityManager、@Query,处理自定义 SQL 查询最优雅的方式是什么?

标签 java spring hibernate jpa

我最近在学习Spring Boot框架,根据我的研究,我可以

  • 在 Maven 依赖项列表中包含 Hibernate JPA 实现,扩展 CrudRepository 并添加自定义方法

  • 使用 Hibernate 中的 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)的 native 查询,那就太好了。

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) {
    }
}

谢谢!

最佳答案

不要做任何这些事情。而不是扩展 CrudRepository 扩展 PagingAndSortingRepository或(当您使用 JPA 时)JpaRepositorythe reference guide 中解释了如何使用它以及如何限制结果。 .

public interface CollectionRepository extends PagingAndSortingRepository <Collection, Integer> {}

然后添加一个查找器方法,该方法接受您的参数和一个 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));

这允许非常灵活的查询生成(我们使用通用实现来服务大多数可搜索数据表)。

基本上,这取决于使用框架(并理解它),而不是绕过它。

关于java - Spring Data Repository 与 ORM、EntityManager、@Query,处理自定义 SQL 查询最优雅的方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34986666/

相关文章:

java - 如何在android中通过匹配字符串从查询中检索int id?

java - JPA、Spring 和 ObjectDB 未更新

java - 在 Spring MVC Controller 中反序列化 json 数组

java - 使 JPA 和 ModelMapper 在实体更新中工作

java - 调用 JAR 时如何保持内部/隐藏数据库连接打开?

java - java中删除字符串中的常见字符串字符

java - JPA:可以在@OneToMany 上添加额外的 JOIN 约束

java - Spring 和 Hibernate c3p0 错误无法完成架构验证

java - 连接池还是数据源?我应该把哪个放在 JNDI 中?

oracle - 具有多个数据源的 Spring/JNDI : ORA-12519, TNS:未找到适当的服务处理程序