Spring-Data-Jpa projection用法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/believer123/article/details/78517915

进行数据查询时,有时候并不需要把全部字段查询出来,只要查询部分的字段即可。那么就需要使用到Sping-Data-Jpa中的projection功能了。

前提:有用户表和订单表,用户与订单的关系是1对多关系。订单表的模型bean:

@Entity
@Table(name = "t_order")
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(targetEntity = User.class)
    @JoinColumn(name = "user_id")
    private User user;

    private String orderName;
    private String orderNumber;

    @Convert(converter = DateToDateTimeConverter.class)
    private DateTime createTime;
    @Convert(converter = DateToDateTimeConverter.class)
    private DateTime updateTime;
    get/set方法略...
}

1、使用接口定义需要获取的字段,如获取订单名称和对应的用户id和用户名称,定义好需要获取的字段对应的get方法:

public interface OrderQueryDTO {

    public Long getUserId();

    public String getOrderName();

    public String getUsername();

}
db查询:
    @Query("select  orderName , user.userId ,user.username  from Order where id = ?1")
    <T> T findOrderWithUserNameByOrderId(Long id, Class<T> target);

使用:

    OrderQueryDTO order2 = orderReadRepository.findOrderWithUserNameByOrderId(1L, OrderQueryDTO.class);
        log.info("2=====使用接口作为projection===" + order2 + "," + order2.getClass().getName());

执行后对应的log:

select order0_.order_name as col_0_0_, order0_.user_id as col_1_0_, user1_.username as col_2_0_ from t_order order0_, t_user user1_ where order0_.user_id=user1_.user_id and order0_.id=?
 2=====使用接口作为projection==={userId=1, orderName=orderName, username=user0},com.sun.proxy.$Proxy105

2、使用Bean作为DTO,如只需要查询订单名称字段,则定义如下bean,注意需要使用构造方法。

public class OrderQueryDTO2 {

    private String orderName;

    public OrderQueryDTO2(String orderName) {
        super();
        this.orderName = orderName;
    }
    get/set方法
    }

    db方法定义:
    OrderQueryDTO2 findOrderNameById(Long id);

使用:

    OrderQueryDTO2 order5 = orderReadRepository.findOrderNameById(1L);
        log.info("5=====findOrderNameById 跟方法名无关,而是根据返回的bean的字段来的===" + order5.getOrderName());

查询结果:

Hibernate: select order0_.order_name as col_0_0_ from t_order order0_ where order0_.id=?
5=====findOrderNameById 跟方法名无关,而是根据返回的bean的字段来的===orderName

根据sql可以看出只查询了订单名称这一个字段

3、查询单个字段,如查询用户id,需要使用@Query设置sql

/**
     * 自定义查询字段,注意这里查询使用的是bean对应的属性字段而不是数据库字段
     * @param username
     * @return
     */
    @Query("select userId from User where username = ?1")
    Long findUserIdByUsername(String username);

以上代码已提交至git服务器:
[oschina 地址]
http://git.oschina.net/cmlbeliever/SpringBootLearning
[github 地址]
https://github.com/cmlbeliever/SpringBootLearning
中SpringJpa工程。对应的类路径为测试包下的com.cml.learn.jpa.test.order.OrderQueryTest


总结:projection方式有如下三种

  1. 使用构造方法进行设置的bean
  2. 使用接口定义,自定义get方法
  3. 自定义sql,返回需要的字段

猜你喜欢

转载自blog.csdn.net/believer123/article/details/78517915