🐳

Spring Data JPAによるソート(複合キーのソート付き)

に公開

spring-bootを使った中での躓いたことや調べたことのメモです。

環境

  • java: 8
  • spring-boot: 2.0.1
  • spring-data-jpa: 2.0.7

前提

以下のEntityで考えます

@Entity
public class Entity {
  @Id
  private int Id;

  private String name;

  private int position;

  // Getter, Setter省略
}

List<T> findAll(Sort sort)

JpaRepositoryを継承したinterfaceを作成した時点でList<T> findAll(Sort sort)が定義されており、次のようにソートできます。

@Service
public class EntityService {

  @Autowired
  EntityRepoistory entityRepository;

  public List<Entity> xxxMethod() {
    return entityRepoistory.findAll(new Sort(ASC, "position"));
  }

}

複合キー

Sortを組み合わせて指定をする

// positionの降順、idの昇順でソート
Sort sort = new Sort(Direction.DESC, "position").and(new Sort(Direction.ASC, "id"));

QueryMethodの定義

JpaRepositoryを継承したinterface上でメソッドを定義するだけでソートを実現できます

@Repository
public interface EntityRepository implements JpaRepository<Entity, Integer> {

  // select * from entity where name = 'xxx' order by position asc と同等
  List<Entity> findByNameOrderByPosition(String name);

  // select * from entity order by position と同等
  // findAllOrderByPositionでは駄目
  List<Entity> findAllByOrderByPosition();
}

findByの戻り値をListにするとこの命名でも複数の結果として取得可能、
findAllOrderByPositionではうまく動かないという罠。

複合キー

// select * from entity order by position desc, id asc と同等
List<Entity> findAllByOrderByPositionDescIdAsc();

アノテーションによる定義

@QueryにJPQL形式で記述することで実現可能

@Repository
public interface EntityRepository implements JpaRepository<Entity, Integer> {
  
  @Query(value = "select e from Entity e order by position desc, id asc")
  List<Sample> queryAll();

  // または

  @Query(value = "select e from Entity")
  List<Sample> queryAll(Sort sort);
}

関連Entityのソートについて

@Orderbyを使用する

@Entity
public class Entity {

  @OrderBy(value = "position desc, id asc")
  @OneToMany()
  @JoinColumn(name = "entity_id")
  private List<EntityItem> entityItems;
}

参考URL

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

Discussion