Spring Boot Jpa 介绍
首先了解 Jpa 是什么?
JPA顾名思义就是Java Persistence API的意思,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
Jpa (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范。它为 Java 开发人员提供了一种对象/关联映射工具来管理 Java 应用中的关系数据。它的出现主要是为了简化现有的持久化开发工作和整合 ORM 技术,结束现在 Hibernate,TopLink,JDO 等 ORM 框架各自为营的局面。
值得注意的是,Jpa是在充分吸收了现有 Hibernate,TopLink,JDO 等 ORM 框架的基础上发展而来的,具有易于使用,伸缩性强等优点。从目前的开发社区的反应上看,Jpa 受到了极大的支持和赞扬,其中就包括了 Spring 与 EJB3. 0的开发团队。
注意:Jpa 是一套规范,不是一套产品,那么像 Hibernate,TopLink,JDO 他们是一套产品,如果说这些产品实现了这个 Jpa 规范,那么我们就可以叫他们为 Jpa 的实现产品。
Jpa具有什么优势?
1、标准化 JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。
2、容器级特性的支持 JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。
3、简单方便 JPA的主要目标之一就是提供更加简单的编程模型:在JPA框架下创建实体和创建Java类一样简单,没有任何的约束和限制,只需要使用 javax.persistence.Entity进行注释,JPA的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握。JPA基于非侵入式原则设计,因此可以很容易的和其它框架或者容器集成。
4、查询能力 JPA的查询语言是面向对象而非面向数据库的,它以面向对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物。JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJBQL的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUPBY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
5、 高级特性
JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。
Spring Boot Jpa
Spring Boot Jpa 是 Spring 基于 ORM 框架、Jpa 规范的基础上封装的一套 Jpa 应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data Jpa 可以极大提高开发效率!
Spring Boot Jpa 让我们解脱了 DAO 层的操作,基本上所有 CRUD 都可以依赖于它来实现
1、基于注解的使用
本篇只介绍注解的使用,另一种基于xml方式的使用大家有兴趣可以自行了解一下。
JPA拥有哪些注解呢?
注解 | 解释 |
---|---|
@Entity | 声明类为实体或表。 |
@Table | 声明表名。 |
@Basic | 指定非约束明确的各个字段。 |
@Embedded | 指定类或它的值是一个可嵌入的类的实例的实体的属性。 |
@Id | 指定的类的属性,用于识别(一个表中的主键)。 |
@GeneratedValue | 指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值。 |
@Transient | 指定的属性,它是不持久的,即:该值永远不会存储在数据库中。 |
@Column | 指定持久属性栏属性。 |
@SequenceGenerator | 指定在@GeneratedValue注解中指定的属性的值。它创建了一个序列。 |
@TableGenerator | 指定持久属性栏属性。 |
@Column | 指定在@GeneratedValue批注指定属性的值发生器。它创造了的值生成的表。 |
@AccessType | 指定持久属性栏属性。 |
@Column | 这种类型的注释用于设置访问类型。如果设置@AccessType(FIELD),则可以直接访问变量并且不需要getter和setter,但必须为public。如果设置@AccessType(PROPERTY),通过getter和setter方法访问Entity的变量。 |
@JoinColumn | 指定一个实体组织或实体的集合。这是用在多对一和一对多关联。 |
@UniqueConstraint | 指定的字段和用于主要或辅助表的唯一约束。 |
@ColumnResult | 参考使用select子句的SQL查询中的列名。 |
@ManyToMany | 定义了连接表之间的多对多一对多的关系。 |
@ManyToOne | 定义了连接表之间的多对一的关系。 |
@OneToMany | 定义了连接表之间存在一个一对多的关系。 |
@OneToOne | 定义了连接表之间有一个一对一的关系。 |
@NamedQueries | 指定命名查询的列表。 |
@NamedQuery | 指定使用静态名称的查询。 |
话不多说,开始干!!!
一、添加jpa起步依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
二、配置文件
在application.yml文件中添加如下配置
spring: datasource:
url:jdbc:mysql://localhost:3306/nd-springboot?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver jpa:
hibernate:
#反向数据库配置
ddl-auto: update
#控制台显示执行的sql语句
show-sql: trueserver: port: 8083
JPA配置的ddl-auto属性
ddl-auto 几种属性
create: 每次运行程序时,都会重新创建表,故而数据会丢失
create-drop: 每次运行程序时会先创建表结构,然后待程序结束时清空表
upadte: 每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
validate: 运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
以上我们完成了基本的配置工作,记下来看一下如何进行表与实体的映射,以及数据访问接口。
三、创建实体以及数据访问接口
先来看看实体类User.java
//@Entity(name = “t_user”)//将实体名称改为t_user
@Entity
//@Table(name =“t_user”)//映射表名为t_user 不加这个注解默认就是实体类名 @Data @AllArgsConstructor
@NoArgsConstructor public class User {
@Id
@GeneratedValue //(采用数据库自动增长自动增长)
private Long id;
private String username;
private String password;}
接着是UserRepository.java,改接口只需要继承JpaRepository接口即可。
public interface UserRepository extends JpaRepository<Person, Long> {
}
然后写一个测试类以供测试使用。
@SpringBootTest
class SpringbootDemo2ApplicationTests {
@Autowired
private UserRepository userRepository;
@Test
void contextLoads() {
User user= new User(0L,“二狗子444”,“123”,"");
User userRep = userRepository.save(user); }}
好了,让我们来运行一下程序看看结果吧,启动程序,查询数据库我们就可以看到,JPA以及自动帮我们创建了表
从上面的repository接口代码我们可以看到,接口中并没有定义任何的方法,这是因为JpaRepository中帮我们定义了基础的增删改查方法,可以很方便的直接使用。
2、自定义删除
接下来我们来看一下如何编写自己的方法。我们以根据name来删除
在repository接口中添加如下查询方法:
@Transactional long deleteByUsername(String username);
注意:这里有个坑啊===自定义删除方法,需要加@Transactional
测试如下:
@Test void contextLoads() {
userRepository.deleteByUsername(“二狗子444”);//delete …by 自定义删除方法 }
然后我们去数据库看看效果
删除成功
3、我们再来看看分页
编写repository接口 集成JpaRepository 支持分页、crud、排序、去重、first…
已经集成了分页了所以我们只要写测试类了
这里分页用的数据我已经提前加好了:
看测试类
Pageable pageable = PageRequest.of(1,3, Sort.by(Sort.Order.desc("id")));//分页排序 Page<User> page = userRepository.findAll(pageable); page.forEach(u->{ System.out.println(u); }); System.out.println("总条数:"+page.getTotalElements()); System.out.println("总页数:"+page.getTotalPages()); System.out.println("当前页数:"+page.getPageable().getPageNumber()); System.out.println("每页条数:"+page.getPageable().getPageSize()); System.out.println("================map过滤=============="); page.map((u)->{ if(u.getId()>100){ return u; }else{ return null; } }).forEach(u->{ System.out.println(u); });
运行结果如下
其他就大家就自己自行去尝试吧 机制都差不多
其实JPA在这里遵循Convention over configuration(约定大约配置)的原则,遵循spring
以及JPQL定义的方法命名。Spring提供了一套可以通过命名规则进行查询构建的机制。这套机制会把方法名首先过滤一些关键字,比如 find…By, read…By, query…By, count…By 和 get…By 。系统会根据关键字将命名解析成2个子语句,第一个 By 是区分这两个子语句的关键词。这个 By 之前的子语句是查询子语句(指明返回要查询的对象),后面的部分是条件子语句。如果直接就是 findBy…返回的就是定义Respository时指定的领域对象集合,同时JPQL中也定义了丰富的关键字:and、or、Between等等,
我们来看一下JPQL中有哪些关键字:
Keyword | Sample | JPQL snippet |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age ⇐ ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByStartDateAfter | … where x.age >= ?1 |
After | findByLastnameAndFirstname | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
… | … | … |
在学习这个的时候我还出了一个坑:
@Entity(name=“xx”) 是给实体类取别名
标准用法:@Entity + @Table(name=“表名”)
以上就是jpa的简单实用和介绍。