Spring Boot中使用PostgreSQL資料庫

程式猿DD發表於2021-10-09

在如今的關係型資料庫中,有兩個開源產品是你必須知道的。其中一個是MySQL,相信關注我的小夥伴們一定都不陌生,因為之前的Spring Boot關於關係型資料庫的所有例子都是對MySQL來介紹的。而今天我們將介紹另外一個開源關係型資料庫:PostgreSQL,以及在Spring Boot中如何使用。

PostgreSQL簡介

在學習PostgreSQL的時候,我們總是會將其與MySQL放一起來比較:MySQL自稱是最流行的開源資料庫,而PostgreSQL則標榜自己是最先進的開源資料庫,那麼有多先進呢?下面就一起認識一下它!

PostgreSQL是一種特性非常齊全的自由軟體的物件-關係型資料庫管理系統(ORDBMS),是以加州大學計算機系開發的POSTGRES,4.2版本為基礎的物件關係型資料庫管理系統。POSTGRES的許多領先概念只是在比較遲的時候才出現在商業網站資料庫中。PostgreSQL支援大部分的SQL標準並且提供了很多其他現代特性,如複雜查詢、外來鍵、觸發器、檢視、事務完整性、多版本併發控制等。同樣,PostgreSQL也可以用許多方法擴充套件,例如通過增加新的資料型別、函式、操作符、聚集函式、索引方法、過程語言等。另外,因為許可證的靈活,任何人都可以以任何目的免費使用、修改和分發PostgreSQL。

PostgreSQL的優勢

既然跟MySQL一樣,同為關係型資料庫,那麼什麼時候用MySQL,什麼時候用PostgreSQL自然是我們需要去了解的。所以下面簡單介紹一下,PostgreSQL相比於MySQL來說,都有哪些優勢,如果你有這些需求,那麼選擇PostgreSQL就優於MySQL,反之則還是選擇MySQL更佳:

  • 支援儲存一些特殊的資料型別,比如:array、json、jsonb
  • 對地理資訊的儲存與處理有更好的支援,所以它可以成為一個空間資料庫,更好的管理資料測量和幾何拓撲分析
  • 可以快速構建REST API,通過PostgREST可以方便的為任何PostgreSQL資料庫提供RESTful API的服務
  • 支援樹狀結構,可以更方便的處理具備此類特性的資料儲存
  • 外部資料來源支援,可以把MySQL、Oracle、CSV、Hadoop等當成自己資料庫中的表來進行查詢
  • 對索引的支援更強,PostgreSQL支援 B-樹、雜湊、R-樹和 Gist 索引。而MySQL取決於儲存引擎。MyISAM:BTREE,InnoDB:BTREE。
  • 事務隔離更好,MySQL 的事務隔離級別repeatable read並不能阻止常見的併發更新,得加鎖才可以,但悲觀鎖會影響效能,手動實現樂觀鎖又複雜。而 PostgreSQL 的列裡有隱藏的樂觀鎖 version 欄位,預設的 repeatable read 級別就能保證併發更新的正確性,並且又有樂觀鎖的效能。
  • 時間精度更高,可以精確到秒以下
  • 字元支援更好,MySQL裡需要utf8mb4才能顯示emoji,PostgreSQL沒這個坑
  • 儲存方式支援更大的資料量,PostgreSQL主表採用堆表存放,MySQL採用索引組織表,能夠支援比MySQL更大的資料量。
  • 序列支援更好,MySQL不支援多個表從同一個序列中取id,而PostgreSQL可以
  • 增加列更簡單,MySQL表增加列,基本上是重建表和索引,會花很長時間。PostgreSQL表增加列,只是在資料字典中增加表定義,不會重建表。

這裡僅列舉了開發者視角關注的一些優勢,還有一些其他優勢讀者可檢視這篇文章,獲得更詳細的解讀。

下載與安裝

讀者可以通過下面的連結獲取PostgreSQL各版本的安裝程式,這裡不對安裝過程做詳細描述了,根據安裝程式的指引相信大家都能完成安裝(一路next,設定訪問密碼和埠即可)。

下載地址:https://www.enterprisedb.com/downloads/postgres-postgresql-downloads

注意:因為14是今天剛釋出的版本,為避免Spring Boot的相容問題,還是選用之前的13.4版本來完成下面的實驗。

安裝完成後,開啟pgAdmin。因為自帶了介面化的管理工具,所以如果你用過mysql等任何關係型資料庫的話,基本不用怎麼學,就可以上手使用了。

PostgreSQL pgAdmin

Spring Boot中如何使用

在安裝好了PostgreSQL之後,下面我們嘗試一下在Spring Boot中使用PostgreSQL資料庫。

第一步:建立一個基礎的Spring Boot專案(如果您還不會,可以參考這篇文章:快速入門

第二步:在pom.xml中引入訪問PostgreSQL需要的兩個重要依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>

這裡postgresql是必須的,spring-boot-starter-data-jpa的還可以替換成其他的資料訪問封裝框架,比如:MyBatis等,具體根據你使用習慣來替換依賴即可。因為已經是更上層的封裝,所以基本使用與之前用MySQL是類似的,所以你也可以參考之前MySQL的文章進行配置,但資料來源部分需要根據下面的部分配置。

第三步:在配置檔案中為PostgreSQL資料庫配置資料來源、以及JPA的必要配置。

spring.datasource.url=jdbc:postgresql://localhost:5432/test
spring.datasource.username=postgres
spring.datasource.password=123456
spring.datasource.driver-class-name=org.postgresql.Driver

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.hbm2ddl.auto=create

第四步:建立使用者資訊實體,對映user_info表(最後完成可在pgAdmin中檢視)

@Entity
@Data
@NoArgsConstructor
public class UserInfo {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private Integer age;

    public UserInfo(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

第五步:建立使用者資訊實體的增刪改查

public interface UserInfoRepository extends JpaRepository<UserInfo, Long> {

    UserInfo findByName(String name);

    UserInfo findByNameAndAge(String name, Integer age);

    @Query("from UserInfo u where u.name=:name")
    UserInfo findUser(@Param("name") String name);

}

第六步:建立單元測試,嘗試一下增刪改查操作。

@Slf4j
@SpringBootTest
public class ApplicationTests {

    @Autowired
    private UserInfoRepository userRepository;

    @Test
    public void test() throws Exception {
        // 建立10條記錄
        userRepository.save(new UserInfo("AAA", 10));
        userRepository.save(new UserInfo("BBB", 20));
        userRepository.save(new UserInfo("CCC", 30));
        userRepository.save(new UserInfo("DDD", 40));
        userRepository.save(new UserInfo("EEE", 50));
        userRepository.save(new UserInfo("FFF", 60));
        userRepository.save(new UserInfo("GGG", 70));
        userRepository.save(new UserInfo("HHH", 80));
        userRepository.save(new UserInfo("III", 90));
        userRepository.save(new UserInfo("JJJ", 100));

        // 測試findAll, 查詢所有記錄
        Assertions.assertEquals(10, userRepository.findAll().size());

        // 測試findByName, 查詢姓名為FFF的User
        Assertions.assertEquals(60, userRepository.findByName("FFF").getAge().longValue());

        // 測試findUser, 查詢姓名為FFF的User
        Assertions.assertEquals(60, userRepository.findUser("FFF").getAge().longValue());

        // 測試findByNameAndAge, 查詢姓名為FFF並且年齡為60的User
        Assertions.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName());

        // 測試刪除姓名為AAA的User
        userRepository.delete(userRepository.findByName("AAA"));

        // 測試findAll, 查詢所有記錄, 驗證上面的刪除是否成功
        Assertions.assertEquals(9, userRepository.findAll().size());

    }

}

把單元測試跑起來:

單元測試

一切順利的話,因為這裡用的是create策略,所以表還在,開啟pgAdmin,可以看到user_info表自動建立出來了,裡面的資料也可以查到,看看跟單元測試的邏輯是否符合。

PostgreSQL pgAdmin

思考一下

如果您之前有讀過本系列教程中關於MySQL的10多篇使用案例,再看這篇使用PostgreSQL的案例,是不是感覺差別非常小?其實真正變動的部分主要是兩個地方:

  1. 資料庫驅動的依賴
  2. 資料來源的配置資訊

而對於更為上層的資料操作,其實並沒有太大的變化,尤其是當使用Spring Data JPA的時候,這就是抽象的魅力所在!你體會到了嗎?

好了,今天的學習就到這裡!如果您在學習過程中遇到困難?可以加入我們超高質量的Spring技術交流群,參與交流與討論,更好的學習與進步!更多Spring Boot教程可以點選直達!,歡迎收藏與轉發支援!

程式碼示例

本文的完整工程可以檢視下面倉庫中2.x目錄下的chapter6-4工程:

如果您覺得本文不錯,歡迎Star支援,您的關注是我堅持的動力!

參考資料:

歡迎關注我的公眾號:程式猿DD,分享外面看不到的乾貨與思考!

相關文章