Spring Data JPA之Spring boot整合JPA进行CRUD(上)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Spring Data JPA之Spring boot整合JPA进行CRUD(上)

Spring boot整合JPA进行CRUD

前言

最近是在项目中使用到了Spring Data JPA来减少大量重复SQL语句的编写,能够感觉到的确是使用起来很方便效率也比较高。Spring Data JPA 能够简化数据访问层的实现,让工程师不必去写一些CRUD的接口和实现。Spring Data JPA 自动提供CRUD的实现,能够部分解放工程师们的工作量。

通过本篇博客可以实现使用JPA进行CRUD

系列博客

Spring Data JPA之自动创建数据库表

本博客的实现demo

spring-data-jpa-crud demo

环境配置

  1. 创建一个Maven项目并引入依赖

1.POM依赖

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.12.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <dependencies>
    <!--spring boot 启动器-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <!--spring mvc-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--spring boot 开发工具-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <scope>runtime</scope>
      <optional>true</optional>
    </dependency>
    <!--spring boot 测试工具-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <!--jpa 启动器-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!--mysql连接器-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
  </dependencies>

2.application.yml文件

server:
  port: 8099
spring:
  application:
    name: spring-data-jpa
  datasource:
    #mysq 驱动
    driver-class-name: com.mysql.cj.jdbc.Driver
    #连接数据库的url中配置ip和数据库名称以及时区
    url: jdbc:mysql://localhost:3306/spring_jpa?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
    username: root
    password: root
  jpa:
    hibernate:
      #更新或者创建数据库表结构
      ddl-auto: update
    #控制台显示SQL
    show-sql: true

完整的项目结构

比较典型的MVC项目结构,在JPA里面将熟悉的dao层数据操作层用repository来命名


代码实现

实体类

目前有一个实体类,一个基础类(用于抽象出一些公共的字段)

基础类BaseEntity


import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import java.util.Date;
/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : BaseEntity
 * @description : [基础类]
 * @createTime : [2022/11/18 15:32]
 * @updateUser : [WangWei]
 * @updateTime : [2022/11/18 15:32]
 * @updateRemark : [描述说明本次修改内容]
 */
//@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。
@MappedSuperclass
public class BaseEntity {
  //定义字段以及字段的类型和长度和是否允许为null
    @Column(name = "create_by",columnDefinition = "varchar(32) COMMENT '创建人'",nullable = false)
    private String createdBy;
    @Column(name = "created_id",columnDefinition = "varchar(32) COMMENT '创建人id'",nullable = false)
    private Long createdId;
    @Column(name = "create_time",nullable = false,columnDefinition = "DATETIME DEFAULT CURRENT_TIMESTAMP  COMMENT '创建时间'")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @Column(name = "updated_by",columnDefinition = "varchar(32) COMMENT '更新人'")
    private String updateBy;
    @Column(name = "updated_id",columnDefinition = "varchar(32) COMMENT '更新人id'")
    private Long updateId;
  定义字段以及字段的类型并默认为当前时间,并当进行修改的时候更新时间为当前实现
    @Column(name = "update_time",columnDefinition = "DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @Column(name = "is_delete",columnDefinition = "tinyint(1) COMMENT '是否删除(0/1 未删除/删除)'")
    private int isDelete=0;
    @Column(name = "remark",columnDefinition = "varchar(64) COMMENT '备注'")
    private String remark;
    public String getCreatedBy() {
        return createdBy;
    }
    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public String getUpdateBy() {
        return updateBy;
    }
    public void setUpdateBy(String updateBy) {
        this.updateBy = updateBy;
    }
    public Long getCreatedId() {
        return createdId;
    }
    public void setCreatedId(Long createdId) {
        this.createdId = createdId;
    }
    public Long getUpdateId() {
        return updateId;
    }
    public void setUpdateId(Long updateId) {
        this.updateId = updateId;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
    public int getIsDelete() {
        return isDelete;
    }
    public void setIsDelete(int isDelete) {
        this.isDelete = isDelete;
    }
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
}

实体类UserEntity

import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : UserEntity
 * @description : [用户实体类]
 * @createTime : [2022/11/18 14:57]
 * @updateUser : [WangWei]
 * @updateTime : [2022/11/18 14:57]
 * @updateRemark : [描述说明本次修改内容]
 */
@Entity //声明类为实体类
@Table(name="jpa_user")//对应创建之后的表名
public class UserEntity extends BaseEntity{
    @Id
    @Column(name = "user_code",columnDefinition = "bigint(20) COMMENT '学号'",nullable = false)//定义字段名和类型以及长度和备注,和是否允许为null
    private Long id;
    @Column(name="user_Name",nullable = false,columnDefinition = "varchar(32) COMMENT '用户名'")
    private String userName;
    @Column(name="pass_word",nullable = false,columnDefinition = "varchar(32) COMMENT '密码'")
    private String password;
    @Column(name="phone_Number",nullable = false,columnDefinition = "varchar(16) COMMENT '手机号'")
    private String phoneNumber;
    @Column(name="sex",columnDefinition = "varchar(2) COMMENT '性别'")
    private String sex;
    @Column(name="birthday",nullable = false,columnDefinition = "datetime COMMENT '生日日期'")
    @DateTimeFormat(pattern = "yyyy-MM-dd ")
    private Date birthday;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getPhoneNumber() {
        return phoneNumber;
    }
    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

启动类

此时已经可以直接运行启动类,启动程序时候在数据库中会直接生成相应的表。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringDataJpaApplication {
  public static void main(String[] args) {
    SpringApplication.run(SpringDataJpaApplication.class, args);
  }
}

可以在mysql中查看,或者在Navicat上查看到已经创建的表





创建数据访问层

在repository中创建UserRepository接口继承JpaRepository接口,JpaRepository接口提供了一些的增删改查的方法。

JpaRepository接口

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
  /*
   * (non-Javadoc)
   * @see org.springframework.data.repository.CrudRepository#findAll()
   */
  @Override
  List<T> findAll();
  /*
   * (non-Javadoc)
   * @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
   */
  @Override
  List<T> findAll(Sort sort);
  /*
   * (non-Javadoc)
   * @see org.springframework.data.repository.CrudRepository#findAll(java.lang.Iterable)
   */
  @Override
  List<T> findAllById(Iterable<ID> ids);
  /*
   * (non-Javadoc)
   * @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
   */
  @Override
  <S extends T> List<S> saveAll(Iterable<S> entities);
  /**
   * Flushes all pending changes to the database.
   */
  void flush();
  /**
   * Saves an entity and flushes changes instantly.
   *
   * @param entity
   * @return the saved entity
   */
  <S extends T> S saveAndFlush(S entity);
  /**
   * Deletes the given entities in a batch which means it will create a single {@link Query}. Assume that we will clear
   * the {@link javax.persistence.EntityManager} after the call.
   *
   * @param entities
   */
  void deleteInBatch(Iterable<T> entities);
  /**
   * Deletes all entities in a batch call.
   */
  void deleteAllInBatch();
  /**
   * Returns a reference to the entity with the given identifier. Depending on how the JPA persistence provider is
   * implemented this is very likely to always return an instance and throw an
   * {@link javax.persistence.EntityNotFoundException} on first access. Some of them will reject invalid identifiers
   * immediately.
   *
   * @param id must not be {@literal null}.
   * @return a reference to the entity with the given identifier.
   * @see EntityManager#getReference(Class, Object) for details on when an exception is thrown.
   */
  T getOne(ID id);
  /*
   * (non-Javadoc)
   * @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example)
   */
  @Override
  <S extends T> List<S> findAll(Example<S> example);
  /*
   * (non-Javadoc)
   * @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example, org.springframework.data.domain.Sort)
   */
  @Override
  <S extends T> List<S> findAll(Example<S> example, Sort sort);
}

UserRepository接口

import com.example.springdatajpa.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : UserRepository
 * @description : [User数据访问接口]
 * @createTime : [2022/11/19 19:15]
 * @updateUser : [WangWei]
 * @updateTime : [2022/11/19 19:15]
 * @updateRemark : [描述说明本次修改内容]
 */
public interface UserRepository extends JpaRepository<UserEntity,Long> {
}

JpaRepository<T, ID>T表示实体的类型,ID表示实体类中ID的类型。

使用Spring Data JPA 创建带条件的CRUD

由于JpaRepository<T, ID>接口只定义了一些较为简单的CRUD,但是对于一些带条件的CRUDJpaRepository并没有给出,但是我们可以在继承JpaRepository<T, ID>接口的接口中创建相应的方法。

import com.example.springdatajpa.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
/**
 * @author : [WangWei]
 * @version : [v1.0]
 * @className : UserRepository
 * @description : [描述说明该类的功能]
 * @createTime : [2022/11/19 19:15]
 * @updateUser : [WangWei]
 * @updateTime : [2022/11/19 19:15]
 * @updateRemark : [描述说明本次修改内容]
 */
public interface UserRepository extends JpaRepository<UserEntity,Long> {
    /*
     * @version V1.0
     * Title: findUserEntitiesByPhoneNumberAndIsDelete
     * @author Wangwei
     * @description 根据手机号查询
     * @createTime  2022/11/20 10:00
     * @param [phoneNumber, isDelete]
     * @return com.example.springdatajpa.entity.UserEntity
     */
    UserEntity findUserEntitiesByPhoneNumberAndIsDelete(String phoneNumber,int isDelete);
}

创建相应的方法,先定义方法的返回值,在定义操作类型(find,delete,search)+By+条件



如果有需要可以参考Spring Data Jpa官网上Spring Data Jpa

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
1月前
|
NoSQL Java 数据库连接
《深入理解Spring》Spring Data——数据访问的统一抽象与极致简化
Spring Data通过Repository抽象和方法名派生查询,简化数据访问层开发,告别冗余CRUD代码。支持JPA、MongoDB、Redis等多种存储,统一编程模型,提升开发效率与架构灵活性,是Java开发者必备利器。(238字)
|
1月前
|
前端开发 Java 应用服务中间件
《深入理解Spring》 Spring Boot——约定优于配置的革命者
Spring Boot基于“约定优于配置”理念,通过自动配置、起步依赖、嵌入式容器和Actuator四大特性,简化Spring应用的开发与部署,提升效率,降低门槛,成为现代Java开发的事实标准。
|
1月前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
1月前
|
存储 Java 关系型数据库
Spring Boot中Spring Data JPA的常用注解
Spring Data JPA通过注解简化数据库操作,实现实体与表的映射。常用注解包括:`@Entity`、`@Table`定义表结构;`@Id`、`@GeneratedValue`配置主键策略;`@Column`、`@Transient`控制字段映射;`@OneToOne`、`@OneToMany`等处理关联关系;`@Enumerated`、`@NamedQuery`支持枚举与命名查询。合理使用可提升开发效率与代码可维护性。(238字)
301 1
|
1月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
365 2
|
2月前
|
人工智能 Java 机器人
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
Spring AI Alibaba集成Ollama,基于Java构建本地大模型应用,支持流式对话、knife4j接口可视化,实现高隐私、免API密钥的离线AI服务。
1933 1
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
存储 JSON Java
490 0
|
7月前
|
SQL Java 编译器
深入理解 Spring Data JPA 的导入与使用:以 UserRepository为例
本文深入解析了 Spring Data JPA 中 `UserRepository` 的导入与使用。通过示例代码,详细说明了为何需要导入 `User` 实体类、`JpaRepository` 接口及 `@Repository` 注解。这些导入语句分别用于定义操作实体、提供数据库交互方法和标识数据访问组件。文章还探讨了未导入时的编译问题,并展示了实际应用场景,如用户保存、查询与删除操作。合理使用导入语句,可让代码更简洁高效,充分发挥 Spring Data JPA 的优势。
465 0
|
Java 数据库连接 API
【Java笔记+踩坑】Spring Data JPA
从常用注解、实体类和各层编写方法入手,详细介绍JPA框架在增删改查等方面的基本用法,以及填充用户名日期、分页查询等高级用法。
【Java笔记+踩坑】Spring Data JPA
|
Java Spring 数据库
怎样动动手指就能实现数据操作?Spring Data JPA背后的魔法揭秘
【8月更文挑战第31天】在Java开发中,数据库交互至关重要。传统的JDBC操作繁琐且难维护,而Spring Data JPA作为集成JPA的数据访问层解决方案,提供了CRUD等通用操作接口,显著减少代码量。通过继承`JpaRepository`,开发者能轻松实现数据的增删改查,甚至复杂查询和分页也不再困难。本文将通过示例详细介绍如何利用Spring Data JPA简化数据访问层的开发,提升代码质量和可维护性。
182 0

热门文章

最新文章