javascript
Spring Boot的Spring Data JPA示例
1.簡(jiǎn)介
在本文中,我們將演示如何利用功能強(qiáng)大的Spring Data JPA API與本課程中的數(shù)據(jù)庫(kù)(內(nèi)存中的H2數(shù)據(jù)庫(kù))進(jìn)行交互。
Spring Data JPA提供了一組非常強(qiáng)大且高度抽象的接口,用于與任何基礎(chǔ)數(shù)據(jù)庫(kù)進(jìn)行交互。 數(shù)據(jù)庫(kù)可以是MySQL,MongoDB,Elasticsearch或任何其他受支持的數(shù)據(jù)庫(kù)。 Spring Data JPA的其他優(yōu)點(diǎn)包括:
- 支持根據(jù)JPA公約建立擴(kuò)展存儲(chǔ)庫(kù)
- 內(nèi)置分頁(yè)支持和動(dòng)態(tài)查詢執(zhí)行
- 支持基于XML的實(shí)體映射
在此示例中,我們將使用H2內(nèi)存數(shù)據(jù)庫(kù)。 數(shù)據(jù)庫(kù)的選擇不應(yīng)影響我們將構(gòu)建的Spring Data定義,因?yàn)檫@是Spring Data JPA提供的主要優(yōu)點(diǎn)。 它使我們能夠?qū)?shù)據(jù)庫(kù)查詢與應(yīng)用程序邏輯完全分開(kāi)。
2.項(xiàng)目設(shè)置
我們將使用許多Maven原型之一為我們的示例創(chuàng)建一個(gè)示例項(xiàng)目。 要?jiǎng)?chuàng)建項(xiàng)目,請(qǐng)?jiān)趯⒂米鞴ぷ骺臻g的目錄中執(zhí)行以下命令:
mvn archetype:generate -DgroupId=com.javacodegeeks.example -DartifactId=JCG-SpringDataJPA-example -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false如果您是第一次運(yùn)行maven,則完成生成命令將花費(fèi)幾秒鐘,因?yàn)閙aven必須下載所有必需的插件和工件才能完成生成任務(wù)。
使用Maven的JPA項(xiàng)目設(shè)置
請(qǐng)注意,現(xiàn)在,您將在所選目錄中擁有一個(gè)與artifactId同名的新目錄。 現(xiàn)在,隨時(shí)在您喜歡的IDE中打開(kāi)項(xiàng)目。
最后,我們使用一個(gè)簡(jiǎn)單的maven命令來(lái)代替使用IDE來(lái)創(chuàng)建該項(xiàng)目。 這有助于我們使項(xiàng)目設(shè)置和初始化不受您可能使用的任何特定IDE的影響。
3. Maven依賴
首先,我們需要在項(xiàng)目中添加適當(dāng)?shù)腗aven依賴項(xiàng)。 我們將以下依賴項(xiàng)添加到我們的pom.xml文件中:
pom.xml
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.10.RELEASE</version><relativePath/> <!-- lookup parent from repository --> </parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version> </properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins> </build>在此處找到與Spring相關(guān)的最新依賴項(xiàng)。
請(qǐng)注意,我們還在此處添加了H2數(shù)據(jù)庫(kù)依賴關(guān)系及其范圍(作為運(yùn)行時(shí)),因?yàn)橐坏?yīng)用程序停止運(yùn)行,H2數(shù)據(jù)就會(huì)被沖走。 在本課程中,我們將不會(huì)關(guān)注H2的實(shí)際工作原理,而是將自己局限于Spring Data JPA API。 您可能還會(huì)看到我們?nèi)绾问褂肧pring應(yīng)用程序配置嵌入式H2控制臺(tái) 。
4.項(xiàng)目結(jié)構(gòu)
在繼續(xù)進(jìn)行并開(kāi)始處理該項(xiàng)目的代碼之前,讓我們?cè)诖私榻B一下將所有代碼添加到項(xiàng)目后將擁有的projet結(jié)構(gòu):
項(xiàng)目結(jié)構(gòu)
我們將項(xiàng)目分為多個(gè)包,以便遵循關(guān)注點(diǎn)分離的原則,并且代碼保持模塊化。
5.定義模型
我們將在我們的項(xiàng)目中添加一個(gè)非常簡(jiǎn)單的模型Person 。 它的定義將非常標(biāo)準(zhǔn),例如:
人.java
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id;@Entity public class Person {@Id@GeneratedValueprivate Long id;private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}//standard getters and setters@Overridepublic String toString() {return String.format("Person{id=%d, name='%s', age=%d}", id, name, age);} }為了簡(jiǎn)潔起見(jiàn),我們省略了標(biāo)準(zhǔn)的getter和setter方法,但是由于Jackson在對(duì)象的序列化和反序列化過(guò)程中使用它們,因此必須將它們制成。
@Entity注釋將該P(yáng)OJO標(biāo)記為對(duì)象,該對(duì)象將由Spring Data API管理,并且其字段將被視為表列(除非標(biāo)記為transient )。
最后,我們?yōu)閠oString()方法添加了一個(gè)自定義實(shí)現(xiàn),以便在測(cè)試應(yīng)用程序時(shí)可以打印相關(guān)數(shù)據(jù)。
6.定義JPA存儲(chǔ)庫(kù)
JPA為我們提供了一種非常簡(jiǎn)單的定義JPA存儲(chǔ)庫(kù)接口的方法。
在了解如何定義JPA信息庫(kù)之前,我們需要記住,只有在利用與JPA相關(guān)的功能時(shí),才使每個(gè)JPA接口與數(shù)據(jù)庫(kù)表的單個(gè)實(shí)體進(jìn)行交互。 如果我們看一下接口定義,我們將對(duì)此有深刻的理解:
PersonRepository.java
import com.javacodegeeks.jpaexample.model.Person; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository;@Repository public interface PersonRepository extends JpaRepository<Person, Long> { }盡管上面的接口定義是空的,但我們?nèi)匀恍枰私庖恍┮c(diǎn):
- @Repository批注將此接口標(biāo)記為Spring Bean,該Bean在應(yīng)用程序啟動(dòng)時(shí)初始化。 借助此注釋,Spring可以管理異常數(shù)據(jù)庫(kù)交互引發(fā)的正常運(yùn)行
- 我們使用Person作為參數(shù)來(lái)表示此JPA接口將管理Person實(shí)體
- 最后,我們還傳遞了數(shù)據(jù)類型Long作為參數(shù)。 這表示Person實(shí)體包含唯一標(biāo)識(shí)符,其類型為L(zhǎng)ong
7.制作服務(wù)界面
在本節(jié)中,我們將定義一個(gè)服務(wù)接口,該接口將充當(dāng)實(shí)現(xiàn)的合同,并重新表達(dá)我們的服務(wù)必須支持的所有操作。 這些動(dòng)作將與結(jié)交新用戶以及獲取與數(shù)據(jù)庫(kù)中對(duì)象有關(guān)的信息有關(guān)。
這是我們將使用的合同定義:
PersonService.java
import com.javacodegeeks.jpaexample.model.Person; import java.util.List;public interface PersonService {Person createPerson(Person person);Person getPerson(Long id);Person editPerson(Person person);void deletePerson(Person person);void deletePerson(Long id);List getAllPersons(int pageNumber, int pageSize);List getAllPersons();long countPersons(); }我們?cè)谠摵贤刑岬搅怂兴膫€(gè)CRUD操作以及分頁(yè)概念。
當(dāng)我們引入基于pageSize和pageNumber從數(shù)據(jù)庫(kù)中獲取所有對(duì)象時(shí),使用分頁(yè)API很重要。 pageSize屬性表示從數(shù)據(jù)庫(kù)中獲取的對(duì)象數(shù),而pageNumber屬性用作查詢的跳過(guò)部分。 有關(guān)Spring分頁(yè)如何工作的詳細(xì)課程,請(qǐng)閱讀本課程 。
8.提供服務(wù)實(shí)施
我們將使用上面的接口定義來(lái)提供其實(shí)現(xiàn),以便我們可以執(zhí)行與我們先前定義的Person實(shí)體相關(guān)的CRUD操作。 我們將在這里執(zhí)行:
PersonServiceImpl.java
import com.javacodegeeks.jpaexample.model.Person; import com.javacodegeeks.jpaexample.repository.PersonRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service;import java.util.List;@Service public class PersonServiceImpl implements PersonService {@Autowiredprivate PersonRepository personRepository;@Overridepublic Person createPerson(Person person) {return personRepository.save(person);}@Overridepublic Person getPerson(Long id) {return personRepository.findOne(id);}@Overridepublic Person editPerson(Person person) {return personRepository.save(person);}@Overridepublic void deletePerson(Person person) {personRepository.delete(person);}@Overridepublic void deletePerson(Long id) {personRepository.delete(id);}@Overridepublic List<Person> getAllPersons(int pageNumber, int pageSize) {return personRepository.findAll(new PageRequest(pageNumber, pageSize)).getContent();}@Overridepublic List<Person> getAllPersons() {return personRepository.findAll();}@Overridepublic long countPersons() {return personRepository.count();} }令人驚訝的是,所有方法實(shí)現(xiàn)都只是一行代碼。 這顯示了JPA存儲(chǔ)庫(kù)提供給我們的抽象級(jí)別。
上面的大多數(shù)操作都很容易理解。 需要注意的主要事情是,我們從未在存儲(chǔ)庫(kù)中提供過(guò)像getAllPersons()等那樣的任何方法! 那么這些方法是如何一起出現(xiàn)的呢? 答案還是在于JPA存儲(chǔ)庫(kù)提供給我們的抽象。 所有方法(如findAll() , delete() , save(...)等)都內(nèi)置在我們?cè)诖鎯?chǔ)庫(kù)接口定義中擴(kuò)展的JpaRepository中。
9.使用CommandLineRunner
為了測(cè)試我們現(xiàn)在編寫(xiě)的收費(fèi)代碼以及數(shù)據(jù)庫(kù)交互部分,我們將在Spring Boot應(yīng)用程序的主類中使用CommandLineRunner 。 CommandLineRunner在Spring Boot應(yīng)用程序的main()方法被調(diào)用之前運(yùn)行,因此,它是執(zhí)行任何初始化步驟或測(cè)試代碼的理想空間。
為了測(cè)試應(yīng)用程序,我們將使用服務(wù)bean在我們的類中執(zhí)行數(shù)據(jù)庫(kù)操作:
pom.xml
import com.javacodegeeks.jpaexample.model.Person; import com.javacodegeeks.jpaexample.service.PersonService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class DataJpaApp implements CommandLineRunner {private static final Logger LOG = LoggerFactory.getLogger("JCG");@Autowiredprivate PersonService service;public static void main(String[] args) {SpringApplication.run(DataJpaApp.class, args);}@Overridepublic void run(String... strings) {LOG.info("Current objects in DB: {}", service.countPersons());Person person = service.createPerson(new Person("Shubham", 23));LOG.info("Person created in DB : {}", person);LOG.info("Current objects in DB: {}", service.countPersons());person.setName("Programmer");Person editedPerson = service.editPerson(person);LOG.info("Person edited in DB : {}", person);service.deletePerson(person);LOG.info("After deletion, count: {}", service.countPersons());} }在上面的示例代碼中,我們只是簡(jiǎn)單地調(diào)用了我們?cè)诜?wù)中創(chuàng)建的一些重要方法,例如創(chuàng)建了一些數(shù)據(jù)并在以后的方法調(diào)用中對(duì)其進(jìn)行了訪問(wèn)。
現(xiàn)在,我們最終將使用Maven本身運(yùn)行我們的項(xiàng)目(再次獨(dú)立于任何IDE來(lái)運(yùn)行我們的項(xiàng)目)。
10.運(yùn)行應(yīng)用程序
使用maven可以輕松運(yùn)行應(yīng)用程序,只需使用以下命令:
運(yùn)行應(yīng)用程序
mvn spring-boot:run一旦運(yùn)行項(xiàng)目,我們將看到以下輸出:
數(shù)據(jù)JPA項(xiàng)目輸出
如預(yù)期的那樣,我們首先創(chuàng)建了一些樣本數(shù)據(jù),并通過(guò)調(diào)用count()方法調(diào)用對(duì)其進(jìn)行了確認(rèn)。 最后,我們刪除了數(shù)據(jù),并再次通過(guò)count()方法調(diào)用進(jìn)行了確認(rèn)。
11.下載源代碼
這是Spring Boot和Spring Data JPA API以及內(nèi)存中H2數(shù)據(jù)庫(kù)的示例。
下載您可以在此處下載此示例的完整源代碼: Spring Data JPA示例
翻譯自: https://www.javacodegeeks.com/2018/03/spring-data-jpa-example-with-spring-boot.html
總結(jié)
以上是生活随笔為你收集整理的Spring Boot的Spring Data JPA示例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 思科路由器模拟器思科模拟软件如何配置路由
- 下一篇: Spring Security with