起因:
由於同事增加了一個對象關聯。並且採用了Example查詢,導致了一個Null的問題。
主表:BoBookingorder
關聯表:BoJobcontainerinfo
一 關聯如下:
@Entity @Table(name = "bo_bookingorder",catalog = "kintech_bo") public class BoBookingorder { private String bookingOrderUUID; private BoJobcontainerinfo boJobcontainerinfo=new BoJobcontainerinfo(); @Id public String getBookingOrderUUID() { return bookingOrderUUID; } @OneToOne @JoinColumn(name = "bookingOrderUUID", referencedColumnName = "orderUUID") public BoJobcontainerinfo getBoJobcontainerinfo() { return boJobcontainerinfo; } public void setBoJobcontainerinfo(BoJobcontainerinfo boJobcontainerinfo) { this.boJobcontainerinfo = boJobcontainerinfo; } }
二 使用三種查詢方式,看sql生成
1 根據bookingOrderNo(非主鍵)查詢
生成的sql
// 生成了2段SQL select * from bo_bookingorder where BookingOrderNo=? and IsValid=1 order by CreateTime desc limit 1 ====================================================== select * from kintech_bo.bo_jobcontainer bobookingo0_ where bobookingo0_.orderUUID=?
PS:
很明顯,自己寫@Query註解sql (select * from xxx where .....),分成了2次查詢,
這意味着,先查詢了主表:BoBookingorder,然後填充了關聯表:BoJobcontainerinfo
2 Example查詢
查詢代碼:還是根據bookingOrderNo 查詢
BoBookingorder entity = new BoBookingorder(); entity.setBookingOrderNo(bookingOrderNo); Example<BoBookingorder> ex = Example.of(entity); BoBookingorder bo1 = bookingorderJpaService.findOne(ex);
生成的sql
select bo.* from kintech_bo.bo_bookingorder bo inner join kintech_bo.bo_jobcontainerinfo boc on bo .bookingOrderUUID=boc .OrderUUID where bo.BookingOrderNo=?
PS:
注意 inner join ,這個就是罪魁禍首。由於是inner join ,導致如果 jobcontainerinfo表沒有數據,則bookingorder也返回null
3 常規findOne
調用Jpa自帶的findOne,通過主鍵查詢,看看是否會inner join 關聯
代碼:
BoBookingorder bo2=bookingorderJpaService.findOne("xxx");
生成的sql
select bo.* from kintech_bo.bo_bookingorder bo left outer join kintech_bo.bo_jobcontainerinfo boc on bo.bookingOrderUUID=boc.OrderUUID where bo.BookingOrderUUID=?
PS:
可以看到,JPA自帶的findOne是left join,所以沒有引發不適。
三 結論:慎用Example來做查詢條件。