Java 데이터베이스 액세스 쿼 리 결과 변환 POJO 클래스 로 설정

이런 조작 은 주로 복잡 한 sql 처리 에 사용 되 는데 간단 한 조작 은 모두 jpa 인 터 페 이 스 를 사용 할 수 있어 더욱 편리 하 다
Spring jdbcTemplate
Spring 은 편리 한 Row Mapper 실현-Bean Property Row Mapper 를 제공 합 니 다.
지정 한 클래스 의 인 스 턴 스 에 데 이 터 를 자동 으로 표시 합 니 다.먼저 이 클래스 를 예화 한 다음 이름 이 일치 하 는 방식 으로 속성 에 표시 합 니 다.
예 를 들 어 속성 명(vehicle No)이 같은 이름 의 열 이나 밑줄 이 있 는 같은 이름 의 열 에 일치 합 니 다(VEHICLENO)。속성 이 일치 하지 않 으 면 속성 값 을 Null 로 되 돌려 줍 니 다.
@Override

public  List query(String sql, RowMapper rowMapper) throws DataAccessException {

   return query(sql, new RowMapperResultSetExtractor(rowMapper));

}

사용자 정의 dto 를 매 핑 할 수도 있 고 enity class 를 매 핑 할 수도 있 습 니 다.
JOPO:
@Data

@AllArgsConstructor

@NoArgsConstructor

public class SendLeads {

    private String source;

    private String subSource;

    @JSONField(serializeUsing = ToStringSerializer.class)

    private Long id;

    private String name;

    private String sex;

    private String mobile;

    @JSONField(format = "yyyy-MM-dd HH:mm:ss")

    private LocalDateTime createTime;

    private String dealerID;

    private String provinceID;

    private String cityID;

    private String seriesID;

    private String specID;

    private String visitSource;

}

접근 방법:
public List findClientRoughLeads(LocalDateTime startTime, LocalDateTime endTime) {

        List query = jdbcTemplate.query(SELECT_SQL,

                new Object[]{convertToString(startTime), convertToString(endTime)},

                new BeanPropertyRowMapper<>(SendLeads.class));

        return query;

    }

실체 필드 를 사용자 정의 할 때 특수 처리 가 필요 하 다 면 RowMapper 를 사용자 정의 하여 MapRow 방법 을 실현 할 수 있 습 니 다.
@Data

@AllArgsConstructor

@NoArgsConstructor

public class SendLeads implements RowMapper {

    private String source;

    private String subSource;

    @JSONField(serializeUsing = ToStringSerializer.class)

    private Long id;

    private String name;

    private String sex;

    private String mobile;

    @JSONField(format = "yyyy-MM-dd HH:mm:ss")

    private LocalDateTime createTime;

    private String dealerID;

    private String provinceID;

    private String cityID;

    private String seriesID;

    private String specID;

    private String visitSource;

    public SendLeads(String source, String mobile, String dealerID) {

        this.source = source;

        this.subSource = "";

        this.id = 22L;

        this.name = "";

        this.sex = "";

        this.mobile = mobile;

        this.createTime = null;

        this.dealerID = dealerID;

        this.provinceID = "";

        this.cityID = "";

        this.seriesID = "";

        this.specID = "";

        this.visitSource = "";

    }

     @Override
    public SendLeads mapRow(ResultSet rs, int rowNum) throws SQLException {
        SendLeads sendLeads = new SendLeads();

        source = rs.getString("source");
        subSource = rs.getString("subSource");
        id = rs.getLong("id");
        name = rs.getString("name");
        sex = rs.getString("sex");
        mobile = rs.getString("mobile");
        createTime = rs.getTimestamp("createTime").toLocalDateTime();
        /**
         *     
         */
        //.....

        dealerID = rs.getString("dealerID");
        provinceID = rs.getString("provinceID");
        cityID = rs.getString("cityID");
        seriesID = rs.getString("seriesID");
        specID = rs.getString("specID");
        visitSource = rs.getString("visitSource");

        return sendLeads;
    }

}

Spring Data Jpa
1.원생 Sql 사용
1.매 핑 Entity class
@Entity

@Table(name = "user")

@Data

@AllArgsConstructor

@NoArgsConstructor

public class User implements Serializable{

    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    @Column

    private Long id;

    @Column

    private String name;

    @Column

    private String phone;

    @Column

    private LocalDateTime createdDate;

    @Column

    private LocalDateTime modifiedDate;

}

Query q = entityManager.createNativeQuery("SELECT * FROM User", User.class);

List users = q.getResultList();

2.사용자 정의 Dto 매 핑
@SqlResultSetMapping,@Constructor Result 를@NamedNativeQueries 와 결합 하여 맵 을 만 듭 니 다.
사용자 정의 Dto
@Data

@AllArgsConstructor

@NoArgsConstructor

public class UserDto {

    private Long id;

    private String name;

    private String phone;

    private LocalDateTime createdDate;

    private LocalDateTime modifiedDate;

}

SqlResultSetMapping,@NamedNativeQueries 설정
@SqlResultSetMapping(

        name = "UserDtoMapping",

        classes = @ConstructorResult(

                targetClass = UserDto.class,

                columns = {

                        @ColumnResult(name = "id", type = Long.class),

                        @ColumnResult(name = "name"),

                        @ColumnResult(name = "phone"),

                        @ColumnResult(name = "created_date", type = LocalDateTime.class),

                        @ColumnResult(name = "modified_date", type = LocalDateTime.class)}))

@NamedNativeQueries({

        @NamedNativeQuery(

                name = "findUser",

                query = "SELECT * FROM User",

                resultSetMapping = "UserDtoMapping"

        )

})

@Entity

@Table(name = "user")

@Data

@AllArgsConstructor

@NoArgsConstructor

public class User implements Serializable {

    public static final String FIND_USER = "findUser";

    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    @Column

    private Long id;

    @Column

    private String name;

    @Column

    private String phone;

    @Column

    private LocalDateTime createdDate;

    @Column

    private LocalDateTime modifiedDate;

}

주의사항:
Where to place @SqlResultSetMapping in case of @ConstructorResult ?
@SqlResultSetMapping can be placed at any entity class (don't annotate POJOs - it won't work). Mapping to POJO class with @ConstructorResult was added in version 2.1 of JPA. POJO used with the mapping has to have correct constructor.
@SqlResultSetMapping 은 설 치 된 Entity class 와 아무런 관계 가 없습니다.다만@SqlResultSetMapping 은 Entity Class 에 놓 아야 하기 때문에 Entity class 를 임의로 찾 았 습 니 다.
사용:
Query q = entityManager.createNamedQuery(User.FIND_USER);

List users = q.getResultList();

더욱 최적화:
The suggestion of putting the @SqlResultSetMapping and @NamedNativeQuery (or @NamedQuery) inside the @Entity class definition is not elegant and evidently does not follow the separation of concerns principle.
The more proper solution is the usage of the @MappedSuperclass annotation as the following:
UserDtoExtend.java (the class must be abstract):
@MappedSuperclass

@SqlResultSetMapping(

        name = "UserDtoMapping",

        classes = @ConstructorResult(

                targetClass = UserDto.class,

                columns = {

                        @ColumnResult(name = "id", type = Long.class),

                        @ColumnResult(name = "name"),

                        @ColumnResult(name = "phone"),

                        @ColumnResult(name = "created_date", type = LocalDateTime.class),

                        @ColumnResult(name = "modified_date", type = LocalDateTime.class)}))

@NamedNativeQueries({

        @NamedNativeQuery(

                name = "findUser",

                query = "SELECT * FROM User",

                resultSetMapping = "UserDtoMapping"

        )

})

public abstract class UserDtoExtend {

    public static final String FIND_USER = "findUser";

}

2.JPQL@Query 사용
사용자 정의 Dto:
@Data

@AllArgsConstructor

@NoArgsConstructor

public class UserDto {

    private Long id;

    private String name;

    private String phone;

    private LocalDateTime createdDate;

    private LocalDateTime modifiedDate;

    public UserDto(Long id, String name, String phone) {

        this.id = id;

        this.name = name;

        this.phone = phone;

    }

}

Entity class :
@Entity

@Table(name = "user")

@Data

@AllArgsConstructor

@NoArgsConstructor

public class User implements Serializable {

    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    @Column

    private Long id;

    @Column

    private String name;

    @Column

    private String phone;

    @Column

    private LocalDateTime createdDate;

    @Column

    private LocalDateTime modifiedDate;

}

설명:
@Repository

public interface UserRepository extends JpaRepository {

    /**

     * @return

     */

    @Query(value = "select new com.test.dto.UserDto(a.id,a.name,a.phone,a.createdDate,a.modifiedDate) from User as a")

    List findUserDto();

}

사용:
List userDtos = userRepository.findUserDto();

참고:
https://stackoverflow.com/questions/25179180/jpa-joining-two-tables-in-non-entity-class/25184489#25184489

좋은 웹페이지 즐겨찾기