Spring Data JPA 一Projections

在开发的过程中,有一个这样的需求,统计出top10,怎么实现

不好的做法:使用list,循环取出统计数据名称和统计结果,然后放入map中

好的做法:使用了Projection变得很简单


---------------------------------------------------------------------------------------------------------

AlertRepository.java


@Query(value = "select alertResult.count as statisticResult,alertResult.name as statisticsName from(select count(1) count,name from alert where DATA_STATUS='1' GROUP BY name order by count desc)alertResult\n" +
        "where rownum <= :top",nativeQuery = true)
    public List<AlertProjection> queryTop10AlertGroupByName(@Param("top")int top);

AlertProjection.java 是一个接口

public interface AlertProjection {
    String getStatisticsName();
    String getStatisticResult();
}


Projections的优点

翻译:在Spring Data Repository的查询方法中通常返回的是domain model。但是有的时候可能因为不同的原因需要改变model的视图,学会了projection就可以很方便地制定视图。

比如下面的模型中,人有名字和地址属性,不希望暴露人的地址,在获取属性时只希望得到名字。

属性说明:

id:主键

firstName 和lastName是数据属性

address 连接到另外一个领域对象



@Entity
public class Person {

  @Id @GeneratedValue
  private Long id;
  private String firstName, lastName;

  @OneToOne
  private Address address;
  
}

@Entity
public class Address {

  @Id @GeneratedValue
  private Long id;
  private String street, state, country;

  
}


Person对应的Repository如下:

interface PersonRepository extends CrudRepository<Person, Long> {

  Person findPersonByFirstName(String firstName);
}

Spring data会返回领域对象的所有属性。如果要检索address,可以为其定义如下的Repository

interface AddressRepository extends CrudRepository<Address, Long> {}

这样使用PersonRepository时会返回整个的Person对象,使用AddessRepository则只会返回address。

如果不想暴露address的详细信息,怎么办?

这时候就可以为repository的使用者定义一个或者多个projection,projection内容如下:

NoAddresses.java

interface NoAddresses {  

  String getFirstName(); 

  String getLastName();  
}

注意:

1 projection是一个声明式的接口

2 包含要导出属性的getter,firstName属性的getter写成getFirstName,这样Spring Data框架才能根据约定正确取得属性

如下,在返回值中使用定义好的projection NoAddresses,就会只返回名称,不会返回地址。


interface PersonRepository extends CrudRepository<Person, Long> {

  NoAddresses findByFirstName(String firstName);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值