网站建设企业建站要求,个人做地方网站,互助网站制作公司,建设工程信息平台官网1.简介 在本文中#xff0c;我们将演示如何利用最流行的ORM#xff08;对象关系映射#xff09;工具之一的Hibernate的功能 #xff0c;该工具可将面向对象的域模型转换为传统的关系数据库。 Hibernate是目前最流行的Java框架之一。 由于这个原因#xff0c;我们在Java Co… 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 dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-jpa/artifactId
/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId
/dependencydependencygroupIdorg.hibernate/groupIdartifactIdhibernate-search-orm/artifactIdversion5.6.1.Final/version
/dependencydependencygroupIdorg.hibernate/groupIdartifactIdhibernate-entitymanager/artifactId
/dependencydependencygroupIdcom.h2database/groupIdartifactIdh2/artifactIdscoperuntime/scope
/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/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.项目结构 在继续进行并开始处理项目代码之前让我们在此介绍完成向项目添加所有代码后将拥有的项目结构 Hibernate项目结构 我们将项目分为多个包以便遵循关注点分离的原则并且代码保持模块化。 请注意 indexpath目录是由Hibernate创建的用于存储索引在本课程的后面部分讨论当您在IDE中导入项目时该目录将不存在。 5.定义Hibernate方言 在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 update spring.jpa.hibernate.ddl-auto属性在这里很重要。 因此Spring Data将根据我们在项目中定义的实体自动创建数据库表而列将由实体的字段构成。 正如我们将属性设置为update 每当我们更新Entity类中的字段时只要重新启动项目该字段就会在数据库中自动更新。 6.定义实体 我们将在我们的项目中添加一个非常简单的模型Person 。 它的定义将非常标准例如 人.java Entity
Indexed
public class Person {IdGeneratedValueprivate Long id;Field(termVector TermVector.YES)private String name;Fieldprivate int age;// standard getters and settersOverridepublic 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);ListPerson getAllPersons(int pageNumber, int pageSize);ListPerson getAllPersons();long countPersons();ListPerson fuzzySearchPerson(String term);ListPerson 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 ListPerson getAllPersons(int pageNumber, int pageSize) {return personRepository.findAll(new PageRequest(pageNumber, pageSize)).getContent();}Overridepublic ListPerson getAllPersons() {return personRepository.findAll();}Overridepublic long countPersons() {return personRepository.count();}OverrideTransactional(readOnly true)public ListPerson fuzzySearchPerson(String term) {return personDAL.fuzzySearchPerson(term);}OverrideTransactional(readOnly true)public ListPerson 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 JpaRepositoryPerson, Long {
} 尽管上面的接口定义是空的但我们仍然需要了解一些要点 Repository批注将此接口标记为Spring Bean该Bean在应用程序启动时初始化。 有了这个注释Spring可以很好地管理异常数据库的交互抛出 我们使用Person作为参数来表示此JPA接口将管理Person实体 最后我们还传递了数据类型Long作为参数。 这表示Person实体包含唯一标识符其类型为Long。 10.定义数据访问层DAL接口 尽管我们已经定义了执行所有CRUD操作的JPA信息库但我们仍将在DAL层中定义用于Hibernate自由文本搜索的查询。 让我们看看我们定义的合同 PersonDAL.java public interface PersonDAL {ListPerson fuzzySearchPerson(String term);ListPerson 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 ListPerson 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 ListPerson 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 ApplicationListenerApplicationReadyEvent {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 indexpath directory_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());ListPerson fuzzySearchedPersons service.fuzzySearchPerson(Shubha);LOG.info(Founds objects in fuzzy search: {}, fuzzySearchedPersons.get(0));ListPerson 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 一旦运行项目我们将看到以下输出 运行Hibernate项目 如预期的那样我们首先创建了一些样本数据并通过调用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