在一个项目的实际开发过程中牵涉到复杂业务的时候,我们不可避免的需要使用中间表来进行数据连接,有的同学就说了,我可以采用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视图简介。到此打完收工!!!
关联文章: