Spring Data JPA 是 Spring 提供的⼀个封装了JPA 操作的框架,⽽ JPA 仅仅是规范,单独使⽤规范⽆法
具体做什么,那么Spring Data JPA 、 JPA规范 以及 Hibernate (JPA 规范的⼀种实现)之间的关系是什
么?
JPA 是⼀套规范,内部是由接⼝和抽象类组成的,Hiberanate 是⼀套成熟的 ORM 框架,⽽且
Hiberanate 实现了 JPA 规范,所以可以称 Hiberanate 为 JPA 的⼀种实现⽅式,我们使⽤ JPA 的 API 编
程,意味着站在更⾼的⻆度去看待问题(⾯向接⼝编程)。
Spring Data JPA 是 Spring 提供的⼀套对 JPA 操作更加⾼级的封装,是在 JPA 规范下的专⻔⽤来进⾏数
据持久化的解决⽅案。
1.@Entity:标识实体类是JPA实体,告诉JPA在程序运行时生成实体类对应表
2.@Table:设置实体类在数据库所对应的表名
3.@Id:标识类里所在变量为主键
4.@GeneratedValue:设置主键生成策略,此方式依赖于具体的数据库
5.@Column:表示属性所对应字段名进行个性化设置
6.@Transient:表示属性并非数据库表字段的映射,ORM框架将忽略该属性
7.@Temporal:(很重要)
当我们使用到java.util包中的时间日期类型,则需要此注释来说明转化成java.util包中的类型。
注入数据库的类型有三种:
TemporalType.DATE(2008-08-08)
TemporalType.TIME(20:00:00)
TemporalType.TIMESTAMP(2008-08-08 20:00:00.000000001)
8.@Enumerated:(很重要)
使用此注解映射枚举字段,以String类型存入数据库
注入数据库的类型有两种:EnumType.ORDINAL(Interger)、EnumType.STRING(String)
9.@Embedded、@Embeddable:
当一个实体类要在多个不同的实体类中进行使用,而其不需要生成数据库表
@Embeddable:注解在类上,表示此类是可以被其他类嵌套
@Embedded:注解在属性上,表示嵌套被@Embeddable注解的同类型类
10.@ElementCollection:集合映射
11.@CreatedDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy:(很重要)
表示字段为创建时间字段(insert自动设置)、创建用户字段(insert自动设置)、最后修改时间字段(update自定设置)、最后修改用户字段(update自定设置)
用法:
1、@EntityListeners(AuditingEntityListener.class):申明实体类并加注解
2 、实现AuditorAware类
3、springboot 启动类加上注解@EnableJpaAuditing
4、在实体类中属性中加上面四种注解
后续会写个这个的demo
12.@MappedSuperclass:(很重要)
实现将实体类的多个属性分别封装到不同的非实体类中
注解的类将不是完整的实体类,不会映射到数据库表,但其属性将映射到子类的数据库字段
注解的类不能再标注@Entity或@Table注解,也无需实现序列化接口
注解的类继承另一个实体类 或 标注@MappedSuperclass类,他可使用@AttributeOverride 或 @AttributeOverrides注解重定义其父类属性映射到数据库表中字段。
具体使用:https://www.w3cschool.cn/java/jpa-entitymanager.html
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.3.RELEASEversion>
<relativePath/>
parent>
<groupId>com.examplegroupId>
<artifactId>demoartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>demoname>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.21version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.10version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.7version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
spring:
datasource:
url: jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true
username: root
password: root
# 使用druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
filters: stat
initialSize: 1
minIdle: 3
maxActive: 20
# 配置获取连接等待超时的时间showBussMonthRentReport
maxWait: 10000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 10000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 30000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20 # 指定每个连接上PSCache的大小
jpa:
hibernate:
ddl-auto: update # 第一次建表create 后面用update,要不然每次重启都会新建表
show-sql: true #打印执行的sql语句
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect #设置数据库方言 记住必须要使用 MySQL5InnoDBDialect 指定数据库类型对应InnoDB ;如果使用MySQLDialect 则对应的是MyISAM
package com.example.demo.model;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
@Setter
@Getter
@ToString
@Entity
@Table(name = "hot")
public class Hot {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "requirements")
private String requirements;
@Column(name = "salary")
private String salary;
@Column(name = "company_name")
private String companyName;
@Column(name = "company_label")
private String companyLabel;
@Column(name = "company_logo")
private String companyLogo;
@Transient
private String company;
}
package com.example.demo.dao;
import com.example.demo.model.Hot;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* ⼀个符合SpringDataJpa要求的Dao层接⼝是需要继承JpaRepository和
JpaSpecificationExecutor
*
* JpaRepository<操作的实体类类型,主键类型>
* 封装了基本的CRUD操作
*
* JpaSpecificationExecutor<操作的实体类类型>
* 封装了复杂的查询(分⻚、排序等)
*
*/
public interface HotDao extends JpaRepository<Hot,Long>, JpaSpecificationExecutor<Hot> {
@Query("from Resume where id=?1 and name=?2")
public List<Hot> findByJpql(Long id,String name);
/**
* 使⽤原⽣sql语句查询,需要将nativeQuery属性设置为true,默认为false(jpql)
* @param name
* @param companyName
* @return
*/
@Query(value = "select * from tb_resume where name like ?1 and
company_name like ?2",nativeQuery = true)
public List<Hot> findBySql(String name,String companyName);
/**
* ⽅法命名规则查询
* 按照name模糊查询(like)
* ⽅法名以findBy开头
* -属性名(⾸字⺟⼤写)
* -查询⽅式(模糊查询、等价查询),如果不写查询⽅式,默认等价
查询
*/
public List<Hot> findByNameLikeAndCompanyName(String name,String
companyName);
}
@RunWith(SpringRunner.class)
@SpringBootTest
class DemoApplicationTests {
@Autowired
private HotDao hotDao;
@Test
void contextLoads() {
Hot hot= new Hot();
hot.setCompanyName("peng");
hotDao.saveAndFlush(hot);
}
}
分析
/**
* ========================针对查询的使⽤进⾏分析=======================
* ⽅式⼀:调⽤继承的接⼝中的⽅法 findOne(),findById()
* ⽅式⼆:可以引⼊jpql(jpa查询语⾔)语句进⾏查询 (=====>>>> jpql 语句类似于
sql,只不过sql操作的是数据表和字段,jpql操作的是对象和属性,⽐如 from Resume where
id=xx) hql
* ⽅式三:可以引⼊原⽣的sql语句
* 规则查询,也就是说定义的接⼝⽅法名是按照⼀定规则形成的,那么框架就能够理解我们的意图
* * ⽅式五:动态查询
* * service层传⼊dao层的条件不确定,把service拿到条件封装成⼀个对象传递给
* Dao层,这个对象就叫做Specification(对条件的⼀个封装)
* *
* *
* * // 根据条件查询单个对象
* * Optional findOne(@Nullable Specification var1);
* * // 根据条件查询所有
* * List findAll(@Nullable Specification var1);
* * // 根据条件查询并进⾏分⻚
* * Page findAll(@Nullable Specification var1, Pageable
* var2);
* * // 根据条件查询并进⾏排序
* * List findAll(@Nullable Specification var1, Sort
* var2);
* * // 根据条件统计
* * long count(@Nullable Specification var1);
* *
* * interface Specification
* * toPredicate(Root var1, CriteriaQuery> var2,
* CriteriaBuilder var3);⽤来封装查询条件的
* * Root:根属性(查询所需要的任何属性都可以从根对象中获取)
* * CriteriaQuery ⾃定义查询⽅式 ⽤不上
* * CriteriaBuilder 查询构造器,封装了很多的查询条件(like =
* 等)
* *
* *
* */