SpringBoot集成JPA及基本使用

前言

在讲解SpringBoot集成JPA之前,先简单了解一下几个概念,JDBC、ORM、JPA以及Spring Data JPA。

1.1 JDBC

JDBC(Java DataBase Connectivity),是java连接数据库操作的原生接口API,为开发者访问数据库提供标准的接口。各数据库厂商依照JDBC规范,实现规范中的接口,实现数据库的连接。Java开发者使用同样的访问代码,配置不同的Driver、url以及账号,即可实现不同数据库厂家的数据库连接。

当数据库连接之后,通过拼接SQL语句,发送到数据库,达到对数据库中数据的操作。

缺点:

1)业务代码耦合SQL字符串拼接语句,维护比较麻烦;

2)不符合Java面向对象的编程思想;

1.2 ORM

对象-关系映射(Object-Relational Mapping,简称ORM),是一种描述对象与关系数据库之间映射的规范,采用面向对象编程的思想,操作数据库。

在Java中,ORM就是将Java类与DB中的Table表进行映射,代码中对相关Java类的操作,关联到数据库后,即体现为DB中关联的Table表的操作。

1.3 JPA

JPA是Java Persistence API的简称,中文名Java持久层API,是JDK5.x版本引入的。JPA的宗旨是为POJO提供持久化标准规范。

JAP采用ORM对象关系映射,以Java面向对象的编程思想,在javax.persistence包下提供对实体对象的CRUD操作,将开发者从繁琐的JDBC和SQL代码中解脱出来。

1.4 Spring Data JPA

Spring Data JPA是Spring提供的一套简化JPA开发的框架,按照约定好的方法名命规则写DAO层接口,可以在不写接口实现的情况下,实现对数据库中Table的操作,同时提供了除CRUD操作之外的许多功能,如分页、复杂查询等。

SpringBoot集成Spring Data JPA

2.1 引入依赖

在SpringBoot项目的pom.xml中引入相关依赖。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 参数校验 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!-- JPA是针对数据库的操作,需要引入对应的数据库 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>compile</scope>
        </dependency>

2.2 参数配置

在application.yml中配置数据库连接信息。

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowMultiQueries=true
    username: root
    password: 123456
    druid:
      stat-view-servlet:
        login-username: druid
        login-password: 123456
        url-pattern: /druid/*
        enabled: true
      filters: stat,wall
      web-stat-filter:
        url-pattern: /
        enabled: true
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
      filter:
        wall:
          config: #支持单个事物多条sql语句执行
            multi-statement-allow: true
            none-base-statement-allow: true
          enabled: true
  jpa:
    hibernate:
      naming:
        #Java代码实体字段命名与数据库表结构字段之间的名称映射策略
        #当没有使用@Table和@Column注解时,implicit-strategy配置项才会被使用,当对象模型中已经指定时,
        #implicit-strategy并不会起作用。
        #implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
        #physical-strategy一定会被应用,与对象模型中是否显式地指定列名或者已经被隐式决定无关,
        #SpringPhysicalNamingStrategy:表名,字段为小写,当有大写字母的时候会添加下划线分隔符号,默认值。
        #PhysicalNamingStrategyStandardImpl:直接映射,不会做过多的处理,会禁止将驼峰转为下划线
        #physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    # 用于指定 Session 是否在视图渲染完成后自动关闭,默认为false,意味着在视图渲染完成后,session会自动关闭
    open-in-view: false
    # 控制是否打印运行时的SQL语句与参数信息
    show-sql: true

说明:spring.jpa.open-in-view通常设置为false,即当视图渲染完成后,Session自动关闭。Spring使用AOP(面向切面编程思想)管理事务,在方法调用前和调用后插入事务处理逻辑。如果open-in-view设置为true时,由于Session保持打开状态,可能导致事务的隔离性问题。另外,在多线程环境中,如果多个线程共享同一个Session,并且该Session的open-in-view设置为true,也可能导致事务的隔离性问题。

2.3 添加数据库表实体类Entity

package com.jingai.jpa.dao.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.util.Date;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
@JsonIgnoreProperties(value = { "hibernateLazyInitializer"})
@Table(name = "tb_product")
public class ProductEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long pid;

    private String name;

    private String deliveryNo;

    private String customer;

    private String securityCode;

    private Date createTime;

    private Date validateTime;

    private int validateNum;

}

说明:如果数据库访问时报com.fasterxml.jackson.databind.exc.InvalidDefinitionException异常,是因为在转化成json的时候,fasterxml.jackson将对象转换为json报错,发现有字段值为null。底层的hibernate会给被管理的Entity加入一个hibernateLazyInitializer属性,jsonplugin会把hibernateLazyInitializer也拿出来操作,并读取里面一个不能被反射操作的属性就产生了这个异常。

2.4 添加Repository

继承JpaRepository接口,自动提供了基本的CRUD、分页、批量保存接口。

package com.jingai.jpa.dao;

import com.jingai.jpa.dao.entity.ProductEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface ProductRepository extends JpaRepository<ProductEntity, Long> {

    List<ProductEntity> findByPidBetween(long startPid, long endPid);

    @Query("from ProductEntity where name like ?1")
    List<ProductEntity> searchByName(String name);

}

在Repository接口中,除了JpaRepository自动提供的接口以外,可以自定义接口。

1)通过Spring Data JPA的命名规范,直接定义接口,无需写Sql语句;

2)使用自定义的SQL语句;

2.5 添加Service

package com.jingai.jpa.service;

import com.jingai.jpa.dao.entity.ProductEntity;

import java.util.List;

public interface ProductService {

    ProductEntity save(ProductEntity entity);

    ProductEntity getById(long id);

    List<ProductEntity> findByPidBetween(long start, long end);

    List<ProductEntity> searchByName(String name);

    int batchSave(List<ProductEntity> list)

}

2.6 添加Service实现类

在Service实现类中,引入Repository对象,对数据库表进行操作。在此处,不仅可以使用ProductRepository中定义的searchByName和findByIdBetween(),而且还可以访问save、getById以及saveAll,这些是在JpaRespository中提供的实现。

package com.jingai.jpa.service.impl;

import com.jingai.jpa.dao.ProductRepository;
import com.jingai.jpa.dao.entity.ProductEntity;
import com.jingai.jpa.service.ProductService;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.List;

@Service
public class ProductServiceImpl implements ProductService {

    @Resource
    private ProductRepository productRepository;

    @Override
    public ProductEntity save(ProductEntity entity) {
        return productRepository.save(entity);
    }

    @Override
    public ProductEntity getById(long id) {
        return productRepository.getById(id);
    }

    @Override
    public List<ProductEntity> findByPidBetween(long startPid, long endPid) {
        return productRepository.findByPidBetween(startPid, endPid);
    }

    @Override
    public List<ProductEntity> searchByName(String name) {
        return productRepository.searchByName("%" + name + "%");
    }

    @Override
    public int batchSave(List<ProductEntity> list) {
        return productRepository.saveAll(list).size();
    }

}

2.7 添加Controller

package com.jingai.jpa.controller;

import com.jingai.jpa.dao.entity.ProductEntity;
import com.jingai.jpa.service.ProductService;
import com.jingai.jpa.util.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.persistence.EntityNotFoundException;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.Map;

@Slf4j
@Validated
@RestController
@RequestMapping("product")
public class ProductController {

    @Resource
    private ProductService productService;

    @GetMapping("get")
    public Map<String, Object> get(@NotNull(message = "id不能为空") @Min(value = 1, message = "id无效") Long id) {
        ProductEntity entity = productService.getById(id);
        try {
            if (entity == null || !StringUtils.hasText(entity.getSecurityCode())) {
                log.info(String.format("id为%d的记录不存在", id));
            }
        } catch(EntityNotFoundException e) {
            return ResponseUtil.fail(String.format("id为%d的记录不存在", id));
        }
        return ResponseUtil.success(entity);
    }

}

在Controller类中引入Service,访问Service的提供的接口,实现对数据库的操作。其他接口的访问也是使用类似的方法,此处就不在贴代码了。

说明:@Validated、@NotNull、@Min为参数校验,详见:Spring validation参数校验基本使用_spring validate 参数-CSDN博客

Repository方法命名规则

规则:findBy(关键字)+ 属性名称(属性名称的首字母大写)+ 查询条件(首字母大写)

方法名词命名规范表

关键字     示例SQL表达式
AndfindByCol1AndCol2(val1, val2)where col1 = ?1 and col2 = ?2
OrfindByCol1OrCol2(val1, val2)where col1 = ?1 or col2 = ?2
Is、EqualsfindByColumn(val)、
findByColumnIs(val)、
findByColumnEquals(val)
where column = ?1
BetweenfindByColBetween(val1, val2)where col between ?1 and ?2
LessThan、BeforefindByColLessThan(val)、
findByColBefore(val)
where col < ?1
LessThanEqualfindByColLessThanEqual(val)whre col <= ?1
GreaterThan、AfterfindByColGreaterThan(val)、
findByColAfter(val)
where col > ?1
GreaterThanEqualfindByColGreaterThanEqual(val)where col >= ?1
IsNullfindByColIsNull()where col is null
IsNotNull、NotNullfindByColIsNotNull()、
findByColNotNull()
where col is not null
LikefindByColLike(val)where col like ?1
NotLikefindByColNotLike(val)where col not like ?1
StartingWithfindByColStartingWith(val)where col like ?1
(参数增加前缀%)
EndingWithfindByColEndingWith(val)where col like ?1
(参数增加后缀%)
ContainingfindByColContaining(val)where col likt ?1
(参数被%包裹)
OrderByfindByCol1OrderByCol2Asc(val)where col1 = ?1 order by col2 asc
NotfindByColNotwhere col <> ?1
InfindByColIn(Collection<?> val)where col in ?1
NotInfindByColNotIn(Collection<?> val)where col not in ?1
TruefindByColTrue()where col = true
FalsefindByColFalse()where col = false
IgnoreCasefindByColIgnoreCase(val)where upper(col) = upper(?1)

小结

限于篇幅,SpringBoot集成Spring Data JPA及基本使用就分享到这里。

关于本篇内容你有什么自己的想法或独到见解,欢迎在评论区一起交流探讨下吧。

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

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

相关文章

【MySQL 所遇问题】

【MySQL 所遇问题】 总结&#xff1a;Error Code: 1064.You have an error in your SQL syntax报错解释1&#xff1a;报错解释2处理过程 Error Code&#xff1a;1366 - Incorrect string value:报错解释处理过程 总结&#xff1a; Error Code: 1064 不可见字符。 某些文本处理…

java8 Stream流常用方法(持续更新中...)

java8 Stream流常用方法 1.过滤数据中年龄大于等于十八的学生2.获取对象中其中的一个字段并添加到集合(以学生姓名&#xff08;name&#xff09;为例)3.获取对象中其中的一个字段并转为其他数据类型最后添加到集合(以学生性别&#xff08;sex&#xff09;为例&#xff0c;将Str…

解析链动2+1模式:探寻电商新商业契机

大家好&#xff0c;我是微三云周丽 在当今数字化时代&#xff0c;电商行业日新月异&#xff0c;不断涌现出各种创新商业模式。其中&#xff0c;链动2121模式以其独特的商业逻辑和快速裂变的特性&#xff0c;吸引了众多用户和企业家的关注。本文将深入剖析链动2121模式的运作机…

在 Windows 系统上安装 TeamViewer 13

在 Windows 系统上安装 TeamViewer 13 References 默认安装到所有用户 同意协议 安装目录 勾选内容 打开文件位置 打开 rClientID.exe Extras -> Options -> Advanced Show advanced options -> Display language 重新启动TeamViewer 语言可修改为中文简体 …

快团团同城落地配怎么一键开团?免费配送设置教程!

1&#xff09;点击快团团小程序底部的【一键开团】找到【物流方式】 2&#xff09;选择物流方式为【顾客自提】后&#xff0c;点击【设置自提点】 3&#xff09;选择自提点 4&#xff09;可勾选已设置的自提点&#xff0c;或是点击【添加自提点】 5&#xff09;设置好自提点…

自制贪吃蛇小游戏

此片文章涉及到到控制台设置的相关操作&#xff0c;虚拟键码&#xff0c;宽字符输出等&#xff0c;有些地方大家可能会看不懂&#xff0c;可以阅读以下文章来进一步了解&#xff1a; 控制台程序设置-CSDN博客 效果展示&#xff1a; QQ2024428-181932 源码已放在文章结尾 目录 …

【while循环】

目录 什么是循环 while语句的执行过程 编程求1*2*3*...*n 所有不超过1000的数中含有数字3的自然数 求数 求数II 编程求1平方2平方...n平方 什么是循环 循环就是重复做同样的事儿使用while语句循环输出1到100 int i 1; while( i < 100 ){cout <<…

ES练习项目-酒店搜索

目录 1 需求分析2 酒店搜索和分页2.1 请求和响应分析2.2 定义实体类&#xff0c;接收请求参数的JSON对象2.3 编写controller&#xff0c;接收页面的请求2.4 编写业务实现&#xff0c;利用RestHighLevelClient实现搜索、分页 3. 酒店结果过滤3.1 请求和响应分析3.2 修改请求参数…

java-stream流案例

需求 代码 Vote类 // 1. 定义一个投票类 public class Vote {private String name;private ArrayList<String> voteList;public Vote(String name, ArrayList<String> voteList) {this.name name;this.voteList voteList;}public String getName() {return nam…

比较LLM和RAG技术:塑造AI的未来

在人工智能&#xff08;AI&#xff09;的动态领域中&#xff0c;两项突破性技术——大型语言模型&#xff08;LLM&#xff09;和检索增强生成&#xff08;RAG&#xff09;因其在理解和生成类人文本方面的变革潜力而脱颖而出。本文开始了LLM和RAG之间的比较之旅&#xff0c;阐明…

ROS2专栏(三) | 理解ROS2的动作

​ 1. 创建一个动作 目标&#xff1a; 在ROS 2软件包中定义一个动作。 1.1 新建包 设置一个 workspace 并创建一个名为 action_tutorials_interfaces 的包&#xff1a; mkdir -p ros2_ws/src #you can reuse existing workspace with this naming convention cd ros2_ws/s…

C++:拷贝构造函数与赋值的区别

目录 拷贝构造函数 拷贝构造函数的使用方法 拷贝构造函数与赋值运算符的区别 谈深拷贝和浅拷贝 浅拷贝 注意: 深拷贝 拷贝构造函数 拷贝构造函数的也是一种构造函数,它的作用是将一个类的成员拷贝到另一个类中,类似于赋值。拷贝构造函数分为深拷贝和浅拷贝。 先来定义一…

【MySQL 5.7安装时候 出现2503报错,解决方案】

MySQL5.7 安装遇 2503问题如何解决 1.能正常安装就点这里2.出现2503问题就看这2.1先看问题2.1.1在官网下载好安装包后&#xff0c;首先先确认安装包是否完整&#xff0c;排除安装包损坏的问题2.1.2 安装时候出现这个2503问题 2.2上解决方案2.2.1 打开任务管理器2.2.2 解决 1.能…

网盘—上传文件

本文主要讲解网盘里面关于文件操作部分的上传文件&#xff0c;具体步骤如下 目录 1、实施步骤&#xff1a; 2、代码实现 2.1、添加上传文件协议 2.2、添加上传文件槽函数 2.3、添加槽函数定义 2.4、关联上传槽函数 2.5、服务器端 2.6、在服务器端添加上传文件请求的ca…

4G远程温湿度传感器在农业中的应用—福建蜂窝物联网科技有限公司

解决方案 农业四情监测预警解决方案 农业四情指的是田间的虫情、作物的苗情、气候的灾情和土壤墒情。“四情”监测预警系统的组成包括管式土壤墒情监测站、虫情测报灯、气象站、农情监测摄像机&#xff0c;可实时监测基地状况,可以提高监测的效率和准确性&#xff0c;为农业生…

分布式系统事务一致性解决方案(基于事务消息)

参考&#xff1a;https://rocketmq.apache.org/zh/docs/featureBehavior/04transactionmessage/ 文章目录 概要错误的方案方案一&#xff1a;业务方自己实现方案二&#xff1a;RocketMQ 事务消息什么是事务消息事务消息处理流程事务消息生命周期使用限制使用示例使用建议 概要 …

进迭时空宣布开源RISC-V芯片的AI核心技术

仟江水商业电讯&#xff08;4月29日 北京 委托发布&#xff09;4月29日&#xff0c;在“创芯生生不息——进迭时空2024年度产品发布会”上&#xff0c;进迭时空CEO、创始人&#xff0c;陈志坚博士宣布将开源进迭时空在自研RISC-V AI CPU上的核心技术&#xff0c;包括AI扩展指令…

数据科学导论续

一、大数据采集的流程和方法 大数据采集的流程和方法 系统日志采集方法 很多互联网企业都有自己的海量数据采集工具&#xff0c;多用于系统日志采集&#xff0c;例如&#xff1a; Flume&#xff1a;分布式日志收集系统&#xff0c;最初由Cloudera开发&#xff0c;现是Apache的…

SPSS之判别分析

SPSS的判别分析过程中默认使用的是Fisher判别法和Bayes判别法&#xff0c;并以前者为主&#xff0c;在指定选项后也可以给出Bayes判别法的结果。 SPSS中判别分析在【分析】—【分类】—【判别】中完成。选定类别变量放入【分组变量】框中&#xff0c;单击定义范围(D)按钮给出类…

《Fundamentals of Power Electronics》——Buck、Boost、Buck-Boost三个电路的CCM-DCM工作特性总结

Buck、Boost、Buck-Boost这三个电路的CCM-DCM工作特性总结如下表所示&#xff1a; Buck、Boost、Buck-Boost这三个电路工作在DCM模式下电压传输比的对比图如下所示&#xff1a; 由上图可知&#xff0c;Buck-Boost电路的工作特性是一条斜率为的直线&#xff0c;Buck电路和Boost电…
最新文章