创建项目
创建的过程和我们的第一篇文章:
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
联系作者
领取专属 10元无门槛券
私享最新 技术干货