Spring Boot 整合 JPA 实现数据持久化

目录

前言

一、JPA 核心概念与实体映射

1. 什么是 JPA?

2. JPA 的主要组件

3. 实体映射

4. 常见的字段映射策略

二、Repository 接口与自定义查询

1. 什么是 Repository 接口?

2. 动态查询方法

3. 自定义查询

4. 分页与排序

三、实战案例:完整数据持久化示例

1. 创建一个简单的用户管理系统

2. 测试接口


前言

在现代企业级应用开发中,数据持久化是不可或缺的一部分。Spring Boot 提供了对 JPA(Java Persistence API)的强大支持,使得数据库操作变得更加简单和高效。本文将从以下几个方面详细讲解如何在 Spring Boot 中整合 JPA 实现数据持久化:

  1. JPA 核心概念与实体映射
  2. Repository 接口与自定义查询

通过本文的学习,你将能够掌握 Spring Boot 中 JPA 的基本使用方法,并能够根据实际需求进行灵活的扩展。


一、JPA 核心概念与实体映射

1. 什么是 JPA?

JPA(Java Persistence API)是 Java EE 平台中用于对象关系映射(ORM)的标准 API。它允许开发者通过 Java 类来表示数据库中的表,并通过 JPA 提供的接口和注解来执行 CRUD(增删改查)操作。

2. JPA 的主要组件
  • EntityManager:负责管理实体对象的生命周期,并提供 CRUD 操作的方法。
  • Persistence Unit:一组相关的实体类和配置信息的集合。
  • Entity:表示数据库表的 Java 类。
3. 实体映射

在 JPA 中,实体类通过注解来映射到数据库表。以下是常用的注解:

  • @Entity:标识这是一个实体类。
  • @Table:指定实体类对应的数据库表名。
  • @Id:标识实体类的主键字段。
  • @GeneratedValue:指定主键的生成策略。
  • @Column:指定字段对应的数据库列名、长度等属性。

示例代码:

import jakarta.persistence.*; 
 
@Entity 
@Table(name = "users")
public class User {
 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    @Column(name = "username", length = 50, nullable = false)
    private String username;
 
    @Column(name = "email", unique = true)
    private String email;
 
    // Getter and Setter methods 
}
4. 常见的字段映射策略
  • 基本类型映射:如 StringIntegerLong 等。
  • 关联关系映射
    • 一对一(OneToOne):通过 @OneToOne 注解实现。
    • 一对多(OneToMany):通过 @OneToMany 注解实现。
    • 多对一(ManyToOne):通过 @ManyToOne 注解实现。
    • 多对多(ManyToMany):通过 @ManyToMany 注解实现。

示例代码(一对多关系):

import jakarta.persistence.*; 
 
@Entity 
@Table(name = "posts")
public class Post {
 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    @Column(name = "title", nullable = false)
    private String title;
 
    @Column(name = "content")
    private String content;
 
    @ManyToOne 
    @JoinColumn(name = "user_id")
    private User user;
 
    // Getter and Setter methods 
}

二、Repository 接口与自定义查询

1. 什么是 Repository 接口?

Spring Data JPA 提供了一个 Repository 接口,用于简化数据访问层的开发。通过继承 JpaRepositoryCrudRepository,我们可以快速获得 CRUD 操作的能力。

示例代码:

import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.stereotype.Repository; 
 
@Repository 
public interface UserRepository extends JpaRepository<User, Long> {
}

  • JpaRepository:继承了 CrudRepository PagingAndSortingRepository,提供了基本的 CRUD 操作和分页支持。
  • UserRepository:定义了一个针对 User 实体的仓库接口。
2. 动态查询方法

Spring Data JPA 支持通过方法名动态生成查询语句。例如:

public interface UserRepository extends JpaRepository<User, Long> {
 
    List<User> findByUsername(String username);
 
    List<User> findByEmailContaining(String keyword);
 
    List<User> findByUsernameAndEmail(String username, String email);
}

  • findByUsername:根据用户名查询用户。
  • findByEmailContaining:根据邮箱包含关键字查询用户。
  • findByUsernameAndEmail:根据用户名和邮箱联合查询用户。
3. 自定义查询

对于复杂的查询需求,可以通过 @Query 注解来自定义 JPQL(Java Persistence Query Language)或原生 SQL 查询。

示例代码:

import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.data.jpa.repository.Query; 
import org.springframework.data.repository.query.Param; 
import org.springframework.stereotype.Repository; 
 
import java.util.List; 
 
@Repository 
public interface UserRepository extends JpaRepository<User, Long> {
 
    @Query("SELECT u FROM User u WHERE u.username  LIKE %:keyword%")
    List<User> findByUsernameLike(@Param("keyword") String keyword);
 
    @Query(value = "SELECT * FROM users WHERE email LIKE %?1%", nativeQuery = true)
    List<User> findByEmailLike(String keyword);
}
  • findByUsernameLike:使用 JPQL 查询用户名包含关键字的用户。
  • findByEmailLike:使用原生 SQL 查询邮箱包含关键字的用户。
4. 分页与排序

Spring Data JPA 提供了 Pageable 接口来支持分页和排序。

示例代码:

import org.springframework.data.domain.Page; 
import org.springframework.data.domain.Pageable; 
 
public interface UserRepository extends JpaRepository<User, Long> {
 
    Page<User> findAll(Pageable pageable);
 
    Page<User> findByUsernameContaining(String keyword, Pageable pageable);
}

三、实战案例:完整数据持久化示例

1. 创建一个简单的用户管理系统

实体类(User.java ):

import jakarta.persistence.*; 
 
@Entity 
@Table(name = "users")
public class User {
 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    @Column(name = "username", length = 50, nullable = false)
    private String username;
 
    @Column(name = "email", unique = true)
    private String email;
 
    // Getter and Setter methods 
}

Repository 接口(UserRepository.java ):

import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.data.jpa.repository.Query; 
import org.springframework.data.repository.query.Param; 
import org.springframework.stereotype.Repository; 
 
import java.util.List; 
 
@Repository 
public interface UserRepository extends JpaRepository<User, Long> {
 
    List<User> findByUsername(String username);
 
    @Query("SELECT u FROM User u WHERE u.email  LIKE %:keyword%")
    List<User> findByEmailLike(@Param("keyword") String keyword);
}

 Service 层(UserService.java ):

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 
 
import java.util.List; 
 
@Service 
public class UserService {
 
    @Autowired 
    private UserRepository userRepository;
 
    public List<User> findAllUsers() {
        return userRepository.findAll(); 
    }
 
    public User saveUser(User user) {
        return userRepository.save(user); 
    }
 
    public List<User> findByUsername(String username) {
        return userRepository.findByUsername(username); 
    }
 
    public List<User> findByEmailLike(String keyword) {
        return userRepository.findByEmailLike(keyword); 
    }
}

Controller 层(UserController.java ):

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.bind.annotation.*; 
 
import java.util.List; 
 
@RestController 
@RequestMapping("/api/users")
public class UserController {
 
    @Autowired 
    private UserService userService;
 
    @GetMapping 
    public List<User> getAllUsers() {
        return userService.findAllUsers(); 
    }
 
    @PostMapping 
    public User createUser(@RequestBody User user) {
        return userService.saveUser(user); 
    }
 
    @GetMapping("/username/{username}")
    public List<User> findByUsername(@PathVariable String username) {
        return userService.findByUsername(username); 
    }
 
    @GetMapping("/email/{keyword}")
    public List<User> findByEmailLike(@PathVariable String keyword) {
        return userService.findByEmailLike(keyword); 
    }
}

2. 测试接口

启动应用后,可以通过 Postman 或 Swagger UI 测试以下接口:

  • GET http://localhost:8080/api/users:获取所有用户。
  • POST http://localhost:8080/api/users:创建新用户。
  • GET http://localhost:8080/api/users/username/{username}:根据用户名查询用户。
  • GET http://localhost:8080/api/users/email/{keyword}:根据邮箱关键字查询用户。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/967245.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

本地部署DeepSeek-R1模型(新手保姆教程)

背景 最近deepseek太火了&#xff0c;无数的媒体都在报道&#xff0c;很多人争相着想本地部署试验一下。本文就简单教学一下&#xff0c;怎么本地部署。 首先大家要知道&#xff0c;使用deepseek有三种方式&#xff1a; 1.网页端或者是手机app直接使用 2.使用代码调用API …

有关网络安全的案例分享 如何保障网络安全

网络发展是非常迅速的&#xff0c;互联网在给人们带来生活娱乐便利的同时&#xff0c;也带来了一些安全隐患&#xff0c;这就需要大家做好防骗规范&#xff0c;确保网络安全&#xff0c;51CTO学堂为大家分享下有关网络安全的案例&#xff0c;以供各位参考。 非法获取公民个人信…

2025新鲜出炉--前端面试题(一)

文章目录 1. vue3有用过吗, 和vue2之间有哪些区别2. vue-router有几种路由, 分别怎么实现3. webpack和rollup这两个什么区别, 你会怎么选择4. 你能简单介绍一下webpack项目的构建流程吗5. webpack平时有手写过loader和plugin吗6. webpack这块你平时做过哪些优化吗&#xff1f;7…

变化检测论文阅读合集

1. ChangeCLIP: Remote sensing change detection with multimodal vision-language representation learning 作者&#xff1a;Sijun Dong a, Libo Wang b, Bo Du c, Xiaoliang Meng a,* 年份&#xff1a;2024 研究方法/模型&#xff1a; 重构原始CLIP&#xff1a;提取双时…

viem库

viem是一个用于和以太坊进行交互的javascript库&#xff0c;它提供了简单的API进行智能合约的读取和写入操作&#xff0c;你可以使用它来与区块链上智能合约进行交互&#xff0c;查询链上数据等。 基本功能 1&#xff0c;创建公有客户端 createPublicClient 可以创建一个链接…

2025影视泛目录站群程序设计_源码二次开发新版本无缓存刷新不变实现原理

1. 引言 本设站群程序计书旨在详细阐述苹果CMS泛目录的创新设计与实现&#xff0c;介绍无缓存刷新技术、数据统一化、局部URL控制及性能优化等核心功能&#xff0c;以提升网站访问速度和用户体验。 2. 技术概述 2.1 无缓存刷新技术 功能特点&#xff1a; 内容不变性&#x…

OpenEuler学习笔记(二十三):在OpenEuler上部署开源MES系统

在OpenEuler上部署小企业开源MES&#xff08;制造执行系统&#xff0c;Manufacturing Execution System&#xff09;是一个非常有价值的项目&#xff0c;可以帮助企业实现生产过程的数字化管理。以下是基于开源MES系统&#xff08;如 Odoo MES 或 OpenMES&#xff09;的部署步骤…

大数据项目2:基于hadoop的电影推荐和分析系统设计和实现

前言 大数据项目源码资料说明&#xff1a; 大数据项目资料来自我多年工作中的开发积累与沉淀。 我分享的每个项目都有完整代码、数据、文档、效果图、部署文档及讲解视频。 可用于毕设、课设、学习、工作或者二次开发等&#xff0c;极大提升效率&#xff01; 1、项目目标 本…

c++ haru生成pdf输出饼图

#define PI 3.14159265358979323846 // 绘制饼图的函数 void draw_pie_chart(HPDF_Doc pdf, HPDF_Page page, float *data, int data_count, float x, float y, float radius) { float total 0; int i; // 计算数据总和 for (i 0; i < data_count; i) { tot…

STM32 Unix时间戳

Unix时间戳 Unix 时间戳&#xff08;Unix Timestamp&#xff09;定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数&#xff0c;不考虑闰秒 时间戳存储在一个秒计数器中&#xff0c;秒计数器为32位/64位的整型变量 世界上所有时区的秒计数器相同&#xff0c;不同时区通过…

Spring Boot启动内嵌tocmat原理

要研究Spring Boot启动内嵌tomcat的原理&#xff0c;就需要先了解一下Spring Boot自动配置的过程&#xff0c;首先简要的梳理一下springboot自动配置的步骤。 一、SpringBoot自动配置 当SpringBoot应用启动时&#xff0c;EnableAutoConfiguration注解被激活&#xff0c;该注解…

腾讯云AI代码助手评测:如何智能高效完成Go语言Web项目开发

腾讯云AI代码助手评测&#xff1a;如何智能高效完成Go语言Web项目开发 ?? 文章目录 腾讯云AI代码助手评测&#xff1a;如何智能高效完成Go语言Web项目开发 ?? 背景引言开发环境介绍腾讯云AI代码助手使用实例 1. 代码补全2. 技术对话3. 代码优化4. 规范代码5. Bug处理 获得…

feign 远程调用详解

在平常的开发工作中&#xff0c;我们经常需要跟其他系统交互&#xff0c;比如调用用户系统的用户信息接口、调用支付系统的支付接口等。那么&#xff0c;我们应该通过什么方式进行系统之间的交互呢&#xff1f;今天&#xff0c;简单来总结下 feign 的用法。 1&#xff1a;引入依…

【JVM详解三】垃圾回收机制

一、对象是否存活 强引用&#xff1a;Object obj new Object(); 只要强引用还在&#xff0c;垃圾收集器永远不会回收掉被引用的对象。在不用对象的时将引用赋值为 null&#xff0c;能够帮助垃圾回收器回收对象。比如 ArrayList 的 clear() 方法实现。软引用&#xff08;SoftRe…

基于lstm+gru+transformer的电池寿命预测健康状态预测-完整数据代码

项目视频讲解: 毕业设计:基于lstm+gru+transformer的电池寿命预测 健康状态预测_哔哩哔哩_bilibili 数据: 实验结果:

opentelemetry-collector 配置elasticsearch

一、修改otelcol-config.yaml receivers:otlp:protocols:grpc:endpoint: 0.0.0.0:4317http:endpoint: 0.0.0.0:4318 exporters:debug:verbosity: detailedotlp/jaeger: # Jaeger supports OTLP directlyendpoint: 192.168.31.161:4317tls:insecure: trueotlphttp/prometheus: …

uniapp访问django目录中的图片和视频,2025[最新]中间件访问方式

新建中间件, middleware.py 匹配,以/cover_image/ 开头的图片 匹配以/episode_video/ 开头的视频 imageSrc: http://192.168.110.148:8000/cover_image/12345/1738760890657_mmexport1738154397386.jpg, videoSrc: http://192.168.110.148:8000/episode_video/12345/compres…

ChunkKV:优化 KV 缓存压缩,让 LLM 长文本推理更高效

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Windows下ollama详细安装指南

文章目录 1、Windows下ollama详细安装指南1.1、ollama介绍1.2、系统要求1.3、下载安装程序1.4、安装步骤1.5、验证安装1.6、环境变量配置1.7、模型选择与安装【deepseek 示例】1.7.1、拉取并运行模型1.7.2、进阶使用技巧 1、Windows下ollama详细安装指南 1.1、ollama介绍 olla…

【算法】动态规划专题⑥ —— 完全背包问题 python

目录 前置知识进入正题模板 前置知识 【算法】动态规划专题⑤ —— 0-1背包问题 滚动数组优化 完全背包问题是动态规划中的一种经典问题&#xff0c;它与0-1背包问题相似&#xff0c;但有一个关键的区别&#xff1a;在完全背包问题中&#xff0c;每种物品都有无限的数量可用。…