Spring Data JPA如何判斷記錄是否存在?

在使用Spring/Spring Boot+Spring Data JPA的開發過程中,判斷表中滿足條件的記錄是否存在是一個經常遇到的業務場景,比如檢查指定用戶名的用戶是否存在,檢查指定id的設備是否存在等等。在業務開發過程中,通常有兩種方法:

1)使用指定的條件查詢數據庫,然後在業務代碼判斷返回的結果是否爲null,如果爲null則滿足條件的記錄不存在,否則記錄存在。

2)使用JPA提供的封裝方法existsXXX,方法返回ture表示滿足條件的記錄存在,否則不存在。

那麼這兩種方法有何區別,在業務中應該如何選擇呢?下面我們從兩種方法使用的SQL語句,網絡交互以及適用的業務場景出發講解兩種方法。

1 實驗環境準備

1.1 版本信息

JPA 版本:2.3.4.RELEASE

MySQL版本:8.0

Wireshark:3.6.1

1.2 數據庫表

@Table(name = "t_device", indexes = @Index(name = "device_id", columnList = "device_id"))
public class Device {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;

    @Column(name = "device_id", unique = true, nullable = false)
    private String deviceId;

    @Column(name = "app_id", nullable = false)
    private String appId;
}

1.3 方法定義

@Repository
public interface DeviceRepository extends JpaRepository<Device, String> {

    Device findByDeviceId(String deviceId); // 方法1

    boolean existsByDeviceId(String deviceId); // 方法2
}

2、SQL分析

有兩種方法可以獲取上述方法1和方法2執行的SQL語句,一種時在應用程序開啓SQL語句打印,一種是通過網絡抓包。由於網絡抓包相對不夠簡潔,因此在應用程序開啓SQL打印可以方便在日常工作中分析JPA執行的SQL。在application.ymal中添加下面的配置可以開啓打印SQL語句:

spring:
  jpa:
    show-sql: true #控制檯顯示SQL

方法Device findByDeviceId(String deviceId);執行的SQL語句爲(語句經過了修改,JPA生成的語句比較不方便查看):

SELECT * FROM t_device WHERE device_id = 'your device id'

方法boolean existsByDeviceId(String deviceId);執行的SQL語句爲(語句經過了修改,JPA生成的語句比較不方便查看):

SELECT id FROM t_device WHERE device_id = 'your device id' LIMIT 1

從SQL語句來看,兩個方法的主要區別爲:

1)方法1查詢記錄的所有字段

2)方法2只查詢記錄的主鍵並且只返回一條記錄(limit 1)

方法1返回的數據量要大於方法2,因此當表的字段很多時,這種數據量差異就更加明顯。下面我們通過網絡抓包來證實數據量的差異。

3 網絡分析

可以使用Wireshark軟件進行網絡抓包和分析,Wireshark支持分析MySQL協議。如果你不方便抓包也沒有關係,可以從本文對應的項目下載抓包文件並分析,下載地址

3.1 方法1對應Server的響應如下:

3.2 方法2對應Server的響應如下:

從網絡抓包來看,方法1返回的數據量要大於方法2。

4 業務場景選擇

從SQL和網絡分析來看,兩種方法的原來是相同的,都是向Server發送一個查詢命令,然後根據查詢的結果進行判斷。不同的是兩種方法執行的SQL不同,Server返回的數據量不同,方法1的數據量以及對帶寬的佔用多與方法2,那麼在開發中如何根據不同的場景進行選擇呢?

  • 場景1:只需要判斷記錄是否存在

    這種場景選擇方法2的成本最低執行效率最高,因爲只是判斷記錄是否存在,不需要查詢記錄所有的字段。

  • 場景2:判斷記錄是否存在,並且在記錄存在時對記錄執行其他操作

    這種場景選擇方法1,因爲在判斷記錄是否存在後還需要進行其他的操作,如果使用方法2還需要再次使用方法1獲取記錄進行操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章