JPA : How to convert a native query result set to POJO class collection

后端 未结 21 1470
孤街浪徒
孤街浪徒 2020-11-22 09:23

I am using JPA in my project.

I came to a query in which I need to make join operation on five tables. So I created a native query which returns five fields.

相关标签:
21条回答
  • 2020-11-22 09:34

    The easiest way is to use so projections. It can map query results directly to interfaces and is easier to implement than using SqlResultSetMapping.

    An example is shown below:

    @Repository
    public interface PeopleRepository extends JpaRepository<People, Long> {
    
        @Query(value = "SELECT p.name AS name, COUNT(dp.people_id) AS count " +
            "FROM people p INNER JOIN dream_people dp " +
            "ON p.id = dp.people_id " +
            "WHERE p.user_id = :userId " +
            "GROUP BY dp.people_id " +
            "ORDER BY p.name", nativeQuery = true)
        List<PeopleDTO> findByPeopleAndCountByUserId(@Param("userId") Long userId);
    
        @Query(value = "SELECT p.name AS name, COUNT(dp.people_id) AS count " +
            "FROM people p INNER JOIN dream_people dp " +
            "ON p.id = dp.people_id " +
            "WHERE p.user_id = :userId " +
            "GROUP BY dp.people_id " +
            "ORDER BY p.name", nativeQuery = true)
        Page<PeopleDTO> findByPeopleAndCountByUserId(@Param("userId") Long userId, Pageable pageable);
    
    }
    
    
    
    // Interface to which result is projected
    public interface PeopleDTO {
    
        String getName();
    
        Long getCount();
    
    }
    

    The fields from projected interface must match fields in this entity. Otherwise field mapping might break.

    Also if you use SELECT table.column notation always define aliases matching names from entity as shown in example.

    0 讨论(0)
  • 2020-11-22 09:37

    Simple way to converting SQL query to POJO class collection ,

    Query query = getCurrentSession().createSQLQuery(sqlQuery).addEntity(Actors.class);
    List<Actors> list = (List<Actors>) query.list();
    return list;
    
    0 讨论(0)
  • 2020-11-22 09:38

    I tried a lot of things as mentioned in the above answers. The SQLmapper was very confusing as to where to put it. Non managed POJOs only were a problem. I was trying various ways and one easy way I got it worked was as usual. I am using hibernate-jpa-2.1.

    List<TestInfo> testInfoList = factory.createNativeQuery(QueryConstants.RUNNING_TEST_INFO_QUERY)
                        .getResultList();
    

    The only thing to take care was that POJO has same member variable names as that of the query ( all in lowercase). And apparently I didn't even need to tell the target class along with query as we do with TypedQueries in JPQL.

    TestInfo.class

    @Setter
    @Getter
    @NoArgsConstructor
    @ToString
    public class TestInfo {
    
        private String emailid;
        private Long testcount;
    
        public TestInfo(String emailId, Long testCount) {
            super();
            this.emailid = emailId;
            this.testcount = testCount;
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 09:40

    Use DTO Design Pattern. It was used in EJB 2.0. Entity was container managed. DTO Design Pattern is used to solve this problem. But, it might be use now, when the application is developed Server Side and Client Side separately.DTO is used when Server side doesn't want to pass/return Entity with annotation to Client Side.

    DTO Example :

    PersonEntity.java

    @Entity
    public class PersonEntity {
        @Id
        private String id;
        private String address;
    
        public PersonEntity(){
    
        }
        public PersonEntity(String id, String address) {
            this.id = id;
            this.address = address;
        }
        //getter and setter
    
    }
    

    PersonDTO.java

    public class PersonDTO {
        private String id;
        private String address;
    
        public PersonDTO() {
        }
        public PersonDTO(String id, String address) {
            this.id = id;
            this.address = address;
        }
    
        //getter and setter 
    }
    

    DTOBuilder.java

    public class DTOBuilder() {
        public static PersonDTO buildPersonDTO(PersonEntity person) {
            return new PersonDTO(person.getId(). person.getAddress());
        }
    }
    

    EntityBuilder.java <-- it mide be need

    public class EntityBuilder() {
        public static PersonEntity buildPersonEntity(PersonDTO person) {
            return new PersonEntity(person.getId(). person.getAddress());
        }
    }
    
    0 讨论(0)
  • 2020-11-22 09:41

    Yes, with JPA 2.1 it's easy. You have very useful Annotations. They simplify your life.

    First declare your native query, then your result set mapping (which defines the mapping of the data returned by the database to your POJOs). Write your POJO class to refer to (not included here for brevity). Last but not least: create a method in a DAO (for example) to call the query. This worked for me in a dropwizard (1.0.0) app.

    First declare a native query in an entity class:

    @NamedNativeQuery (
    name = "domain.io.MyClass.myQuery",
    query = "Select a.colA, a.colB from Table a",
    resultSetMapping = "mappinMyNativeQuery")   // must be the same name as in the SqlResultSetMapping declaration
    

    Underneath you can add the resultset mapping declaration:

    @SqlResultSetMapping(
    name = "mapppinNativeQuery",  // same as resultSetMapping above in NativeQuery
       classes = {
          @ConstructorResult( 
              targetClass = domain.io.MyMapping.class,
              columns = {
                   @ColumnResult( name = "colA", type = Long.class),  
                   @ColumnResult( name = "colB", type = String.class)
              }
          )
       } 
    )
    

    Later in a DAO you can refer to the query as

    public List<domain.io.MyMapping> findAll() {
            return (namedQuery("domain.io.MyClass.myQuery").list());
        }
    

    That's it.

    0 讨论(0)
  • 2020-11-22 09:43

    In hibernate you can use this code to easily map your native query.

    private List < Map < String, Object >> getNativeQueryResultInMap() {
    String mapQueryStr = "SELECT * FROM AB_SERVICE three ";
    Query query = em.createNativeQuery(mapQueryStr);
    NativeQueryImpl nativeQuery = (NativeQueryImpl) query;
    nativeQuery.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
    List < Map < String, Object >> result = query.getResultList();
    for (Map map: result) {
        System.out.println("after request  ::: " + map);
    }
    return result;}
    
    0 讨论(0)
提交回复
热议问题