spring-data-jpa

標籤:spring-data-jpa

Spring Data Jpa 自動化的選擇 - Code First

潮流特區
MacauYeah ・2025-01-22

Code First vs Database First 在早期SQL資料庫盛行的年代,在設計要使用資料庫儲存資料時,很經常遇到一個策略選擇的問題Code First vs Database First 這兩個策略的差異可能越來越講不清,筆者也找了一些現時網路上的講法。 Code First 先從寫程式的角度出發,設計數據模型,再使用工具把你程式碼中的數據模型類Class,生成一個對應用SQL資料庫的表Table,自動編做好對應的數據結構Schema。這樣你在設計時,以程式設計為主導,方便熟悉程式的人使用。這常見於第一手開發設計,因為資料都是第一次收集和儲存,考慮收集程式的運作最為實際。 Database First 先從SQL資料庫的儲存、取用資料的方式出發,先用SQL成生Table及Schema,再轉變成為程式碼中的數據模型。這樣的資料庫在日後作分析用途時,比較簡單易懂,方便使用熟悉SQL的人去使用。這也常見於二次開發程式,因為這樣可以確保不會錯誤地破壞原有資料庫。 那麼筆者為何講這兩個差異越來越講不清?那是因為現在的資料庫不能單純地只考慮初次或二次開發問題,而是需要考慮多個系統協調運行的問題。 多系統共享協定 Database First 因為隨著資料系統發展,有些資料會作為數據源出現或用作共享媒界,如果一定要對設計策略作分類,在多系統協調運作下,這些應該叫使Database First。不論它們是SQL還是NoSQL資料庫,我們的程式碼都要為這個預先定義好的數據結構作出妥協。不論使用工具,還是人為分析,都要把共享的數據結構轉換成自己程式中的數據模型。 即使不是多系統協調運作,有時候因為要移植系統,但同時又要令兩個系統版本相容。新系統也是被逼使用Database First的方式設計。 自動化考量 Code First 前述我們講到,很多時候我們也是從Database First的方式思考。不過筆者就這個Database First,也弄到滿身傷痕。 首先,拋開工具轉換的誤差,我們人為的把共享數據轉化為數據模型,共享數據有時會有一些先天的缺陷,例如 資料沒有設計Primay Key 主鍵,唯一鍵、日期時間的定義不明確等。面對一些意義不明的數據來源,要整合確實很要命。而且二次開發中,不可能100%重用原有的資料庫結構,很多時都會加入新的欄位或更多表格去計數。一旦加入新欄位,在團隊多人開發中,那麼使用唯一的共享開發環境,就變很易有程式碼上的衝突。 若需要多人開發,各人有一個Code First的開發用資料庫,是很必要的。這也可以在系統正式升級前,對比開發中資料庫及舊資料庫的結構,觀看它們之間的差異,評估升級的風險。 也許Code First並不是重點,重點是可以隨時建立一個測試用的資料庫,這才方便合作開發。自動化的地方,不單只限於數據結構,範例資料也該是如此。如果有維繫一個初始範例資料,可以在有需要時自動生成,對於多變的環境一定有很幫助。 現時,筆者基本上都會人為檢視資料庫,人工對照編寫程式中的資料結構即是人工的Database First,並確保那時程式再次經自動化生成的測試用資料庫,並沒有失真即是Code First。至於範例資料,初期筆者也只使用SQL生成,但後期因為資料結構開始複雜,筆者也暫暫使用程式碼生成,雖然工作量會多了,但對於資料庫升級、品牌更換,這是很有效的手段,程式碼升級測試也更順暢,絕比SQL生成更易維護。 Ref Code First vs Database First httpsbuiltin.comarticlescodefirstvsdatabasefirstapproach

Spring Boot 03 - 做好Database的模組化及測試用例

潮流特區
MacauYeah ・2024-04-12

這節,我們將會使用springdatajpa,寫一個業務上的資料庫模組,提供資料表的存取,讓你的好同僚可以直接使用。這樣可以在多模組的環境中,減少同一個資料表在不同地方重複又重複地重定義。將來要更新,也可以使用jar檔的方式發佈。 下戴模版 我們跟上節一樣,使用Spring Initializr Maven 下載模版,但細節筆者就不再講啦。Dependency主要選擇 H2 Database Spring Data JPA 對pom.xml作一些微調,並把springbootstartdatajpa,h2改為只在測試中生效。 並把Java檔案搬一搬位置 # old location srcmainjavaiogithubmacauyeahspringboottutorialspringbootdatatestSpringBootDataTestApplication.java srcmainresourcesapplication.properties # new location srctestjavaiogithubmacauyeahspringboottutorialspringbootdatatestSpringBootDataTestApplication.java srctestresourcesapplication.properties 以上的操作,主要是因為我們的目標是提供Schema,或者叫資料表規格。其他用於做連線的操作,我們不需要打包在jar內。所以把那些次要的東西都放在test資料夾中。我們這時可以先用mvn test指令,確保一切功能還是正常。 Entity folder 然後我們入正題,在pom.xml中加入hibernatecore,springdatajpa, 然後在main資料夾下加入 Entity、Repository,例如前述用過的Apple和AppleRepo,最後資料夾就像是這樣。 . pom.xml src main ` java ` io ` github ` macauyeah ` springboot ` tutorial ` springbootdatatest Apple.java ` AppleRepo.java ` test java ` io ` github ` macauyeah ` springboot ` tutorial ` springbootdatatest SpringBootDataTestApplication.java ` SpringBootDataTestApplicationTests.java ` resources ` application.properties 然後我們在Test Case中使用AppleRepo @SpringBootTest class SpringBootDataTestApplicationTests @Autowired AppleRepo appleRepo; @Test void contextLoads Apple apple = new Apple; apple.setUuidUUID.randomUUID.toString; apple.setWeight100.0; apple.setGravity1000.0; appleRepo.saveapple; 這個跟前述02springdatajpa最大的差別,就是我們的main中只有Entity相關的Class,我們發佈jar,別人引用我們的class,別人不會解發其他不相干的商業邏輯。假如發佈02的例子,因為Spring有自動初始化Component的原因,很可能會誤觸發02中的BasicApplicationRunner.java Source Code spring boot data test

Spring Boot 02 - 快速接入Database的選擇: Spring Data JPA

潮流特區
MacauYeah ・2024-03-08

快速下戴模版 使用Spring initializr,可以很容易就建立一個以Spring boot starter為底的java project。大家可以使用Spring 官網又或是vscode plugin 快速地建立一個maven或gradle project。筆者較為熟悉maven,就以maven起一個範例。 在使用Spring initializr有幾件事必需要指定的 Spring boot version 3.x.y 或以上 Language java Group Id 請選擇有意思的域名,如果你用github,可以選 io.github.yourusername artifactId 這個範例的名字,例如commandline Packaging type 本次使用jar,日後若開發web 應用,可以使用war Java version 17或以上 Dependency Spring Data JPA, Spring Boot DevTools 這次不像過去順利,因為這裏欠缺了Database連線資料,為了方便測試,我們先在pom.xml加入 h2與spring的整合很好。即使用什麼都不設定,直接運行mvn springbootrun,都可以成功執行了。但如果可以,在application.properties加入資料庫設定,會方便日後移植到其他常用的資料庫品版牌。 # srcmainresourcesapplication.properties spring.datasource.driverclassname=org.h2.Driver spring.datasource.url=jdbch2memtestdb; spring.datasource.usename=random spring.datasource.password=random 然後我們就可以做靠Spring Data JPA去生資料庫的表 table。Spring Data JPA預設使用的是Hibernate。假設,我們有一個表叫APPLE。我們就可以開一個class Apple和一個interface AppleRepo去接它。 srcmainjavaiogithubmacauyeahspringtutorialspringbootdatabasicApple.java @Entity public class Apple @Id String uuid; Double weight; getter setter srcmainjavaiogithubmacauyeahspringtutorialspringbootdatabasicAppleRepo.java public interface AppleRepo extends JpaRepository no content here 注意,因為不同需要,AppleRepo可能繼承不同的XXXRepository,它們大部份都是用來觸發寫入資料庫的指令。而這個也晚除了直接存取Hibnerate EntityManager的需要。 亦因為我們現在用的是h2Database,其實資料表並不存在。我們需要在執行Spring Boot時,同步先建立表,所以在application.properties 加入自動建表的設定。 # srcmainresourcesapplication.properties spring.jpa.generateddl=true spring.jpa.hibernate.ddlauto=update 然後在Spring Boot Context的環境下,可以隨時執行寫入的操作。 @Autowired private AppleRepo appleRepo; public void saveApple Apple apple = new Apple; apple.setUuidUUID.randomUUID.toString; apple.setWeight100.0; appleRepo.saveapple; Source Code spring boot data basic 因為h2Database只是用作測試用,所以springboot執行完,資料庫就會被刪除。而上述原始碼當中,還附上了一些dump sql的方法,至少可以讓大家驗證己儲存的結果。