javascript
Spring休眠教程
1.簡介
在本文中,我們將演示如何利用最流行的ORM(對象關系映射)工具之一的Hibernate的功能 ,該工具可將面向對象的域模型轉換為傳統的關系數據庫。 Hibernate是目前最流行的Java框架之一。 由于這個原因,我們在Java Code Geeks上提供了很多教程,其中大多數可以在此處找到。
在本課中,我們將創建一個基于Spring Boot的簡單應用程序,它將利用Hibernate配置和Spring Data JPA的功能。 我們將使用H2內存數據庫。 數據庫的選擇不應影響我們將構建的Spring Data定義,因為這是Hibernate和Spring Data JPA提供的主要優點。 它使我們能夠將數據庫查詢與應用程序邏輯完全分開。
2.制作Spring Boot項目
在本課中,我們將使用最流行的Web工具之一來制作示例項目,并且不會從命令行執行它,而是使用Spring Initializr 。 只需在瀏覽器中打開鏈接并進行瀏覽即可。 要設置我們的項目,我們使用以下配置:
Spring Initializr配置
我們在此工具中添加了三個依賴項:
- Web :這是一個基本的Spring依賴關系,它將與配置有關的注釋和基本注釋收集到項目中。
- H2 :由于我們使用內存數據庫,因此需要這種依賴性。
- Data JPA :我們將在數據訪問層中使用Spring Data JPA。
接下來,解壓縮下載的zip項目并將其導入您喜歡的IDE。
3. Maven依賴
首先,我們需要查看該工具將哪些Maven依賴項添加到了我們的項目中,以及需要哪些其他依賴項。 我們將對pom.xml文件具有以下依賴性:
pom.xml
<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>org.hibernate</groupId><artifactId>hibernate-search-orm</artifactId><version>5.6.1.Final</version> </dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</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>在此處找到與Spring相關的最新依賴項。 我們添加了也需要執行Hibernate搜索的依賴項。
請注意,我們還在此處添加了H2數據庫依賴關系及其范圍(作為運行時),因為一旦應用程序停止運行,H2數據就會被沖走。 在本課程中,我們將不關注H2的實際工作原理,而將自己局限于Hibernate配置。 您可能還會看到我們如何使用Spring應用程序配置嵌入式H2控制臺 。
最后,要了解添加此依賴項時添加到項目中的所有JAR,我們可以運行一個簡單的Maven命令,當我們向其添加一些依賴項時,該命令使我們能夠查看項目的完整依賴關系樹。 這是我們可以使用的命令:
檢查依賴樹
mvn dependency:tree當我們運行此命令時,它將向我們顯示以下依賴關系樹:
依賴樹
[INFO] --------< com.javacodegeeks.example:JCG-BootHibernate-Example >--------- [INFO] Building JCG-BootHibernate-Example 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ JCG-BootHibernate-Example --- [INFO] com.javacodegeeks.example:JCG-BootHibernate-Example:jar:1.0-SNAPSHOT [INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:1.5.6.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter:jar:1.5.6.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot:jar:1.5.6.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:1.5.6.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:1.5.6.RELEASE:compile [INFO] | | | +- ch.qos.logback:logback-classic:jar:1.1.11:compile [INFO] | | | | \- ch.qos.logback:logback-core:jar:1.1.11:compile [INFO] | | | +- org.slf4j:jul-to-slf4j:jar:1.7.25:compile [INFO] | | | \- org.slf4j:log4j-over-slf4j:jar:1.7.25:compile [INFO] | | \- org.yaml:snakeyaml:jar:1.17:runtime [INFO] | +- org.springframework.boot:spring-boot-starter-aop:jar:1.5.6.RELEASE:compile [INFO] | | +- org.springframework:spring-aop:jar:4.3.10.RELEASE:compile [INFO] | | \- org.aspectj:aspectjweaver:jar:1.8.10:compile [INFO] | +- org.springframework.boot:spring-boot-starter-jdbc:jar:1.5.6.RELEASE:compile [INFO] | | +- org.apache.tomcat:tomcat-jdbc:jar:8.5.16:compile [INFO] | | | \- org.apache.tomcat:tomcat-juli:jar:8.5.16:compile [INFO] | | \- org.springframework:spring-jdbc:jar:4.3.10.RELEASE:compile [INFO] | +- org.hibernate:hibernate-core:jar:5.0.12.Final:compile [INFO] | | +- antlr:antlr:jar:2.7.7:compile [INFO] | | \- org.jboss:jandex:jar:2.0.0.Final:compile [INFO] | +- javax.transaction:javax.transaction-api:jar:1.2:compile [INFO] | +- org.springframework.data:spring-data-jpa:jar:1.11.6.RELEASE:compile [INFO] | | +- org.springframework.data:spring-data-commons:jar:1.13.6.RELEASE:compile [INFO] | | +- org.springframework:spring-orm:jar:4.3.10.RELEASE:compile [INFO] | | +- org.springframework:spring-context:jar:4.3.10.RELEASE:compile [INFO] | | +- org.springframework:spring-tx:jar:4.3.10.RELEASE:compile [INFO] | | +- org.springframework:spring-beans:jar:4.3.10.RELEASE:compile [INFO] | | +- org.slf4j:slf4j-api:jar:1.7.25:compile [INFO] | | \- org.slf4j:jcl-over-slf4j:jar:1.7.25:compile [INFO] | \- org.springframework:spring-aspects:jar:4.3.10.RELEASE:compile [INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.5.6.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.5.6.RELEASE:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.16:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.16:compile [INFO] | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.16:compile [INFO] | +- org.hibernate:hibernate-validator:jar:5.3.5.Final:compile [INFO] | | +- javax.validation:validation-api:jar:1.1.0.Final:compile [INFO] | | \- com.fasterxml:classmate:jar:1.3.3:compile [INFO] | +- com.fasterxml.jackson.core:jackson-databind:jar:2.8.9:compile [INFO] | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.0:compile [INFO] | | \- com.fasterxml.jackson.core:jackson-core:jar:2.8.9:compile [INFO] | +- org.springframework:spring-web:jar:4.3.10.RELEASE:compile [INFO] | \- org.springframework:spring-webmvc:jar:4.3.10.RELEASE:compile [INFO] | \- org.springframework:spring-expression:jar:4.3.10.RELEASE:compile [INFO] +- org.hibernate:hibernate-search-orm:jar:5.6.1.Final:compile [INFO] | \- org.hibernate:hibernate-search-engine:jar:5.6.1.Final:compile [INFO] | +- org.apache.lucene:lucene-core:jar:5.5.4:compile [INFO] | +- org.apache.lucene:lucene-misc:jar:5.5.4:compile [INFO] | +- org.apache.lucene:lucene-analyzers-common:jar:5.5.4:compile [INFO] | \- org.apache.lucene:lucene-facet:jar:5.5.4:compile [INFO] | \- org.apache.lucene:lucene-queries:jar:5.5.4:compile [INFO] +- org.hibernate:hibernate-entitymanager:jar:5.0.12.Final:compile [INFO] | +- org.jboss.logging:jboss-logging:jar:3.3.1.Final:compile [INFO] | +- dom4j:dom4j:jar:1.6.1:compile [INFO] | +- org.hibernate.common:hibernate-commons-annotations:jar:5.0.1.Final:compile [INFO] | +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile [INFO] | +- org.javassist:javassist:jar:3.21.0-GA:compile [INFO] | \- org.apache.geronimo.specs:geronimo-jta_1.1_spec:jar:1.1.1:compile [INFO] +- com.h2database:h2:jar:1.4.196:runtime [INFO] \- org.springframework.boot:spring-boot-starter-test:jar:1.5.6.RELEASE:test [INFO] +- org.springframework.boot:spring-boot-test:jar:1.5.6.RELEASE:test [INFO] +- org.springframework.boot:spring-boot-test-autoconfigure:jar:1.5.6.RELEASE:test [INFO] +- com.jayway.jsonpath:json-path:jar:2.2.0:test [INFO] | \- net.minidev:json-smart:jar:2.2.1:test [INFO] | \- net.minidev:accessors-smart:jar:1.1:test [INFO] | \- org.ow2.asm:asm:jar:5.0.3:test [INFO] +- junit:junit:jar:4.12:test [INFO] +- org.assertj:assertj-core:jar:2.6.0:test [INFO] +- org.mockito:mockito-core:jar:1.10.19:test [INFO] | \- org.objenesis:objenesis:jar:2.1:test [INFO] +- org.hamcrest:hamcrest-core:jar:1.3:test [INFO] +- org.hamcrest:hamcrest-library:jar:1.3:test [INFO] +- org.skyscreamer:jsonassert:jar:1.4.0:test [INFO] | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test [INFO] +- org.springframework:spring-core:jar:4.3.10.RELEASE:compile [INFO] \- org.springframework:spring-test:jar:4.3.10.RELEASE:test [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------注意到了什么? 通過向項目中添加四個依賴項,添加了如此多的依賴項。 Spring Boot本身會收集所有相關的依賴項,在這件事上對我們沒有任何幫助。 最大的優點是,所有這些依賴項都可以保證彼此兼容。
4.項目結構
在繼續進行并開始處理項目代碼之前,讓我們在這里介紹完成向項目添加所有代碼后將擁有的項目結構:
休眠項目結構
我們將項目分為多個包,以便遵循關注點分離的原則,并且代碼保持模塊化。
請注意, indexpath目錄是由Hibernate創建的,用于存儲索引(在本課程的后面部分討論),當您在IDE中導入項目時,該目錄將不存在。
5.定義休眠方言
在application.properties文件中,我們定義了項目類路徑上存在的Spring Data JPA使用的兩個屬性。 Spring Boot使用Hibernate作為默認的JPA實現。
application.properties
## Hibernate Properties # The SQL dialect makes Hibernate generate better SQL for the chosen database spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect# Hibernate DDL auto (create, create-drop, validate, update) spring.jpa.hibernate.ddl-auto = updatespring.jpa.hibernate.ddl-auto屬性在這里很重要。 因此,Spring Data將根據我們在項目中定義的實體自動創建數據庫表,而列將由實體的字段構成。 正如我們將屬性設置為update ,每當我們更新Entity類中的字段時,只要重新啟動項目,該字段就會在數據庫中自動更新。
6.定義實體
我們將在我們的項目中添加一個非常簡單的模型Person 。 它的定義將非常標準,例如:
人.java
@Entity @Indexed public class Person {@Id@GeneratedValueprivate Long id;@Field(termVector = TermVector.YES)private String name;@Fieldprivate int age;// standard getters and setters@Overridepublic String toString() {return String.format("Person{id=%d, name='%s', age=%d}", id, name, age);} }為了簡潔起見,我們省略了標準的getter和setter方法,但是由于Jackson在對象的序列化和反序列化過程中使用它們,因此必須將它們制成。
@Entity注釋將此POJO標記為將由Spring Data API管理的對象,并且其字段將被視為表列(除非標記為瞬態),而@Field注釋將此字段標記為Hibernate索引,以便我們可以在這些字段上也運行全文搜索查詢。
最后,我們為toString()方法添加了一個自定義實現,以便在測試應用程序時可以打印相關數據。
7.制作服務接口
在本節中,我們將定義一個服務接口,該接口將充當實現的合同,并代表我們的服務必須支持的所有操作。 這些動作將與結交新用戶以及獲取與數據庫中對象有關的信息有關。
這是我們將使用的合同定義:
PersonService.java
public interface PersonService {Person createPerson(Person person);Person getPerson(Long id);Person editPerson(Person person);void deletePerson(Person person);void deletePerson(Long id);List<Person> getAllPersons(int pageNumber, int pageSize);List<Person> getAllPersons();long countPersons();List<Person> fuzzySearchPerson(String term);List<Person> wildCardSearchPerson(String term); }請注意,合同最后還包括兩種方法,它們也為Hibernate搜索提供支持。
8.實施服務
我們將使用上面的接口定義來提供其實現,以便我們可以執行與我們先前定義的Person實體相關的CRUD操作。 我們將在這里執行:
PersonServiceImpl.java
@Service public class PersonServiceImpl implements PersonService {private final PersonRepository personRepository;private final PersonDAL personDAL;@Autowiredpublic PersonServiceImpl(PersonRepository personRepository, PersonDAL personDAL) {this.personRepository = personRepository;this.personDAL = personDAL;}@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();}@Override@Transactional(readOnly = true)public List<Person> fuzzySearchPerson(String term) {return personDAL.fuzzySearchPerson(term);}@Override@Transactional(readOnly = true)public List<Person> wildCardSearchPerson(String term) {return personDAL.wildCardSearchPerson(term);} }我們只是使用DAL bean訪問我們上面定義的方法。 我們還使用了@Transactional(readOnly = true)批注,這樣我們就不必在執行一些寫操作時就需要打開一個Hibernate會話,但是由于我們只需要執行搜索,因此我們可以放心地提到readOnly屬性設置為true 。
9.定義JPA存儲庫
由于大多數操作都是由JPA Repository本身完成的,因此我們在這里定義它:
PersonRepository.java
@Repository public interface PersonRepository extends JpaRepository<Person, Long> { }盡管上面的接口定義是空的,但我們仍然需要了解一些要點:
- @Repository批注將此接口標記為Spring Bean,該Bean在應用程序啟動時初始化。 有了這個注釋,Spring可以很好地管理異常數據庫的交互拋出
- 我們使用Person作為參數來表示此JPA接口將管理Person實體
- 最后,我們還傳遞了數據類型Long作為參數。 這表示Person實體包含唯一標識符,其類型為Long。
10.定義數據訪問層(DAL)接口
盡管我們已經定義了執行所有CRUD操作的JPA信息庫,但我們仍將在DAL層中定義用于Hibernate自由文本搜索的查詢。 讓我們看一下我們定義的合同:
PersonDAL.java
public interface PersonDAL {List<Person> fuzzySearchPerson(String term);List<Person> wildCardSearchPerson(String term); }11.實現DAL接口
在我們定義的DAL接口中,我們將實現兩種不同類型的自由文本搜索:
- 模糊搜索:當我們要查找與搜索詞相距一定距離的詞時,可以使用模糊搜索。 為了理解差距,讓我們考慮一個例子。 術語Hibernate和Hibernat有1由于缺少差距e在后文中,術語Hibernate和Hibernawe還具有以下在后面的字符串即單個字符1的缺口w可以更換成原字符串。
- 通配符搜索:這些就像具有匹配短語的SQL語句一樣。 像Hibernate匹配短語一樣,可以是Hiber , bernate等。
讓我們在DAL層中實現這兩個功能。
11.1定義模糊查詢
我們將從模糊搜索實現開始。 這是一個非常智能和復雜的搜索,因為這需要對數據庫索引中保存的每個術語進行標記化。 在此處閱讀有關Lucene如何執行此操作的更多信息。
讓我們在這里實現此搜索查詢:
模糊查詢
@PersistenceContext private EntityManager entityManager;@Override public List<Person> fuzzySearchPerson(String term) {FullTextEntityManager fullTextEntityManager =org.hibernate.search.jpa.Search.getFullTextEntityManager(entityManager);QueryBuilder queryBuilder =fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Person.class).get();Query fuzzyQuery = queryBuilder.keyword().fuzzy().withEditDistanceUpTo(2).withPrefixLength(0).onField("name").matching(term).createQuery();FullTextQuery jpaQuery =fullTextEntityManager.createFullTextQuery(fuzzyQuery, Person.class);return jpaQuery.getResultList(); }我們僅使用2的編輯距離。這是Hibernate和Lucene引擎支持的最大間隙。
11.2定義通配符查詢
通配符查詢易于理解和實現。 就像SQL LIKE語句一樣工作:
通配符查詢
@Overridepublic List<Person> wildCardSearchPerson(String term) {FullTextEntityManager fullTextEntityManager =org.hibernate.search.jpa.Search.getFullTextEntityManager(entityManager);QueryBuilder queryBuilder =fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Person.class).get();Query wildcardQuery = queryBuilder.keyword().wildcard().onField("name").matching("*" + term + "*").createQuery();FullTextQuery jpaQuery =fullTextEntityManager.createFullTextQuery(wildcardQuery, Person.class);return jpaQuery.getResultList();}我們在術語的前后??使用* ,以便LIKE可以在兩個方向上使用。
12.在Hibernate中建立搜索索引
在Hibernate開始存儲索引數據之前,我們需要確保搜索索引確實存在。 可以通過在應用程序啟動后立即構造它來完成:
BuildSearchIndex.java
@Component public class BuildSearchIndex implements ApplicationListener<ApplicationReadyEvent> {@PersistenceContextprivate EntityManager entityManager;@Overridepublic void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {try {FullTextEntityManager fullTextEntityManager =Search.getFullTextEntityManager(entityManager);fullTextEntityManager.createIndexer().startAndWait();}catch (InterruptedException e) {System.out.println("An error occurred trying to build the serach index: " +e.toString());}return;} }盡管我們在Hibernate中構造了一個搜索索引,但是索引數據將存儲在哪里。 接下來,我們將對其進行配置。
13.存儲索引數據
由于Hibernate需要存儲Index數據,以便不必在每次執行操作時都重建索引數據,因此我們將為Hibernate提供文件系統目錄,以在其中存儲此數據:
application.properties
# Specify the Lucene Directory spring.jpa.properties.hibernate.search.default.directory_provider = filesystem# Using the filesystem DirectoryProvider you also have to specify the default # base directory for all indexes spring.jpa.properties.hibernate.search.default.indexBase = indexpathdirectory_provider僅提供哪種類型的系統將存儲數據,因為我們甚至可以將索引數據存儲到云中。
14.創建命令行運行器
現在,我們準備運行我們的項目。 將樣本數據插入
DataJpaApp.java
@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());List<Person> fuzzySearchedPersons = service.fuzzySearchPerson("Shubha");LOG.info("Founds objects in fuzzy search: {}", fuzzySearchedPersons.get(0));List<Person> wildSearchedPersons = service.wildCardSearchPerson("hub");LOG.info("Founds objects in wildcard search: {}", wildSearchedPersons.get(0));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());} }15.使用Maven運行項目
使用maven可以輕松運行應用程序,只需使用以下命令:
運行應用程序
mvn spring-boot:run一旦運行項目,我們將看到以下輸出:
運行休眠項目
如預期的那樣,我們首先創建了一些樣本數據,并通過調用count()方法調用對其進行了確認。 最后,調用搜索方法以獲得預期結果。
16.結論
在本課程中,我們研究了如何使用Hibernate配置Spring Data API,以及如何僅通過為實體定義POJO類就可以幫助我們在數據庫中自動構造Tables。 即使更新實體,也不必擔心在數據庫中進行更改!
我們還使用Hibernate搜索運行了一些示例,這些示例由Lucene引擎本身提供了用于索引的功能,而Hibernate為我們提供了有關Lucene功能的有用包裝。
17.下載源代碼
這是Spring Boot和Hibernate ORM Framework的一個示例。
下載您可以在此處下載此示例的完整源代碼: JCG-BootHibernate-Example
翻譯自: https://www.javacodegeeks.com/2018/04/spring-hibernate-tutorial.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Spring休眠教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 6868代表什么意思 6868代表的含义
- 下一篇: 安卓手机照片删除怎么恢复