Spring Data之Projection的使用

背景

假设我们存在一个User实体,同时有一个接口要查询id、firstName、lastName,我们如何实现呢

@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String firstName;

    private String lastName;

    private Integer age;

    private String idCard;

    private Date birthday;

    @Temporal(TemporalType.DATE)
    private Date createTime;

    private Date updateTime;

}
public interface UserRepository extends JpaRepository<User,Long>{
	List<User> findByAge(Integer age);
}

最直接的做法就是调用findByAge方法,然后循环将List中的User转换为返回对象,但这有两个不好的地方

  • 该查询会将User的所有属性都查询出来,我们只需要3个字段
  • 会有一层for循环对象转换的过程,DO-VO

Projection

使用Projection能解决以上两个问题,Projection并不是一个注解开关,而是一种写法。Spring Data允许自定义的返回类型,可以有选择地检索托需要的字段,避免查询所有字段。我们可以将返回类型定义为接口所需要的字段,就可以避免一次没必要的for循环对象转换。

public interface UserRepository extends JpaRepository<User,Long> {

    List<UserInfo> findByAge(Integer age);

    interface UserInfo{
        Long getId();

        String getFirstName();

        String getLastName();
    }
}

可以看到现在将findByAge的返回结果范型改为UserInfo,UserInfo是一个接口,只包含方法声明,这样JPA就知道查询时只需要UserInfo中的3个字段了

接口的调用如下

@GetMapping(value = "/users")
    public HttpEntity<List<UserRepository.UserInfo>> queryUserInfo(Integer age){
        return ResponseEntity.ok(userRepository.findByAge(age));
    }

控制台日志

Hibernate: select user0_.id as col_0_0_, user0_.first_name as col_1_0_, user0_.last_name as col_2_0_ from user user0_ where user0_.age=?

在这里插入图片描述
如果想把id改成userId返回,需要用到@Value填充值,同时给getId加上@JsonIgnore

interface UserInfo{
    @JsonIgnore
    Long getId();

    @Value("#{target.id}")
    String getUserid();

    String getFirstName();

    String getLastName();
}

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值