Spring Data JPA 三:实现多表联查的另一种方式

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

       在一个项目的实际开发过程中牵涉到复杂业务的时候,我们不可避免的需要使用中间表来进行数据连接,有的同学就说了,我可以采用JPA进行主外键进行关联啊?多对多,多对一,一对一,等,采用主外键关联在数据的操作过程中具有很强的耦合性,尤其对于需要经常删改数据表而言,我们是不建议采用主外键关联这种模式

       对于项目中需要用到多表联查的需求,我们可以通过封装实体类的方式来实现,对于其中不确定的查询条件,利用Spring Data JPA @Query定义中的SpEL中等特性,可以满足一些基本的查询需求,如:

( rd.orderId=:#{#orderPageReq.orderId} or :#{#orderPageReq.orderId} is null)

但是对于一些特殊情况,比如当我们需要根据订单支付金额是否等于0,这时存在三个查询条件1:全部,2:等于0,3:不等于0,对于这种情况,简单的利用SpEL规则就不能满足我们的需求了。

       以订单(order)和订单详情(orderDetail)两张表作为关联查询,两张表中的order.orderId和orderDetail.orderId存在对应关系,但是没有设外键关系。

一、首先在数据库中创建视图:

CREATE VIEW `view_gx_order_info` AS SELECT
`tbl_gx_order`.`order_id` AS `order_id`,
        `tbl_gx_order`.`complaint_state` AS `complaint_state`,
        `tbl_gx_order`.`create_time` AS `create_time`,
        `tbl_gx_order`.`order_amount` AS `order_amount`,
        `tbl_gx_order_detail`.`device_id` AS `device_id`,
        `tbl_gx_order_detail`.`discount_amount` AS `discount_amount`
FROM
        (
                `tbl_gx_order`
                JOIN `tbl_gx_order_detail` ON (
                (
                `tbl_gx_order`.`order_id` = `tbl_gx_order_detail`.`order_id`
        )
)
        )

二、创建视图的映射对象:

import lombok.Data;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Subselect;

import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author ; dongdongqiang
 * @Description 订单详情视图
 * @Date 2018/10/30
 */
@Data
@Entity
@Immutable
@Subselect("select * from view_gx_order_info")
public class GxOrderInfoDO implements Serializable{
    private static final long serialVersionUID = -1480564219055635362L;

    @Id
    private String orderId;
    /**
     * 投诉状态
     *
     * @return
     */
    private Integer complaintState;
    /**
     *
     * 订单创建时间
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;
    /**
     * 订单支付金额
     */
    private BigDecimal orderAmount;
    /**
     * 设备的ID
     */
    private String deviceId;
    /**
     * 优惠金额
     */
    private BigDecimal discountAmount;

}

三、创建Repository类

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

/** * @author ; dongdongqiang 
 * @Description 订单详情视图 
 * @Date 2018/10/30 
 */

public interface GxOrderInfoRepository extends JpaRepository<GxOrderInfoDO, String>,JpaSpecificationExecutor<GxOrderInfoDO> {

}

四、Service

此时的GxOrderInfoRepository与其他的数据库表查询接口的用法就是一样的了。

@Override
public List test(OrderDetailReq gxOrderInfoDO) {
    Page<GxOrderInfoDO> page = gxOrderInfoRepository.findAll((root, cq, cb) -> {
        Predicate predicate = cb.conjunction();
        List<Expression<Boolean>> expressions = predicate.getExpressions();
        if (!StringUtils.isEmpty(gxOrderInfoDO.getUserId())) {
            expressions.add(cb.equal(root.get("userId"), gxOrderInfoDO.getUserId()));
        }
        if (!StringUtils.isEmpty(gxOrderInfoDO.getOrderId())) {
            expressions.add(cb.equal(root.get("orderId"), gxOrderInfoDO.getOrderId()));
        }
        return predicate;
    }, new PageRequest(0, 20, Sort.Direction.DESC, "createTime")));
    return page.getContent();
}

关于SQL中视图的优缺点请自行百度或者参考SQL视图简介。到此打完收工!!!

关联文章:

Spring Data JPA 一:实现多表关联查询

Spring Data JPA 二:实现多表关联分页查询

猜你喜欢

转载自blog.csdn.net/qq_27376871/article/details/83547438
今日推荐