热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:来说说JPAHibernateSpringDataJPA之间的什么关系?

篇首语:本文由编程笔记#小编为大家整理,主要介绍了来说说JPAHibernateSpringDataJPA之间的什么关系?相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了来说说JPAHibernateSpring Data JPA之间的什么关系?相关的知识,希望对你有一定的参考价值。




目录
  • JPA
  • Hibernate
  • Spring Data JPA
  • 实践

来说说JPA、Hibernate、Spring Data JPA之间的什么关系

Java 持久层框架访问数据库的方式大致分为两种:一种以 SQL 核心,封装一定程度的 JDBC 操作,比如: MyBatis。另一种是以 Java 实体类为核心,将实体类的和数据库表之间建立映射关系,也就是我们说的ORM框架,如:Hibernate、Spring Data JPA。


JPA

Spring Data JPA是建立的JPA的基础之上, 那到底什么是JPA呢?

我们都知道不同的数据库厂商都有自己的实现类,后来统一规范也就有了数据库驱动,Java在操作数据库的时候,底层使用的其实是JDBC,而JDBC是一组操作不同数据库的规范。我们的Java应用程序,只需要调用JDBC提供的API就可以访问数据库了,而JPA也是类似的道理。

JPA全称为Java Persistence API(Java持久层API),它是Sun公司在JavaEE 5中提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具,来管理Java应用中的关系数据,JPA吸取了目前Java持久化技术的优点,旨在规范、简化Java对象的持久化工作。很多ORM框架都是实现了JPA的规范,如:Hibernate、EclipseLink。

需要注意的是JPA统一了Java应用程序访问ORM框架的规范。

JPA为我们提供了以下规范:



  1. ORM映射元数据:JPA支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。



  2. JPA 的API:用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发人员不用再写SQL了。



  3. JPQL查询语言:通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。




Hibernate

Hibernate是Java中的对象关系映射解决方案。对象关系映射或ORM框架是将应用程序数据模型对象映射到关系数据库表的技术。Hibernate 不仅关注于从 Java 类到数据库表的映射,也有 Java 数据类型到 SQL 数据类型的映射。

Hibernate 和 JPA是什么关系呢

上面我们介绍到JPA是Java EE 5规范中提出的Java持久化接口,而Hibernate是一个ORM框架

JPA和Hibernate的关系:

• JPA是一个规范,而不是框架

• Hibernate是JPA的一种实现,是一个框架

Spring Data是啥

Spring Data是Spring 社区的一个子项目,主要用于简化数据(关系型&非关系型)访问,其主要目标是使得数据库的访问变得方便快捷。

• 它提供很多模板操作

– Spring Data Elasticsearch

– Spring Data MongoDB

– Spring Data Redis

– Spring Data Solr

• 强大的 Repository 和定制的数据储存对象的抽象映射

• 对数据访问对象的支持


Spring Data JPA

Spring Data JPA是在实现了JPA规范的基础上封装的一套 JPA 应用框架,虽然ORM框架都实现了JPA规范,但是在不同的ORM框架之间切换仍然需要编写不同的代码,而使用Spring Data JPA能够方便大家在不同的ORM框架之间进行切换而不需要更改代码。Spring Data JPA旨在通过将统一ORM框架的访问持久层的操作,来提高开发人的效率。


Spring Data JPA和Hibernate的关系

Hibernate其实是JPA的一种实现,而Spring Data JPA是一个JPA数据访问抽象。也就是说Spring Data JPA不是一个实现或JPA提供的程序,它只是一个抽象层,主要用于减少为各种持久层存储实现数据访问层所需的样板代码量。但是它还是需要JPA提供实现程序,其实Spring Data JPA底层就是使用的 Hibernate实现。

总结就是:

• Hibernate是JPA的一种实现,是一个框架

• Spring Data JPA是一种JPA的抽象层,底层依赖Hibernate


实践

理论一定要与实践相结合

1、首先,我们需要配置pom.xml


mysql
mysql-connector-java



org.springframework.boot
spring-boot-starter-data-jpa

2、然后是application.properties 的配置

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/数据库名字?useUnicode=true&characterEncoding=utf-8&serverTimezOne=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=create
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true

这里重点简单介绍下spring.jpa.properties.hibernate.hbm2ddl.auto有几种配置:



  • create:表示每次加载Hibernate时都会删除上一次生成的表(包括数据),然后重新生成新表,即使两次没有任何修改也会这样执行。适用于每次执行单测前清空数据库的场景。



  • create-drop:表示每次加载Hibernate时都会生成表,但当SessionFactory关闭时,所生成的表将自动删除。



  • update:最常用的属性值,第一次加载Hibernate时创建数据表(前提是需要先有数据库),以后加载Hibernate时不会删除上一次生成的表,会根据实体更新,只新增字段,不会删除字段(即使实体中已经删除)。



  • validate:每次加载Hibernate时都会验证数据表结构,只会和已经存在的数据表进行比较,根据model修改表结构,但不会创建新表。



  • 不配置此项,表示禁用自动建表功能



spring.jpa.show-sql=true 该配置当在执行数据库操作的时候会在控制台打印 sql 语句,方便我们检查排错等。

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 这是数据库的方言配置。

3、接下来我们建立用户实体类

@Entity
public class User {

@Id
@GeneratedValue
private long id;
@Column(nullable = false, unique = true)
private String userName;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private int age;
}

这里的一些注解解释如下:



  • @Entity 是一个类注解,用来注解该类是一个实体类用来进行和数据库中的表建立关联关系,首次启动项目的时候,默认会在数据中生成一个同实体类相同名字的表(table),也可以通过注解中的 name 属性来修改表(table)名称, 如@Entity(name=“user”) , 这样数据库中表的名称则是 user。该注解十分重要,如果没有该注解首次启动项目的时候你会发现数据库没有生成对应的表。



  • @Table 注解也是一个类注解,该注解可以用来修改表的名字,该注解完全可以忽略掉不用,@Entity 注解已具备该注解的功能。



  • @Id 类的属性注解,该注解表明该属性字段是一个主键,该属性必须具备,不可缺少。



  • @GeneratedValue 该注解通常和 @Id 主键注解一起使用,用来定义主键的呈现形式,该注解通常有多种使用策略,先总结如下:



  • @GeneratedValue(strategy= GenerationType.IDENTITY) 该注解由数据库自动生成,主键自增型,在 mysql 数据库中使用最频繁,oracle 不支持。



  • @GeneratedValue(strategy= GenerationType.AUTO) 主键由程序控制,默认的主键生成策略,oracle 默认是序列化的方式,mysql 默认是主键自增的方式。



  • @GeneratedValue(strategy= GenerationType.SEQUENCE) 根据底层数据库的序列来生成主键,条件是数据库支持序列,Oracle支持,Mysql不支持。



  • @GeneratedValue(strategy= GenerationType.TABLE) 使用一个特定的数据库表格来保存主键,较少使用。



  • @Column 是一个类的属性注解,该注解可以定义一个字段映射到数据库属性的具体特征,比如字段长度,映射到数据库时属性的具体名字等。



  • @Transient 是一个属性注解,该注解标注的字段不会被映射到数据库当中。



4、声明 UserRepository接口,继承JpaRepository,如下所示

public interface UserRepository extends JpaRepository {

}

这里的 JpaRepository继承了接口PagingAndSortingRepositoryQueryByExampleExecutor。而PagingAndSortingRepository又继承CrudRepository

因此,JpaRepository接口同时拥有了基本CRUD功能以及分页功能。因此,这里我们可以继承JpaRepository,从而获得Spring为我们预先定义的多种基本数据操作方法。

5、然后我们定义一个测试类, 这里我们演示下添加操作, @Transactional 表示开启事务防止出现脏数据。

……
@Autowired
private UserRepository userRepository;

@Test
@Transactional
public void userAddTest() {
User user = new User();
user.setUserName("李嘉图");
user.setAge(30);
user.setPassword("123456");
userRepository.save(user);
User item = userRepository.findByUserName("ljt");
log.info(JsonUtils.toJson(item));
}

6、接下来我们说下查询,查询可以分为基本查询和自定义查询,一种是 spring data 默认已经实现,只需要要继承JpaRepository,一种是根据查询的方法来自动解析成 SQL

@Test
public void testQuery() throws Exception {
User user=new User();
userRepository.findAll();
userRepository.findOne(1l);
userRepository.save(user);
userRepository.delete(user);
userRepository.count();
userRepository.exists(1l);
……
}

7、自定义的简单查询就是根据方法名来自动生成SQL,主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy后面跟属性名称,举几个例子:

User findByUserName(String userName);

User findByUserNameOrEmail(String username, String email);

Long deleteById(Long id);

Long countByUserName(String userName);

List findByEmailLike(String email);

User findByUserNameIgnoreCase(String userName);

List findByUserNameOrderByEmailDesc(String email);

8、接下来,我们说下复杂的查询,在实际的开发中我们需要用到分页、删选、连表等查询的时候就需要特殊的方法或者自定义 SQL

以分页查询为例,分页查询在实际使用中非常普遍了,spring data jpa已经帮我们实现了分页的功能,在查询的方法中,需要传入参数Pageable,当查询中有多个参数的时候Pageable建议做为最后一个参数传入。Pageablespring 封装的分页实现类,使用的时候需要传入页数、每页条数和排序规则。

Page findALL(Pageable pageable);

Page findByUserName(String userName,Pageable pageable);

9、我们看下下面的测试用例

@Test
public void testPageQuery() throws Exception {
int page=1,size=5;
Sort sort = new Sort(Direction.DESC, "id");
Pageable pageable = new PageRequest(page, size, sort);
userRepository.findALL(pageable);
userRepository.findByUserName("testName", pageable);
}

Spring data大部分的SQL都可以根据方法名定义的方式来实现,但是由于某些原因我们想使用自定义的 SQL来查询,spring data 也是完美支持的,如下所示:

@Modifying
@Query("update User u set u.userName = ?1 where c.id = ?2")
int modifyByIdAndUserId(String userName, Long id);

@Transactional
@Modifying
@Query("delete from User where id = ?1")
void deleteByUserId(Long id);

@Transactional(timeout = 10)
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);


推荐阅读
  • 初探PLC 的ST 语言转换成C++ 的方法
    自动控制软件绕不开ST(StructureText)语言。它是IEC61131-3标准中唯一的一个高级语言。目前,大多数PLC产品支持ST ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • 项目运行环境配置及可行性分析
    本文介绍了项目运行环境配置的要求,包括Jdk1.8、Tomcat7.0、Mysql、HBuilderX等工具的使用。同时对项目的技术可行性、操作可行性、经济可行性、时间可行性和法律可行性进行了分析。通过对数据库的设计和功能模块的设计,确保系统的完整性和安全性。在系统登录、系统功能模块、管理员功能模块等方面进行了详细的介绍和展示。最后提供了JAVA毕设帮助、指导、源码分享和调试部署的服务。 ... [详细]
  • 一:什么是solrSolr是apache下的一个开源项目,使用Java基于lucene开发的全文搜索服务器;Lucene是一个开放源代 ... [详细]
  • solr导入mysql_Solr导入MySQL中的数据
    一、目标将MySQL数据库中的数据导入至Solr中,并且由Solr生成中文索引,使用Solr查询信息。二、数据导入1、将solr-8.2.0dist下的 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • android ... [详细]
  • java计算机毕业设计springboot+vue信息工程学院学生社团网站
    项目介绍本信息工程学院学生社团平台是针对目前信息工程学院学生社团的实际需求,从实际工作出发,对过去的信息工程学院学生社团平台存在的问题进行分析 ... [详细]
  • 芝兰生于幽谷,不因无人而不芳随想的夜晚2013822
    为什么80%的码农都做不了架构师?昨晚和今晚敲完了string.py的源代码,有两个类看不懂:Template和Formatter& ... [详细]
author-avatar
喵喵-浩_174
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有