Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用ORM、EntityManager、@Query的Spring数据存储库,处理自定义SQL查询最优雅的方式是什么?_Java_Spring_Hibernate_Jpa - Fatal编程技术网

Java 使用ORM、EntityManager、@Query的Spring数据存储库,处理自定义SQL查询最优雅的方式是什么?

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框架

我最近一直在学习SpringBoot框架,根据我的研究,我可以

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

  • 使用Hibernate中的
    EntityManager
    执行自定义SQL查询

  • 使用注释
    @org.springframework.data.jpa.repository.Query
问题

  • 他们是否缓存我查询的数据

  • 他们有相同的表现吗

  • 哪一种是定制SQL查询最优雅的方式?如果它们都不是,那么在使用Spring框架(不限于存储库模式)和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;
    }
}
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();
    }
}
谢谢

  • 您可以使用上述每个方法缓存数据。因为这是另一回事。例如,您需要使用Ehcache或Redis,并对希望缓存的方法提供
    @Cacheable
    注释

  • 非常相似,只是确保你不会把事情搞砸。我更愿意使用JPARepository和原生查询,但这是个人偏好的问题。您可以查看一些文章,例如:

  • 为此:
    @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));