百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

SpringBoot项目中使用Jpa(SpringDataJpa)

bigegpt 2025-02-24 15:10 8 浏览

前言

  • JPA是 Java Persistence API 的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关 系,并将运行期的实体对象持久化到数据库中。
  • 在ORM框架中,Hibernate是一支很大的部队,使用很广泛,也很方便,能力也很强,同时Hibernate也是和JPA整 合的比较良好,我们可以认为JPA是标准,事实上也是,JPA几乎都是接口,实现都是Hibernate在做,宏观上面看,在 JPA的统一之下Hibernate很良好的运行。
  • 我们都知道Spring的强大,到目前为止,企业级应用Spring几乎是无所不能,无所不在,已经是事实上的标准了, 企业级应用不使用Spring的几乎没有。而Spring整合第三方框架的能力又很强,他要做的不仅仅是个最早的IOC容器这 么简单一回事,现在Spring涉及的方面太广,主要是体现在和第三方工具的整合上。而在与第三方整合这方面,Spring 希望把持久化这块内容也拿下。于是就有了Spring-data-**这一系列包。包括,Spring-data-jpa,Spring-data- template,Spring-data-mongodb,Spring-data-redis,还有个民间产品,mybatis-spring,和前面类似,这是和 mybatis整合的第三方包,这些都是干的持久化工具干的事儿。
  • 这里介绍Spring-data-jpa,表示与Jpa的整合
  • SpringData

:其实SpringData就是Spring提供了一个操作数据的框架。而SpringData JPA只是SpringData框架下的一个基于JPA标准操作数据的模块,总得包括以下:

    • ORM映射:支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系
    • API:操作实体对象来执行CRUD操作
    • 查询语言:通过面向对象而非面向数据库的查询语言(JPQL)查询数据,避免程序的SQL语句紧密耦合
  • SpringDataJPA

:基于JPA的标准数据进行操作。简化操作持久层的代码。只需要编写接口就可以。

  • 后面博主会陆续写出Jpa的关联关系和增删改查以及连表查询操作,欢迎关注

什么是Spring Data Jpa

Spring Data Jpa是Spring Data家族的一部分,Spring Data JPA相对于Java EE中的JPA,配置更简单,以轻量级的方式实现了部分在 EJB 容器环境下才具有的功能,将 EntityManager 的创建与销毁、事务管理等代码抽取出来,并由其统一管理,并且极大的简化了数据库访问层的代码。 Spring Data包含众多子项目除了JPA还有Spring Data MongoDB等等


SpringJpa 的运行原理

  1. SpringJPA 的全称是 Spring Data JPA 。其中JPA是 Java Persistence API 的缩写(Java持久化API),是SUN公司推出的一套接口,一套标准,Hibernate是一个具体的ORM的持久层框架(类似于Mybatis框架)实现了JPA接口 。
  2. Spring Data 是Spring开发团队提供的一套标准API和不同持久层整合技术实现。Spring Data 的出现就是为了简化、统一持久层的各种实现技术API。 (注:Spring Data 在项目里以 spring-data-commons 这个jar存在 )
  3. Spring Data JPA 既实现了 Spring Data 接口又实现了JPA接口,也是为了简化持久层的开发。 (注:Spring Data JPA 在项目里以 spring-data-jpa 这个jar存在

SpringJpa 优点

  1. 提供统一的接口,可避免我们再次重复的编写基础的DAO类;
  2. 遵循JPA规范,同时也提供了灵活的数据访问方式;
  3. 通过方法名即可自动生成HQL语句;
  4. 通过接口自动注入实现类,实现非常简单。

Spring Data JPAMyBatis 对比

Spring Data JPAMyBatis 对比,实际上就是 HibernateMyBatis 的对比,具体如下:

从基本概念和框架目标上看,两个框架差别还是很大的。 hibernate是一个自动化更强、更高级的框架,毕竟在java代码层面上,省去了绝大部分sql编写,取而代之的是 用面向对象的方式操作关系型数据库的数据。 MyBatis则是一个能够灵活编写sql语句,并将sql的入参和查询结果映射成POJOs的一个持久层框架。所以,从表 面上看,hibernate能方便、自动化更强,而MyBatis 在Sql语句编写方面则更灵活自由。

注:至于这两个框架用哪一个,可以根据自己的掌握情况或者使用场景进行选择。我个人推荐使用Spring Data JPA,因为的确很简单,符合敏捷开发要求。


SpringBoot 引入 SpringDataJpa 依赖


    org.springframework.boot
    spring-boot-starter-data-jpa

在yml文件配置如下,按需索取

spring:
  datasource:
    url:  jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
    username: root
    password: root
  jpa:
    database: mysql
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    show-sql: true
    hibernate:
      ddl-auto: update # 一般使用update
        # create: 每次运行程序时,都会重新创建表,故而数据会丢失
        # create-drop: 每次运行程序时会先创建表结构,然后待程序结束时清空表
        # upadte: 每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
        # validate: 运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
        # none: 禁用DDL处理

这里贴出来博主的一些配置:



    4.0.0
    com.jmccms
    Jmccms
    0.0.1-SNAPSHOT
    Jmccms
    https://repo.spring.io/milestone
    CYJ:ChenYongJia 服务提供者Jmccms

    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.5.RELEASE
         
    

    
    
        UTF-8
        UTF-8
        1.8
        
        Greenwich.RELEASE
        5.1.39
        4.12
        1.0.18
        
    

    

        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-actuator
        

        
        
            org.springframework.boot
            spring-boot-starter-aop
        

        

        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        

        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix
        

        
        
        
            org.springframework.cloud
            spring-cloud-starter-oauth2
        

        
        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        

        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        

        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
        
            junit
            junit
        

        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        

        
        
            org.springframework.boot
            spring-boot-starter-jdbc
        

        
        
            org.springframework.boot
            spring-boot-starter-security
        

        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        

        
        
            mysql
            mysql-connector-java
            ${mysql-connector}
        

        
        
            org.projectlombok
            lombok
            true
        

        
        

        
        
            com.alibaba
            fastjson
            1.2.56
        

        
        
            com.google.code.gson
            gson
            2.8.5
        

        
        
            com.alibaba
            easyexcel
            1.1.2-beta5
        

        

        
        
            org.apache.commons
            commons-lang3
            
            3.6
            provided
        

        
        
            org.apache.httpcomponents
            httpclient
            4.5.8
        

        
        

        

        

        
        
            io.springfox
            springfox-swagger2
            2.9.2
        

        
        
            io.springfox
            springfox-swagger-ui
            2.9.2
        

        
        
            eu.bitwalker
            UserAgentUtils
            1.21
        

    

    
    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                
                ${spring-cloud.version}
                
                pom
                import
            
        
    

    
        
            
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
        
        jmccms
    

    
    
        
            spring-milestones
            Spring Milestones
            https://repo.spring.io/milestone
            
                false
            
        
    



使用 Spring Data Jpa 增删改查(当然一般都和 lombok 结合使用)

第一步先创建你的数据库和配置文件保持一致,Jpa将自动帮你建表

package com.jmccms.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * @Description: 用户类
 * @BelongsProject: Jmccms
 * @BelongsPackage: com.jmccms.entity
 * @Author: ChenYongJia
 * @CreateTime: 2019-05-02 15:32
 * @Email chen87647213@163.com
 */
@Getter
@Setter
@AllArgsConstructor // 自动所有参数的构造方法方法
@NoArgsConstructor // 自动无参的构造方法方法
@Builder
@Entity
@Table(name = "jmccms_user")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @OrderBy
    @Column(columnDefinition = "bigint(19) unsigned  COMMENT '用户id'")
    private Long userId;
    @Column(columnDefinition = "varchar(64) NOT NULL COMMENT '用户名称'  ")
    private String userName;
    @Column(columnDefinition = "varchar(100) NOT NULL COMMENT '用户密码'  ")
    private String userPassWord;
    @Column(columnDefinition = "datetime COMMENT '用户创建时间' ")
    @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")    //日期格式化为中国的时区 东8区
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")    //接受::字符串日期需要格式化为日期类型
    private Date userCreateTime;
    @Column(columnDefinition = "datetime COMMENT '用户最后一次登录时间' ")
    @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")    //日期格式化为中国的时区 东8区
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")    //接受::字符串日期需要格式化为日期类型
    private Date userLastLoginTime;
    @Column(columnDefinition = "timestamp COMMENT '最后一次修改时间'", nullable = false, updatable = false, insertable = false)
    @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")    //日期格式化为中国的时区 东8区
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")    //接受::字符串日期需要格式化为日期类型
    private Timestamp userLastUpdateTime;
    @Column(columnDefinition = "varchar(64) NOT NULL COMMENT '创建人'  ")
    private String userFounder;
    @Column(columnDefinition = "varchar(64) COMMENT '修改人'  ")
    private String userUpdateMan;

    @JsonIgnore
    @ManyToMany(fetch = FetchType.EAGER) // 指定多对多关系
    @Cascade(value = { CascadeType.ALL }) // 设置级联关系
    @JoinTable(name = "jmccms_user_role", // 指定第三张中间表名称
            joinColumns = { @JoinColumn(name = "user_id") }, // 本表主键userId与第三张中间表user_role_tb的外键user_role_tb_user_id对应
            inverseJoinColumns = { @JoinColumn(name = "role_id") }) // 多对多关系另一张表与第三张中间表表的外键的对应关系
    @NotFound(action = NotFoundAction.IGNORE) // NotFound : 意思是找不到引用的外键数据时忽略,NotFound默认是exception
    private Set rolesSet = new HashSet<>();// 用户所拥有的角色集合

}

  • 建立数据库访问层
    • 使用 Spring Data JPA 建立数据库十分简单,只需要定义一个继承了 JpaRepository 的接口,下面是博主项目的一个类,可以参照
package com.jmccms.dao;

import com.jmccms.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import javax.transaction.Transactional;
import java.util.List;

/**
 * @Description: 用户接口
 * @BelongsProject: Jmccms
 * @BelongsPackage: com.jmccms.dao
 * @Author: ChenYongJia
 * @CreateTime: 2019-05-02 18:05
 * @Email chen87647213@163.com
 */
public interface UserRepository extends JpaRepository, JpaSpecificationExecutor {

    /**
     * 根据用户名和密码查询用户
     * @return
     */
    User findByUserNameAndUserPassWord(String userName, String userPassWord);

    /**
     * 根据用户名查询用户
     * @return
     */
    User findByUserName(String userName);

    /**
     * 根据用户id查询用户信息
     * @param userId
     * @return
     */
    User findByUserId(Long userId);

    /**
     * 批量删除用户信息
     *
     * @param userList
     * @return
     */
    @Query(value = "DELETE FROM jmccms_user WHERE user_id IN (:userList)", nativeQuery = true)
    @Modifying
    @Transactional
    Integer deleteUser(@Param(value = "userList") List userList);

    /**
     * 根据ID查询用户角色
     *
     * @param userId
     * @return
     */
    @Query(value = "SELECT role_id FROM jmccms_user_role WHERE 1=1 AND user_id=:usersId ", nativeQuery = true)
    List getUserRole(@Param(value = "usersId") Long userId);

}
  • 继承了 JpaRepository 就相当于有了下面的数据访问操作方法,这些都是 Spring Data Jpa 封装好的。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.data.jpa.repository;

import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

@NoRepositoryBean
public interface JpaRepository extends PagingAndSortingRepository, QueryByExampleExecutor {
    List findAll();

    List findAll(Sort var1);

    List findAllById(Iterable var1);

     List saveAll(Iterable var1);

    void flush();

     S saveAndFlush(S var1);

    void deleteInBatch(Iterable var1);

    void deleteAllInBatch();

    T getOne(ID var1);

     List findAll(Example var1);

     List findAll(Example var1, Sort var2);
}

支持的关键字、示例及JPQL片段如下表所示:

Keyword

Sample

JPQL Snippet

And

findByLastnameAndFirstname

… where x.lastname = ?1 and x.firstname = ?2

Or

findByLastnameOrFirstname

… where x.lastname = ?1 or x.firstname = ?2

Is,Equals

indByFirstname,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

findByAgeGreaterThanEqual

… where x.age >= ?1

After

findByStartDateAfter

… 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

NotLike

findByFirstnameNotLike

… findByFirstnameNotLike

StartingWith

findByFirstnameStartingWith

… where x.firstname like ?1 (parameter bound with appended %)

EndingWith

findByFirstnameEndingWith

… where x.firstname like ?1 (parameter bound with prepended %)

Containing

findByFirstnameContaining

… where x.firstname like ?1 (parameter bound wrapped in %)

OrderBy

findByAgeOrderByLastnameDesc

… where x.age = ?1 order by x.lastname desc

Not

findByLastnameNot

… where x.lastname <> ?1

In

findByAgeIn(Collection ages)

… where x.age in ?1

NotIn

findByAgeNotIn(Collection ages)

… where x.age not in ?1

True

findByActiveTrue()

… where x.active = true

False

findByActiveFalse()

… where x.active = false

IgnoreCase

findByFirstnameIgnoreCase

… where UPPER(x.firstame) = UPPER(?1)

#头条创作挑战赛#

相关推荐

Linux 系统启动完整流程

一、启动系统流程简介如上图,简述系统启动的大概流程:1:硬件引导UEFi或BIOS初始化,运行POST开机自检2:grub2引导阶段系统固件会从MBR中读取启动加载器,然后将控制权交给启动加载器GRU...

超专业解析!10分钟带你搞懂Linux中直接I/O原理

我们先看一张图:这张图大体上描述了Linux系统上,应用程序对磁盘上的文件进行读写时,从上到下经历了哪些事情。这篇文章就以这张图为基础,介绍Linux在I/O上做了哪些事情。文件系统什么是...

linux入门系列12--磁盘管理之分区、格式化与挂载

前面系列文章讲解了VI编辑器、常用命令、防火墙及网络服务管理,本篇将讲解磁盘管理相关知识。本文将会介绍大量的Linux命令,其中有一部分在“linux入门系列5--新手必会的linux命令”一文中已经...

Linux环境下如何设置多个交叉编译工具链?

常见的Linux操作系统都可以通过包管理器安装交叉编译工具链,比如Ubuntu环境下使用如下命令安装gcc交叉编译器:sudoapt-getinstallgcc-arm-linux-gnueab...

可算是有文章,把Linux零拷贝技术讲透彻了

阅读本文大概需要6.0分钟。作者:卡巴拉的树链接:https://dwz.cn/BaQWWtmh本文探讨Linux中主要的几种零拷贝技术以及零拷贝技术适用的场景。为了迅速建立起零拷贝的概念...

linux软链接的创建、删除和更新

大家都知道,有的时候,我们为了省下空间,都会使用链接的方式来进行引用操作。同样的,在系统级别也有。在Windows系列中,我们称其为快捷方式,在Linux中我们称其为链接(基本上都差不多了,其中可能...

Linux 中最容易被黑客动手脚的关键目录

在Linux系统中,黑客攻击后常会针对关键目录和文件进行修改以实现持久化、提权或隐藏恶意活动。本文介绍下黑客最常修改的目录及其手法。一、/etc目录关键文件有:/etc/passwd和/et...

linux之间传文件命令之Rsync傻瓜式教程

1.前言linux之间传文件命令用什么命令?本文介绍一种最常用,也是功能强大的文件同步和传输工具Rsync,本文提供详细傻瓜式教程。在本教程中,我们将通过实际使用案例和最常见的rsync选项的详细说...

Linux下删除目录符号链接的方法

技术背景在Linux系统中,符号链接(symlink)是一种特殊的文件,它指向另一个文件或目录。有时候,我们可能需要删除符号链接,但保留其指向的目标目录。然而,在删除符号链接时可能会遇到一些问题,例如...

阿里云国际站注册教程:aa云服务器怎么远程链接?

在全球化的今天,互联网带给我们无以计数的便利,而云服务器则是其中的重要基础设施之一。这篇文章将围绕阿里云国际站注册、aa云服务器如何远程链接,以及服务器安全防护如Ddos防火墙、网站应用防护waf防火...

Linux 5.16 网络子系统大范围升级 多个新适配器驱动加入

Linux在数据中心中占主导地位,因此每个内核升级周期的网络子系统变化仍然相当活跃。Linux5.16也不例外,周一最新与网络相关的更新加入了大量的驱动和新规范的支持。一个较新硬件的驱动是Realt...

搭建局域网文件共享服务(Samba),手机电脑都能看喜欢的影视剧

作为一名影视爱好者,为了方便地观看自己喜欢的影视作品,在家里搞一个专门用来存放电影的服务器是有必要的。蚁哥选则用一台Ubuntu系统的电脑做为服务器,共享影音文件,其他同一个局域网内的电脑或手机可以...

分享一个实用脚本—centos7系统巡检

概述这周闲得慌,就根据需求写了差不多20个脚本(部分是之前分享过的做了一些改进),今天主要分享一个给平时运维人员用的centos7系统巡检的脚本,或者排查问题检查系统情况也可以用..实用脚本#!/bi...

Linux 中创建符号链接的方法

技术背景在Linux系统里,符号链接(SymbolicLink),也被叫做软链接(SoftLink),是一种特殊的文件,它指向另一个文件或者目录。符号链接为文件和目录的管理带来了极大的便利,比...

一文掌握 Linux 符号链接

符号链接(SymbolicLink),通常被称为“软链接”,是Linux文件系统中一种强大而灵活的工具。它允许用户创建指向文件或目录的“快捷方式”,不仅简化了文件管理,还在系统配置、软件开发和日...