【问题标题】:Querying an unmapped Entity using jpa and hibernate使用 jpa 和 hibernate 查询未映射的实体
【发布时间】:2019-05-21 06:43:22
【问题描述】:

我是 spring、hibernate 和 jpa 的新手。 问题陈述是打一些报告数据库和表中的记录。我正在使用spring boot来创建我的REST应用程序。现在我想从中挑选数据的表很大,我不想为那个表创建实体需要根据某些条件查询表并选择四列作为输出(从大约 60 列中)。我试图在我的 DAO 层中使用 javax.persistence.EntityManager 解决这个问题。但是我到处都得到使用的建议EntityManager 实体必须与某个表进行映射。有没有办法从表中选择结果而不为此生成完整的巨大实体。基本上我想运行一个简单的本机选择查询并获取结果。

SELECT new com.xyz.abc.response.TradeInfo(trade.price,trade.ref,trade.nominal) from Trade trade_tb trade where trade.date between and 。

上面的查询我想在数据库上运行。

【问题讨论】:

    标签: spring hibernate jpa


    【解决方案1】:

    你可以试试这个

    创建一个实体Trade,其中包含您想要的 4 个字段。

    *Hibernate 仅在实体中添加了某些字段但在数据库中不存在时才会抛出错误。反之亦然。

    现在您可以编写这样的自定义查询并获取对象

    List<Object[]> list = em.createQuery("SELECT t.price, t.ref, t.nominal from Trade t where ... ").getResultList();
    
    
    for (Object[] obj : list){
        System.out.println(obj[0]); // price
        System.out.println(obj[1]); // ref
    }
    

    将字段包装在自定义对象中并将其作为 TypedQuery 执行。

    String query = "SELECT NEW SomeObject(t.price, t.ref, t.nominal) from Trade t where ...";
    
    TypedQuery<SomeObject> typedQuery = em.createQuery(query , SomeObject.class);
    
    List<SomeObject> results = typedQuery.getResultList();
    

    【讨论】:

      【解决方案2】:

      你提到你不想为一个巨大的表创建一个实体。你不需要。您可以创建一个仅使用您需要的列的实体。根据您提供的查询,您将需要这样的东西(注意,我实际上并没有测试这些是否有效,它可能有一些错字):

      @Entity
      @Table(name = "trade_tb")
      public class Trade {
          @Id
          @GeneratedValue(strategy = GenerationType.IDENTITY)
          private Long id;
          private Double price;
          private String ref;
          private Double nominal;
          private LocalDate date;
      
          //getters, setters, constructors
      }
      

      一旦你有了这个实体,你就可以像这样定义一个存储库接口:

      @Repository
      public interface TradeRepository extends CrudRepository<Trade,Long> {
          public List<Trade> findByDateBetween(LocalDate beginDate, LocalDate endDate);
      }
      

      Spring boot 会发挥一些作用并自动实现存储库。您需要做的就是自动装配存储库,您只需在其上调用 findByDateBetween 方法即可。

      如果您真的不想定义任何实体,您将需要一个本机查询。 (我在帖子底部添加了一个链接,它比我能更好地解释这些)但是查询需要是有效的 sql,而您的查询中有一些 java 的东西。您需要手动将查询结果映射到对象。 顺便说一句,如果你有实体,你可以使用 JPQL 查询。这些允许使用更接近您的查询的语法,并且会自动为您映射到 Java 对象。

      请记住,Hibernate 和 JPA 用于对象到关系的映射。如果你不打算使用实体,你最好只使用 JDBC。

      有关详细信息,请参阅

      https://spring.io/guides/gs/accessing-data-jpa/

      https://thoughts-on-java.org/jpa-native-queries/

      https://www.tutorialspoint.com/jpa/jpa_jpql.htm

      https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods

      【讨论】:

        【解决方案3】:

        使用自定义实体管理器查询,可以直接查询返回ResultSet的表。

        从 SpringBoot 上下文中获取 EntityManager。

        @PersistenceContext
        private EntityManager entityManager;
        
        Query query = entityManager.createQuery("SELECT trade.price,trade.ref,trade.nominal FROM trade_table trade");
        List<TradeDO[]> tradeRows = query.getResultList();
        

        对于每个 TradeDO,属性的顺序对应于 SELECT 参数顺序。

        【讨论】:

          猜你喜欢
          • 2013-01-22
          • 2010-11-27
          • 2013-08-15
          • 2021-09-13
          • 2012-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多