快速入门Spring Data JPA

Spring Data JPA是Spring Data框架的一小部分,它能够让开发者能够更加简单的对数据库进行增删改查。

由于Spring Data JPA可以自动生成SQL代码所以一般情况下,简单的增删查改就可以交给Spring Data JPA来完成,而复杂的动态SQL等用MyBatis来完成。

Spring Data JPA的入门非常简单,接下来请看正文(我使用的是MySQL数据库):

快速入门Spring Data JPA

首先我们先创建一个数据库和表,创建数据库和表的SQL代码如下:

-- 如果存在text数据库就删除该数据库
drop database if exists text;
-- 创建名为text的数据库
create database text charset utf8;use text;-- 用户表
create table user_info(id INT(11) primary key AUTO_INCREMENT,user_name VARCHAR(20) NOT NULL,gender INT(1) NOT NULL COMMENT '0.男;1.女',create_time DATETIME
);

创建一个空的Spring项目,我使用的是Spring Boot创建的项目。pom文件中引入的依赖如下:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombook:用来自动生成get,set,toString和构造方法等--><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><!--MySQL驱动--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!--Spring Data JPA依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency></dependencies>

因为Spring Boot默认支持的数据库是H2,所以如果想要使用其他的数据库就必须配置application.properties文件,所以在依赖引入之后还需要修改配置文件,配置文件中除了设置数据库的配置之外还需要设置JPA的配置,但是这个配置也非常简单,只有一行,代码如下:

spring.jpa.hibernate.ddl-auto=update
#设置显示SQL代码
spring.jpa.show-sql=true

spring.jpa.hibernate.ddl-auto的取值值有4种:

  • none: MySQL默认的配置。不能修改数据库结构;
  • update: Hibernate能够根据给定实体类结构来修改数据库;
  • create: 每次都创建数据库,但是在关闭后并不进行删除;
  • create-drop: 创建数据库,并且当SessionFactory关闭时删除它。

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的JavaEE架构中取代CMP,完成数据持久化的重任。

创建JAVA实体类:

package com.example.spring.jpa;import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;import javax.persistence.*;
import java.util.Date;@Data
@Entity
@Table(name = "user_info")
public class UserInfo {@Id@Column(name="id")@GeneratedValue(strategy = GenerationType.AUTO)private Integer id;@Column(name="user_name")private String userName;@Column(name="gender")private Integer gender;@Column(name="create_time")private Date createTime;
}

@Data: 该注解是Lombook的注解,添加这个注解后程序会在编译阶段自动生成get,set,toString,无参构造方法等基础方法。

@Entity: 该注解表示这个类是一个JPA实体。

@Table: 该注解表示这个实体和数据库中表的对应关系。如果没有该注解就默认对应的数据库中表的名称为类名即:UserInfo。name属性的值为数据库中对应的表名。

@Id: 表示该属性为主键。

@Column: 该注解表示这个属性和数据库中字段的对应关系。name属性的值为数据库中对应的字段名。如果没有该注解则默认属性名就是字段名。

@GeneratedValue: 提供主键值的生成策略规范。有四种取值默认为AUTO即自动生成ID。

编写持久层的代码,只需要加上@Repository注解并继承CrudRepository接口,接口传的类型为<实体类型,主键类型>:

package com.example.spring.jpa;import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;@Repository
public interface UserRepository extends CrudRepository<UserInfo, Integer> {
}

编写业务逻辑层代码:

package com.example.spring.jpa;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service
public class JpaService {@Resourceprivate UserRepository userRepository;//添加数据public Object insertUserInfo(UserInfo userInfo) {return userRepository.save(userInfo);}//根据id删除数据public void deleteUserInfo(Integer id) {userRepository.deleteById(id);}//修改数据public Object update(UserInfo userInfo) {return userRepository.save(userInfo);}//查找数据public Object selectUserInfo() {return userRepository.findAll();}
}

这些方法都是来自CrudRepository接口,它里面定义了常用CRUD接口。

如果你仔细观察就会发现插入数据和修改数据使用的是同一个接口,它会根据主键值是否存在于数据库中来判断是修改还是插入。

编写控制层接口:

package com.example.spring.jpa;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
@RequestMapping("/jpa")
public class Controller {@Resourceprivate JpaService jpaService;@RequestMapping("/delete")public void delete(Integer id) {jpaService.deleteUserInfo(id);}@RequestMapping("/select")public Object select() {return jpaService.selectUserInfo();}@RequestMapping("/insert")public Object insert(UserInfo userInfo) {return jpaService.insertUserInfo(userInfo);}@RequestMapping("/update")public Object update(UserInfo userInfo) {return jpaService.update(userInfo);}
}

到此为止你已经入门了

JAP是如何区分你是想要插入数据,还是修改数据?

接下来我们使用Postman进行测试,用结果和它所对应现象来说话

细心的小伙伴可能会发现当程序刚一启动数据库中就自动创建了一个不认识的表:

如果没注意的话你可以将数据库删除重新创建,然后再重新启动一边程序。

那么这个表是干啥的?有啥用呢?往下看

根据控制台打印的SQL语句我们可以知道,程序先查询并设置了hibernate_sequence表中的内容,然后才进行的插入操作,注意此时我们没有给id传值

执行完修改操作后我们可以从响应中发现修改成功了,接下来我们再看一下控制台打印的SQL语句,注意此时我们给id传值了

 我们可以发现程序是先根据id来查找到值之后才进行的修改。

接下来我们再插入时给id赋予初值然后再来看结果:

注意看:此时的SQL语句中可以看出来程序是先根据id查找表中的对应书据,发现没找到,然后才查询并设置了hibernate_sequence表中的内容,然后才进行的插入操作。

总结:

程序会先判断主键是否有初值,如果没有就执行插入操作;否则根据该值来查找对应的数据,如果找到就执行修改操作;否则就执行插入操作;

针对项目自定义查询

我们上面使用操作数据库的方法都是CrudRepository接口中的方法,那么就算它再全也不可能覆盖所有的接口,所以我们还可以针对自己的项目进行自定义接口,例如我现在想要根据gender来查询用户信息:

在UserRepository接口中添加一个方法:

package com.example.spring.jpa;import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;import javax.persistence.criteria.CriteriaBuilder;
import java.util.List;@Repository
public interface UserRepository extends CrudRepository<UserInfo, Integer> {List<UserInfo> findByGender(Integer gender);
}

为了方便起见,我们直接在控制层调用:

@RequestMapping("/selectByGender")
public Object select(Integer gender) {return userRepository.findByGender(gender);
}

注意:虽然他给了我们自定义接口的能力,但是接口的命名必须符合要求。在IDEA中编译器就会进行提示:

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分类损失函数与评估指标

目录 1 评估指标 1.1 准确率 1.2 精确率 1.3 召回率 1.4 F1 score 1.5 ROC曲线 1.6 AUC 1.7 PRC曲线的优势 2 损失函数 1. 负对数似然损失 2. 交叉熵损失 3. 指数损失 3 分类问题为什么用交叉熵损失不用 MSE 损失 1 评估指标 混淆矩阵 TP(True Positive) ---- 正…

xxl-job使用自动注册节点,ip不对,如何解决????

很明显这时我们本机的ip和我们xxl-job自动注册的ip是不一致的&#xff0c;此时该如何处理呢&#xff1f;&#xff1f;&#xff1f;&#xff1f; 方法一&#xff1a;在配置文件中&#xff0c;将我们的ip固定写好。 ### xxl-job executor server-info xxl.job.executor.ip写你的…

【LAMMPS学习】八、基础知识(3.3)使用分布式网格

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

Vue加载glb / gltf模型(如何在vue中使用Three.js,vue使用threejs加载glb模型)

简介&#xff1a;Three.js 是一个用于在 Web 上创建和显示 3D 图形的 JavaScript 库。它提供了丰富的功能和灵活的 API&#xff0c;使开发者可以轻松地在网页中创建各种 3D 场景、模型和动画效果。可以用来展示产品模型、建立交互式场景、游戏开发、数据可视化、教育和培训等等…

配置路由器实现互通

1.实验环境 实验用具包括两台路由器(或交换机)&#xff0c;一根双绞线缆&#xff0c;一台PC&#xff0c;一条Console 线缆。 2.需求描述 如图6.14 所示&#xff0c;将两台路由器的F0/0 接口相连&#xff0c;通过一台PC 连接设备的 Console 端口并配置P地址&#xff08;192.1…

C++|运算符重载(2)|运算符重载的方法与规则

写在前面 上篇介绍到&#xff0c;为什么要进行运算符重载&#xff1a;是因为我们希望预定义的内部运算符&#xff0c;在特定的类对象上亦可以直接使用。 C|运算符重载&#xff08;1&#xff09;|为什么要进行运算符重载-CSDN博客https://blog.csdn.net/weixin_74197067/artic…

Spring Boot 多环境配置:YML 文件的三种高效方法

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

06节-51单片机-LCD1602调试工具

欢迎订阅专栏&#xff0c;持续为您更新&#xff01; 1.LCD1602调试工具 使用LCD1602液晶屏作为调试窗口&#xff0c;提供类似printf函数的功能&#xff0c;可实时观察单片机内部数据的变换情况&#xff0c;便于调试和演示。 本文提供的LCD1602代码属于模块化的代码&#xff…

Java集合-泛型(Generic)

目录 1、泛型(Generic) 1.1 泛型方法 1.2 泛型类 1.3 泛型接口 1.4 泛型通配符 1、泛型(Generic) 当集合中存储的对象类型不同时&#xff0c;那么会导致程序在运行的时候的转型异常 import java.util.ArrayList; import java.util.Iterator; public class Demo5 { pub…

Samtec应用分享 | 汽车应用中的视觉系统

【前言】 视觉系统在未来的汽车设计中扮演着关键的角色。 在过去&#xff0c;一直是由驾驶员掌握和应对道路上的危险&#xff0c;但现代车辆在保障驾驶安全方面发挥着前所未有的作用。 视觉系统&#xff0c;无论是可见光摄像头还是先进的探测系统&#xff0c;如激光雷达&…

rk3588 安卓调试

rknn装上了android系统&#xff0c;用type-c usb连接上电脑&#xff0c;设备管理器发现了rk3588&#xff0c;但是Android Studio没有发现设备 后来怀疑是驱动没有安装&#xff0c;我用的驱动下载地址&#xff1a; 瑞芯微Rockchip驱动安装助手(适用于RK3308 RK3399等) Mcuzone…

ARP代理

10.1.0.1/8 和10.2.0.1/8是在同一个网段 10.1.0.2/16 和10.2.0.2/16 不在同一个网段 10.1.0.1/8 和10.1.0.2/16 是可以ping通的 包发出来了&#xff0c;报文有发出来&#xff0c;目的地址是广播包 广播请求&#xff0c;发到路由器的接口G 0/0/0 target不是本接口&#xff0…