【问题标题】:Fetch only some attributes from table using jpa findall java使用 jpa findall java 从表中仅获取一些属性
【发布时间】:2021-06-01 15:51:42
【问题描述】:

我只想从表中选择几列。问题是我正在使用前端过滤器的规范和分页,我认为我不能将它们与标准构建器连接起来。我最初的想法是创建一个带有我想要的属性的@MappedSuperClass(在这种情况下,只是 id 和日期),并使用一个空子类中的 dao 存储库进行获取。我之前做过类似的事情并且它有效,但是子类使用不同的表,所以这是一个不同的球类游戏。在这种情况下,由于两个子类都使用同一个表,并且除了一个没有任何属性的类之外没有什么可以区分的,它会一直获取原始更大的类。我想避免在获取后仅使用我想要的列创建视图或在后端处理数据,但我认为这是唯一可能的解决方案。

超类

@MappedSupperClass
public class Superclass
{

   @Column( name = "id" )
   private Integer id;

   @Column( name = "date" )
   private Date date;
}

原始子类

@Entity
@Table( name = "table" )
public class OriginalSubclass
extends Superclass
{

   @Column( name = "code" )
   private Integer code;

   @Column( name = "name" )
   private String name;
}

新的子类

@Entity
@Table( name = "table" )
public class NewSubclass
extends Superclass
{
}

我为新的子类创建了一个新的 dao

@Repository
public interface NewSubclassDao
extends JpaRepository<NewSubclass, Integer>, JpaSpecificationExecutor<NewSubclass>
{
}

有没有办法通过与我的想法相似的东西只获得我想要的属性? 还是可以使用标准构建器来做到这一点? 如果所有选项都不可行,您更愿意使用视图还是处理数据?

编辑

为了清楚起见,我希望 Spring 使用 JPA findAll 或非常类似的东西只为我带来 id 和 date 属性,而不会弄乱规范中的分页或过滤器。

【问题讨论】:

    标签: java spring hibernate jpa


    【解决方案1】:

    您应该可以使用@Query 执行以下操作:

    @Repository
    @Transactional(readOnly = true)
    public interface NewSubclassDao
    extends JpaRepository<NewSubclass, Integer>, JpaSpecificationExecutor<NewSubclass>
    {
        @Query("SELECT table.code FROM #{#entityName} table")              
        public Set<Integer> findAllCodes();
    }
    

    【讨论】:

    • 但是分页和过滤器不能正常工作吗?
    • 不太可能。但是您可以扩展 PagingAndSortingRepository 并添加接口方法以对结果进行分页。
    【解决方案2】:

    有很多方法可以做到这一点,但我认为这是Blaze-Persistence Entity Views 的完美用例。

    我创建了该库以允许在 JPA 模型和自定义接口或抽象类定义模型之间轻松映射,例如 Spring Data Projections on steroids。这个想法是您按照自己喜欢的方式定义目标结构(域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

    使用 Blaze-Persistence Entity-Views 的用例的 DTO 模型可能如下所示:

    @EntityView(User.class)
    public interface UserDto {
        @IdMapping
        Long getId();
        String getName();
        Set<RoleDto> getRoles();
    
        @EntityView(Role.class)
        interface RoleDto {
            @IdMapping
            Long getId();
            String getName();
        }
    }
    

    查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

    UserDto a = entityViewManager.find(entityManager, UserDto.class, id);

    Spring Data 集成让您可以像使用 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

    Page<UserDto> findAll(Pageable pageable);
    

    最好的部分是,它只会获取实际需要的状态!

    【讨论】:

    • 我不知道t think this is what I asked for, or maybe Im 弄错了。这和简单的 JPA 有什么区别?我知道如何按页面获取数据。问题是如何按照我要求的方式获取数据。我将编辑问题以更清楚地说明我想要获取的内容
    • 好吧,你不能只告诉 Hibernate 只获取 1-2 个基本属性,这就是为什么人们通常使用 DTO 来处理这个问题。您可能能够使其与您的映射超类解决方案一起使用并使用 @Immutable 注释实体,但在使用此类解决方案时要小心并始终清除持久性上下文,否则您可能会得到虚假的 OptimisticLockExceptions 或丢失的写入。跨度>
    猜你喜欢
    • 2015-07-31
    • 2020-03-15
    • 2016-02-26
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多