发布于2021-05-29 22:36 阅读(489) 评论(0) 点赞(11) 收藏(1)
JPA (The Java Persistence API ),即 Java 持久层 API,SUN 公司推出,是一种基于 ORM 的让对象能够快速映射到关系型数据库的技术规范
。JPA 并不是一个框架,只是一种规范,它需要第三方自行实现其功能,在众多框架中 Hibernate 是最为强大的一个,其他的还有TopLink、OpenJPA 和 JDO 等框架。
JPA 的出现主要是为了简化持久层开发以及整合 ORM 技术实现统一,结束Hibernate、TopLink、JDO 等 ORM 框架各自为营的局面。JPA 是在吸收现有 ORM 框架的基础上发展而来,易于使用,伸缩性强。
总的来说,JPA包括以下3方面的技术:
●
ORM 映射元数据
: 支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系
●API
: 操作实体对象来执行CRUD操作
●查询语言
: 通过面向对象而非面向数据库的查询语言(JPQL)查询数据,避免程序的SQL语句紧密耦合
JPA 常用注解
● @
Entity
: 标注用于实体类声明语句之前,指出该Java 类为实体类
,将映射到指定的数据库表。
● @Table
:当实体类类名与其映射的数据库表名不同名时需要使用 @Table 标注说明
,该标注与@Entity 标注并列使用,置于实体类声明语句之前,可写于单独语句行,也可与声明语句同行。@Table 标注的常用选项是 name,用于指明数据库的表名 @Table标注还有一个两个选项 catalog 和 schema 用于设置表所属的数据库目录或模式,通常为数据库名。
● @Basic :表示一个简单的属性到数据库表的字段的映射,可以用在类属性上以及Getter方法上,对于没有任何标注的getXxxx()方法,默认即为 @Basic。@basic注解有两个属性:fetch 属性表示该属性的读取策略,有EAGER和LAZY两种,分别表示急加载和延迟加载,默认为EAGER;optional 属性用来指定属性是否可空。
● @Column
:当实体的属性与其映射的数据库表的列不同名时需要使用@Column 标注说明
,该属性通常置于实体的属性声明语句之前,还可与 @Id 标注一起使用。@Column 标注的常用属性是 name,用于设置映射数据库表的列名。
● @GeneratedValue: 用于标注主键的生成策略
,通过 strategy 属性指定。默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略:SqlServer 对应 identity,MySQL 对应 auto increment。
● @Id
:用于声明一个实体类的属性映射为数据库的主键列
。该属性通常置于属性声明语句之前,可与声明语句同行,也可写在单独行上,也可置于属性的getter方法之前。
● @Transient
:表示该属性并非一个到数据库表的字段的映射
,ORM框架将忽略该属性
。如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic。
● @Temporal:在核心的 Java API 中并没有定义 Date 类型的精度(temporal precision).。而在数据库中,表示 Date 类型的数据有 DATE、TIME 和 TIMESTAMP 三种精度(即单纯的日期、时间或者两者兼备)。在进行属性映射时可使用@Temporal注解来调整精度
.
● @OneToMany
● @ManyToOne
● @ManyToMany
● @Query (Spring Data JPA 用法)
● @Modifying
Spring 是一个大家庭,一个技术的生态圈,其中整合的内容包罗万象。而 Spring Data xxx 系列就是 Spring 这个生态圈对数据持久化层的整合。
Spring Data是Spring用来解决数据访问的解决方案,它包含了大量关系型数据库以及NoSQL数据库的数据持久层访问解决方案。它包含 Spring Data JPA、Spring Data MongoDB、Spring Data Neo4j、Spring Data GernFile 和 Spring Data Cassandra等。
目前现有的 Spring-data-jpa,Spring-data-template,Spring-data-mongodb,Spring-data-redis 等。当然,也包括最开始用的 mybatis-spring ,MyBatis 与 Spring 的整合。于是,就出现了 Spring-data-jpa ,Spring 与 JPA 的整合。
Spring Data JPA是Spring Data家族的一部分,基于 Spring Data 框架、在JPA 规范的基础上开发的一个框架,可以轻松实现基于JPA的存储库,使用 Spring Data JPA 可以极大地简化JPA 的写法。此模块处理对基于JPA的数据访问层的增强支持。 它使构建使用数据访问技术的Spring驱动应用程序变得更加容易。
Spring Data JPA 是采用基于JPA规范的Hibernate框架基础下提供了Repository层的实现。
Spring Data Repository 极大地简化了实现各种持久层的数据库访问而写的样板代码量,同时CrudRepository提供了丰富的CRUD功能去管理实体类。Spring Data JPA 旨在通过减少实际需要的工作量来显著改善数据访问层的实现。作为开发人员,您编写repository接口,可以在几乎不用写实现的情况下实现对数据库的访问和操作,除了CRUD外,还包括自定义查找器方法、分页和排序等一些常用的功能,Spring将自动提供实现。
总的来说 JPA 是 ORM 规范,Hibernate、TopLink等是JPA规范的具体实现,这样的好处是开发者可以面向JPA规范进行持久层的开发,而底层的实现则是可以切换的。Spring Data Jpa则是在JPA之上添加另一层抽象(Repository层的实现),极大地简化持久层开发及ORM框架切换的成本
。
Spring Data JPA也可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现。
JPA默认使用Hibernate作为ORM实现,所以,一般会使用Spring Data JPA就会使用Hibernate
。
在 Java web 项目中,我们经常会看到这个包名或者以它为后缀名的类名,它所代表的是,数据库持久化层,是 Data Access Object 的简写。不过有时候我们也会看到 mapper 等。其实这些都是同一个意思,代表数据库持久化层。
在 JDBCTemplate 中,会用 “dao”;在 MyBatis 中,会用 “mapper”(对应 xxxMapper.xml文件;在 JPA 中,会用"repository"。
其实名称完全是自定义,只不过开发者在开发的时候会有一些约定俗成的习惯,仅此而已。
(1)Repository 接口
最顶层的接口,是一个空的接口,没有定义任何的方法,目的是为了统一所有Repository的类型,且能让组件扫描的时候自动识别。
(2)CrudRepository 接口
CrudRepository 接口继承 Repository 接口,实现了CRUD相关方法
。只需要编写写一个接口类继承这个接口类,不需要实现这个接口就可以完成基本的CRUD操作。因为这个接口会自动为域对象创建增删改查方法,供业务层直接使用。
(3)PagingAndSortingRepository
是 CrudRepository 的子接口,实现了分页和排序的方法
;
(4)QueryByExampleExecutor 接口
(5)JpaRepository 接口
是 PagingAndSortingRepository 的子接口,增加了一些实用的功能,比如:批量操作等。如果业务需要即提供CRUD操作,又需要提供分页以及排序功能,那么就可以直接继承这个接口
。
(6)JpaSpecificationExecutor 接口
用来做负责查询的接口。该接口提供了对JPA Criteria查询的支持。注意,这个接口很特殊,不属于Repository体系,而Spring data JPA不会自动扫描识别,所以会报找不到对应的Bean,我们只需要继承任意一个继承了Repository的子接口或直接继承Repository接口,Spring data JPA就会自动扫描识别,进行统一的管理。
1、使用 Repository 接口默认实现方法
2、关键字
直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字写法如下:
3、JPQL 查询
(1)类似HQL的语法,在接口上使用@Query标识:
@Query("select book from Book book where book.id = ?1")
public Book findById(Integer id);
(2)@Query 与 @Modifying 这两个注解一起声明,可定义个性化更新操作:
@Modifying
@Query("update Book book set book.name = ?1 where book.id < ?2")
public int updateName(String name, Integer id);
(3)也可以使用原生sql,只需要 @Query(nativeQuery=true) 标识即可:
@Query(value="select * from book where name like %?1" ,nativeQuery=true)
public List<Book> testFindByName(String str);
<!--spring-data-jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.23</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
username: root
password: admin
driver-class-name: com.mysql.jdbc.Driver
jpa:
generate-ddl: false
hibernate:
ddl-auto: update #自动更新
show-sql: true #日志中显示sql语句
application:
name: spring-data-jpa-demo
server:
port: 8009 #端口号
数据库如下:
import lombok.Data;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name="book")
@Data
public class Book {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Integer id;
private String name;
private String author;
private double price;
private Date publicationDate;
}
(1)@Entity 注解用于实体类声明语句之前,
指出该Java 类为实体类
,将映射到指定的数据库表。@Table 用于指明实体类映射的数据库表名。
(2)@Entity 和@Table 注解的包是 javax.persistence.* ,千万不要导错包。
import com.newstar.Entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book,Integer> {
}
当自定义接口继承 JpaRepository 接口时,需要两个参数:
实体类类名
和实体类主键的数据类型
。
本例中,实体类时Book,其主键id的数据类型是Integer,因此参数是Book和Integer。
@RestController
@RequestMapping("/jpa")
public class JpaController {
@Autowired
BookRepository bookRepository;
@RequestMapping("find")
public List<Book> book(){
System.out.println(bookRepository.findAll());
return bookRepository.findAll();
}
}
浏览器访问得到如下结果:
作者:我是不是很美
链接:http://www.javaheidong.com/blog/article/207620/d6975c6cb92b2aba4d01/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!