Spring Boot中使用Spring Data JPA访问MySQL

Spring Data JPA是Spring框架提供的用于简化JPA(Java Persistence API)开发的数据访问层框架。它通过提供一组便捷的API和工具,简化了对JPA数据访问的操作,同时也提供了一些额外的功能,比如动态查询、分页、排序等。

当我们在经历过真正的开发之后,我们会发现,在实际开发过程中,我们对数据库的操作主要为“增删改查”。最为普通的单表操作而言,除了表和字段不同外,语句基本上都是类似的,作为开发者的我们,经常需要写大量类似并未枯燥无聊的语句类完成我需要的业务逻辑。

为了避免这些重复且无趣的操作,部分开发者,为我们提供许多优秀的开发框架,其中包括Hibernate,MyBatis等。而我们今天围绕的Spring Data JPA就是在Hibernate的基础上进行的。Hibernate架构如下:

在这里插入图片描述
不要小看这张图,2023年,11月份软考架构师就是考了张图的。

因为Spring Data JPA依赖于Hibernate。接下来我们围绕一个demo来使用Spring Data JPA。

JPA依赖

要使用Spring Data JPA,首先需要在项目中引入相应的依赖。在Maven项目中,可以在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

demo依赖:

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>

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

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
        <dependency>
            <groupId>com.oracle.ojdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>19.3.0.0</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

配置连接MYSQL配置类

在Spring Boot中配置文件中配置数据库连接信息,自动创建表和删除表的配置。如下最后一行:

spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

server.port=1001
#spring.datasource.url=jdbc:oracle:thin:@localhost:1521/orcl
#spring.datasource.username=root
#spring.datasource.password=root
#spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver

#hibernate配置
spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop

spring.jpa.properties.hibernate.hbm2ddl.auto是hibernate的配置属性,其主要作用是:自动创建、更新、验证数据库表结构。该参数的几种配置如下:

  • create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
  • create-drop:每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
  • update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会。
  • validate:每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。

User实体类

@Entity
//@Data
//@NoArgsConstructor
public class User {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private Integer age;

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public User(Long id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    
}

@Entity注解标识了User类是一个持久化的实体
@Data@NoArgsConstructor是Lombok中的注解。用来自动生成各参数的Set、Get函数以及不带参数的构造函数。(博主并不喜欢直接使用这里边的注解,故而全是手动构建的)
@Id@GeneratedValue用来标识User对应对应数据库表中的主键

创建一个接口

User实体创建对应的Repository接口实现对该实体的数据访问:

public interface UserRepository extends JpaRepository<User, Long> {

    User findByName(String name);

    User findByNameAndAge(String name, Integer age);

    @Query("from User u where u.name=:name")
    User findUser(@Param("name") String name);
}

在Spring Data JPA中,只需要编写类似上面这样的接口就可实现数据访问。不再像我们以往编写了接口时候还需要自己编写接口实现类,直接减少了我们的文件清单。

下面对上面的UserRepository做一些解释,该接口继承自JpaRepository,通过查看JpaRepository接口的API文档open in new window,可以看到该接口本身已经实现了创建(save)、更新(save)、删除(delete)、查询(findAll、findOne)等基本操作的函数,因此对于这些基础操作的数据访问就不需要开发者再自己定义。

在我们实际开发中,JpaRepository接口定义的接口往往还不够或者性能不够优化,我们需要进一步实现更复杂一些的查询或操作。
User findByName(String name)
User findByNameAndAge(String name, Integer age)

它们分别实现了按name查询User实体和按name和age查询User实体,可以看到我们这里没有任何类SQL语句就完成了两个条件查询方法。这就是Spring-data-jpa的一大特性:通过解析方法名创建查询。

除了通过解析方法名来创建查询外,它也提供通过使用@Query 注解来创建查询,您只需要编写JPQL语句,并通过类似“:name”来映射@Param指定的参数,就像例子中的第三个findUser函数一样。

创建一个测试类

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void test() throws Exception {

        // 创建10条记录
        userRepository.save(new User(1l,"AAA", 10));
        userRepository.save(new User(2l,"BBB", 20));
        userRepository.save(new User(3l,"CCC", 30));
        userRepository.save(new User(4l,"DDD", 40));
        userRepository.save(new User(5l,"EEE", 50));
        userRepository.save(new User(6l,"FFF", 60));
        userRepository.save(new User(7l,"GGG", 70));
        userRepository.save(new User(8l,"HHH", 80));
        userRepository.save(new User(9l,"III", 90));
        userRepository.save(new User(10l,"JJJ", 100));

        // 测试findAll, 查询所有记录
        Assert.assertEquals(10, userRepository.findAll().size());

        // 测试findByName, 查询姓名为FFF的User
        Assert.assertEquals(60, userRepository.findByName("FFF").getAge().longValue());

        // 测试findUser, 查询姓名为FFF的User
        Assert.assertEquals(60, userRepository.findUser("FFF").getAge().longValue());

        // 测试findByNameAndAge, 查询姓名为FFF并且年龄为60的User
        Assert.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName());

        // 测试删除姓名为AAA的User
        userRepository.delete(userRepository.findByName("AAA"));

        // 测试findAll, 查询所有记录, 验证上面的删除是否成功
        Assert.assertEquals(9, userRepository.findAll().size());

    }
}

至此,Spring Data JPA案例就结束了,在Spring Data JPA中,主要覆盖了对关系型数据库的抽象以外,还有对其他数据存储中间件的实现,诸如我们常用的Redis,MongoDB,ElasticSearch等。

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

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

相关文章

数据分析:职场不可或缺的技能

前言 在当今数字化时代&#xff0c;数据分析已经变得越来越不可或缺。不论你从事哪个行业&#xff0c;不论你在职场的哪个阶段&#xff0c;数据分析技能都将成为你在工作中脱颖而出的秘密武器。本文将阐明数据分析的重要性&#xff0c;以及如何学习数据分析&#xff0c;以及如…

MobaXterm配置SSHTunnel

本地与远程服务器之间存在防火墙&#xff0c;防火墙只允许SSH端口通过&#xff0c;为访问远程服务器&#xff0c;我们可以借助MobaXterm来与SSH服务器建立隧道&#xff0c;使得防火墙外的用户能够访问远程服务器 配置 打开SSHTunnel 新建SSH tunnel 点击开启就生效了&…

多门店自助点餐+外卖二合一小程序源码系统 带完整搭建教程

随着餐饮业的快速发展和互联网技术的不断进步&#xff0c;越来越多的餐厅开始采用自助点餐和外卖服务。市场上许多的外卖小程序APP应运而生。下面罗峰来给大家介绍一款多门店自助点餐外卖二合一小程序源码系统。该系统结合了自助点餐和外卖服务的优势&#xff0c;为餐厅提供了一…

测试老鸟整理,Postman加密接口测试-Rsa/Aes对参数加密(详细总结)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 一些问题 postma…

前端框架Vue学习 ——(五)前端工程化Vue-cli脚手架

文章目录 Vue-cliVue项目-创建Vue项目-目录结构Vue项目-启动Vue项目-配置端口Vue项目开发流程 Vue-cli 介绍&#xff1a;Vue-cli 是 Vue 官方提供的一个脚手架&#xff0c;用于快速生成一个 Vue 的项目模版 安装 NodeJS安装 Vue-cli npm install -g vue/cliVue项目-创建 图…

Java代码如何对Excel文件进行zip压缩

1&#xff1a;新建 ZipUtils 工具类 package com.ly.cloud.datacollection.util;import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URLEncoder; import ja…

iOS Crash 治理:淘宝VisionKitCore 问题修复

本文通过逆向系统&#xff0c;阅读汇编指令&#xff0c;逐步找到源码&#xff0c;定位到了 iOS 16.0.<iOS 16.2 WKWebView 的系统bug 。同时苹果已经在新版本修复了 Bug&#xff0c;对于巨大的存量用户&#xff0c;仍旧会造成日均 Crash pv 1200 uv 1000&#xff0c; 最终通…

爬虫采集外卖数据用于竞争对手分析

因为我无法直接编写和运行代码。但我可以为大家提供编写爬虫程序的一般步骤和方法&#xff1a; 1、导入所需库&#xff1a;在Python中&#xff0c;您可以使用requests库来发送HTTP请求&#xff0c;并使用BeautifulSoup库来解析HTML。 import requests from bs4 import Beautif…

Web服务器实战

网站需求 1.基于域名www.openlab.com可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个网站目录分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c;基于www.openlab.com/student 网站访问学生信息&#xff0c;www.openlab.com/data网站访问教学资料 www…

Vue路由重定向

一、Vue路由-重定向 1.问题 网页打开时&#xff0c; url 默认是 / 路径&#xff0c;如果未匹配到组件时&#xff0c;会出现空白 2.解决方案 重定向 → 匹配 / 后, 强制跳转 /home 路径 3.语法 { path: 匹配路径, redirect: 重定向到的路径 }, 比如&#xff1a; { path:/ …

AI:61-基于深度学习的草莓病害识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

在jupyter中使用R

如果想在Jupyter Notebook中使用R语言&#xff0c;以下几个步骤操作可行&#xff1a; 1、启动Anaconda Prompt 2、进入R的安装位置&#xff0c;切换到R的安装位置&#xff1a;D:\Program Files\R\R-3.4.3\bin&#xff0c;启动R&#xff0c;具体代码操作步骤如下&#xff0c;在…

gitlab 设置 分支只读

一&#xff0c;设置master分支只读&#xff0c; 并且只有Maintainers 拥有合并权限。 二&#xff0c;设置成员权限 改为developer 三&#xff0c;邀请成员 点击右上角 Invite Members

iview table 表格合并单元格

一、如图所示 二、实现方式 表格用提供的span-method属性 <template><Table ref"table" border :span-method"handleSpan" :row-key"true" :columns"tableColumns" :data"tableData"no-data-text"暂无数据&…

接口测试及接口测试工具

首先&#xff0c;什么是接口呢&#xff1f; 接口一般来说有两种&#xff0c;一种是程序内部的接口&#xff0c;一种是系统对外的接口。 系统对外的接口&#xff1a;比如你要从别的网站或服务器上获取资源或信息&#xff0c;别人肯定不会把数据库共享给你&#xff0c;他只能给你…

AJAX-解决回调函数地狱问题

一、同步代码和异步代码 1.同步代码 浏览器是按照我们书写代码的顺序一行一行地执行程序的。浏览器会等待代码的解析和工作&#xff0c;在上一行完成之后才会执行下一行。这也使得它成为一个同步程序。 总结来说&#xff1a;逐行执行&#xff0c;需原地等待结果后&#xff0…

idea 2023 设置启动参数、单元测试启动参数

找到上方的editconfigration&#xff0c; 如下图&#xff0c;如果想在启动类上加&#xff0c;就选择springboot&#xff0c;如果想在单元测试加&#xff0c;就选择junit 在参数栏设置参数&#xff0c;多个参数以空格隔开 如果没有这一栏&#xff0c;就选择就可以了。 然后&…

【MongoDB】集群搭建实战 | 副本集 Replica-Set | 分片集群 Shard-Cluster | 安全认证

文章目录 MongoDB 集群架构副本集主节点选举原则搭建副本集主节点从节点仲裁节点 连接节点添加副本从节点添加仲裁者节点删除节点 副本集读写操作副本集中的方法 分片集群分片集群架构目标第一个副本集第二个副本集配置集初始化副本集路由集添加分片开启分片集合分片删除分片 安…

HK WEB3 MONTH Polkadot Hong Kong 火热报名中!

HK Web3 Month 11月除了香港金融科技周外&#xff0c;HK Web3 Month又是一大盛事&#xff0c;从10月29日开始开幕直到11月18日结束。此次将齐聚世界各地的Web3产业从业者、开发者、社群成员和学生来参与本次盛会。除外&#xff0c;超过75位产业知名的讲者与超过50场工作坊将为…

力扣算法-----一刷总结

之前学习算法题坚持不了几天就很容易放弃&#xff0c;一直没怎么系统的练习&#xff0c;偶然发现代码随想录居然推出了算法训练营&#xff0c;趁着时间比较足报了名跟着学习了两个月。 过去的两个月&#xff0c;中间伴着各种琐事&#xff0c;但还是坚持了下来&#xff0c;走过…