首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Spring Boot简明教程之数据访问(二):JPA(超详细

创建项目

创建的过程和我们的第一篇文章:

SpringBoot简明教程之快速创建第一个SpringBoot应用

大致相同,差别只是我们在挑选所需要的组件时,除了Web组件外,我们需要添加如下三个组件:

或者,我们按照第一次创建完成后,手动在pom.xml文件中加入以下配置:

我们发现,与我们直接使用JDBC template不同的是,这次我们引入了一个新的包:,我们进一步查看,就会发现,其主要是引入了一个的包。

Spring Data简介

Spring Data是为了简化构建基于 Spring 框架应用的数据访问技术,包括关系、非关系数据库、云数据服务等等。SpringData为我们提供使用统一的API来对数据访问层进行操作,让我们在使用关系型或者非关系型数据访问技术时都基于Spring提供的统一标准,标准包含了CRUD(创建、获取、更新、删除)、查询、排序和分页的相关操作,同时为我们提供了统一的数据访问类的模板,例如:MongoTemplate、RedisTemplate等。

JPA简介

JPA(Java Persistence API)定义了一系列对象持久化的标准,它的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术,目前实现了这一规范的有 Hibernate、TopLink、JDO 等 ORM 框架。

Spring Data 与JPA

我们可以将Spring-data-jpa理解为Spring Boot对于JPA的再次封装,使得我们通过Spring-data-jpa即实现常用的数据库操作:

JpaRepository实现基本功能: 编写接口继承JpaRepository既有crud及分页等基本功能

定义符合规范的方法命名: 在接口中只需要声明符合规范的方法,即拥有对应的功能

支持自定义查询: @Query自定义查询,定制查询SQL

Specifications查询(Spring Data JPA支持JPA2.0的Criteria查询)

使用Spring Data JPA的基本流程

创建实体类(entity)

创建Dao层(Repository)

编写配置文件

创建Controller

直接启动项目,看到Spring Boot自动帮我们在数据库中自动创建了t_user表:

并且因为我们之前对属相使用了@Transient注解,不进行映射,所以我们看到表中没有字段。现在我们将@Transient注释后,再次启动项目:

就也被成功的创建。

接着,我们尝试着往数据库中插入一条数据,我们在浏览器中输入:

再到数据库中进行查看:

插入成功。

现在我们来查询刚刚插入的数据,浏览器输入:

成功查询到刚才插入的数据,并且我们可以在控制台看到Spring Boot为我们打印的刚才执行的查询语句:

JPA常用注解说明

虽然我们在上面的示例中已经使用了常用了的注解,但是为了方便和理解,我们在这个地方归纳一下关于JPA的一些常用的注解及其对应的参数。

@Entity:表示该类是一个的实体类。@Entity标注是必需的 ,name属性为可选;需要注意的是:@Entity标注的实体类至少需要有一个无参的构造方法。

@Table:表示该实体类所映射的数据表信息,需要标注在类名前,不能标注在方法或属性前。参数如下:

@Column:表示该属性所映射的字段,此标记可以标注在Getter方法或属性前。它有如下参数:

@Id:表示该属性为主键,每一个实体类至少要有一个主键(Primary key)。

@Basic: 实体属性设置加载方式为惰性加载

自定义查询

我们刚刚在上面使用的是JPA已经封装好的一些默认的查询方式,但是我们在实际的项目中,可能需要自定义一些符合实际需求的查询,那么我们就需要用到自定义查询。

关键字查询

JPA已经帮我们做好了关键字,我们只需要将这些关键字组成方法名,就可以实现相对应的查询。

我们除了使用关键字以外,还可以使用、、等。

例如,我们在Controller中加入如下方法得:

在userRepository中加入如下方法:

在数据库中插入下面两条数据:

在浏览器输入:

我们就可以看到返回了如下数据,查询成功。

自定义SQL语句

通常如果使用JPA提供给我们的关键字组成的查询方法仍然无法满足需求,那么我们就可以使用来实现自定的SQL语句。

原生SQL

JPA中支持使用原生的SQL语句,例如:

在userRepository中加入下面的方法:

在controller中加入以下方法:

在浏览器中输入:

返回数据,查询成功

但是,如果我们需要执行、操作时,除了使用外,还需要使用、

两个注解。

例如:

在userRepository中加入下面的方法:

在controller中加入以下方法:

在浏览器中输入:,我们就会发现数据库中phone为456的数据就已经被删除了。

JPQL查询

在userRepository中加入下面的方法:

在controller中加入以下方法:

浏览器输入:,数据返回,查询成功:

复杂查询

分页查询

我们经常会遇到进行分页查询的情况,而JPA就很好的替我们解决了这一个问题。只需要几行代码就可以解决:

例如:在controller中加入以下方法:

浏览器输入:

返回的数据格式为:

限制查询

除了限制查询以外,对于排行榜类的数据,或许我们只需要取出前面几名即可,Jpa也对这种情况做了很好的支持:

例如:在userRepository中加入下面的方法:

在controller中加入以下方法:

在浏览器输入:

返回的数据为:

常见问题及其解决方案:

如果提示:No identifier specified for entity: xxx

解决方案:这是因为在创建实体类时,导入的jar包错误导致的。我们将更改为:即可

如果提示: No default constructor for entity: :

解决方案:这是因为在实体类中创建了含参数的构造方法造成的,这是因为在使用类反射机制 Class.newInstance()方法创建实例时,需要有一个默认的无参数构造方法,否则会执出实例化异常(InstantiationException),所以将构造方法更改为无参数即可。

如果提示:Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query

解决方案:这是因为在JPA中执行DELETE/UPDATE操作时,需要使用、

两个注解,补上即可。

如果提示:Can not issue data manipulation statements with executeQuery()。

解决方案:如果提示这个错误,就需要查询检查自己的SQL语句是否书写正确,如果正确,检查是否加上、两个注解

如果提示:Ambiguous handler methods mapped for HTTP path

解决方案:这是由于URL映射重复引起的,将你所请求的URL重新进行定义即可。

如果在使用PageRequest方法显示过期

解决方案:将构造方法更改为:PageRequest.of即可。在2.0版本以后,就使用of(…) 方法代替 PageRequest(…)构造器。

总结

我们首先介绍了,然后演示了一遍使用JPA的基本流程,最后详细的介绍了我们主要使用的几个注解、注意事项等;以及除了使用默认的查询方式外,如何去使用自定义查询和复杂查询。

源码地址

https://github.com/cquptrhw/Spring-boot-learning

联系作者

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181011G20B4900?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券