Spring Data JPA 框架

Spring Data JPA 框架

简介

  • Spring Data Jpa 是应⽤于Dao层的⼀个框架,简化数据库开发的,作⽤和Mybatis框架⼀样,但是在使

    ⽤⽅式和底层机制是有所不同的。最明显的⼀个特点,Spring Data Jpa 开发Dao的时候,很多场景我们

    连sql语句都不需要开发。由Spring出品。

  • Spring Data JPA 是 Spring 基于JPA 规范的基础上封装的⼀套 JPA 应⽤框架,可使开发者⽤极简的

    代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常⽤功能!学习并使⽤

    Spring Data JPA 可以极⼤提⾼开发效率。

  • 说明:Spring Data JPA 极⼤简化了数据访问层代码。

    如何简化呢?使⽤了Spring Data JPA,我们Dao层中只需要写接⼝,不需要写实现类,就⾃动具有

    了增删改查、分⻚查询等⽅法。

    使⽤Spring Data JPA 很多场景下不需要我们⾃⼰写sql语句

JPA规范和Hibernate之间的关系

Spring Data JPA 是 Spring 提供的⼀个封装了JPA 操作的框架,⽽ JPA 仅仅是规范,单独使⽤规范⽆法

具体做什么,那么Spring Data JPA 、 JPA规范 以及 Hibernate (JPA 规范的⼀种实现)之间的关系是什

么?

image

JPA 是⼀套规范,内部是由接⼝和抽象类组成的,Hiberanate 是⼀套成熟的 ORM 框架,⽽且

Hiberanate 实现了 JPA 规范,所以可以称 Hiberanate 为 JPA 的⼀种实现⽅式,我们使⽤ JPA 的 API 编

程,意味着站在更⾼的⻆度去看待问题(⾯向接⼝编程)。

Spring Data JPA 是 Spring 提供的⼀套对 JPA 操作更加⾼级的封装,是在 JPA 规范下的专⻔⽤来进⾏数

据持久化的解决⽅案。

Spring Data 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

Spring Data JPA 使用

  • 导入坐标

<?xml version="1.0" encoding="UTF-8"?>

<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.0</modelVersion>

    <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>2.3.3.RELEASE</version>

        <relativePath/> <!-- lookup parent from repository -->

    </parent>

    <groupId>com.example</groupId>

    <artifactId>demo</artifactId>

    <version>0.0.1-SNAPSHOT</version>

    <name>demo</name>

    <description>Demo project for Spring Boot</description>

    <properties>

        <java.version>1.8</java.version>

    </properties>

    <dependencies>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-data-jpa</artifactId>

        </dependency>

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>5.1.21</version>

        </dependency>

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>druid</artifactId>

            <version>1.1.10</version>

        </dependency>

        <dependency>

            <groupId>org.projectlombok</groupId>

            <artifactId>lombok</artifactId>

            <optional>true</optional>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-annotations</artifactId>

            <version>2.9.7</version>

        </dependency>

    </dependencies>

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

</project>

  • 配置 Spring 的配置⽂件

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

  • 编写实体类,使⽤ JPA 注解配置映射关系

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<T> findOne(@Nullable Specification<T> var1);

    * * // 根据条件查询所有

    * * List<T> findAll(@Nullable Specification<T> var1);

    * * // 根据条件查询并进⾏分⻚

    * * Page<T> findAll(@Nullable Specification<T> var1, Pageable

    * var2);

    * * // 根据条件查询并进⾏排序

    * * List<T> findAll(@Nullable Specification<T> var1, Sort

    * var2);

    * * // 根据条件统计

    * * long count(@Nullable Specification<T> var1);

    * *

    * * interface Specification<T>

    * * toPredicate(Root<T> var1, CriteriaQuery<?> var2,

    * CriteriaBuilder var3);⽤来封装查询条件的

    * * Root:根属性(查询所需要的任何属性都可以从根对象中获取)

    * * CriteriaQuery ⾃定义查询⽅式 ⽤不上

    * * CriteriaBuilder 查询构造器,封装了很多的查询条件(like =

    * 等)

    * *

    * *

    * */

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355