7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Repositoryを使った検索で特定カラムだけをPOJOへマッピングする

Last updated at Posted at 2017-09-11

概要

Spring Data JPAのRepositoryを使った検索で必要なカラムだけを取得する方法があったのでコードを書いて動かしてみました。
いままではJPQLでSELECT new com.example.domain.Fuga(...) FROM Hoge AS hoge ...のような書き方をしていたのですが、だいぶ簡単に実装できるようになりました。

環境

  • Windows10 Professional
  • Java 1.8.0_144
  • Spring Boot 1.5.6
    • Spring Data JPA 1.11.6
    • Hibernate 5.0.1
    • Lombok
  • MySQL 5.6.25

参考

サンプルコード

Entityクラス

package com.example.domain.entity;

import com.example.domain.StandardType;
import lombok.*;

import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;

@Entity
@Table(name="item")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString(exclude = {"itemStocks"})
@EqualsAndHashCode(exclude = {"itemStocks"})
public class Item implements Serializable {

    private static final long serialVersionUID = -3153084093423004609L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name="name", nullable = false)
    private String name;
    @Column(name="price", nullable = false)
    private Integer price;
    @Column(name="sales_from", nullable = false)
    private LocalDateTime salesFrom;
    @Column(name="sales_to", nullable = false)
    private LocalDateTime salesTo;
    @Enumerated(EnumType.ORDINAL)
    @Column(name="standard_type", nullable = false)
    private StandardType standardType;
    @JoinColumn(name = "category_id", nullable = false)
    @ManyToOne
    private Category category;
    @Column(name="del_flag", nullable = false)
    private Boolean delFlag;
    @Column(name="create_at", nullable = false)
    private LocalDateTime createAt;
    @Column(name="update_at", nullable = false)
    private LocalDateTime updateAt;

    @OneToMany(mappedBy = "item", cascade = CascadeType.ALL)
    private List<ItemStock> itemStocks;
}

Dtoクラス

Itemエンティティのうちid、name、priceだけを持つDtoクラスです。
Repositoryで検索した結果をこのクラスにマッピングします。

package com.example.domain.dto;

import lombok.Value;

@Value
public class ItemNameAndPrice {
    private Long id;
    private String name;
    private Integer price;
}

Repositoryクラス

package com.example.domain.repository;

import com.example.domain.entity.Item;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ItemRepository extends JpaRepository<Item, Long> {
    // Class-based projections用の検索メソッド
    <T> T findOneById(Long id, Class<T> type);
}

findOneを使った検索

Item item = repository.findOne(1L);

発行されるSQL

select
    item0_.id as id1_1_0_,
    item0_.category_id as categor10_1_0_,
    item0_.create_at as create_a2_1_0_,
    item0_.del_flag as del_flag3_1_0_,
    item0_.name as name4_1_0_,
    item0_.price as price5_1_0_,
    item0_.sales_from as sales_fr6_1_0_,
    item0_.sales_to as sales_to7_1_0_,
    item0_.standard_type as standard8_1_0_,
    item0_.update_at as update_a9_1_0_,
    category1_.id as id1_0_1_,
    category1_.create_at as create_a2_0_1_,
    category1_.del_flag as del_flag3_0_1_,
    category1_.name as name4_0_1_,
    category1_.update_at as update_a5_0_1_ 
from
    item item0_ 
inner join
    category category1_ 
       on item0_.category_id=category1_.id 
where
    item0_.id=?

Class-based projections

ItemNameAndPrice nameAndPrice = repository.findOneById(1L, ItemNameAndPrice.class);

内部的にDtoをnewしているのは変わりません。

select new com.example.domain.dto.ItemNameAndPrice(
    generatedAlias0.id,
    generatedAlias0.name,
    generatedAlias0.price) 
from
    Item as generatedAlias0 
where
    generatedAlias0.id=:param0

発行されるSQL

select
    item0_.id as col_0_0_,
    item0_.name as col_1_0_,
    item0_.price as col_2_0_ 
from
    item item0_ 
where
    item0_.id=?
7
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?