springdata个人学习笔记

news2025/1/18 21:10:37

入门

初始化springboot

在这里插入图片描述

依赖引入

<!--        springdata-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--        阿里巴巴数据库池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
<!--        mysql引擎-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
<!--        lombok-->
        <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>

配置文件

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/blog?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: xx
    type: com.alibaba.druid.pool.DruidDataSource
  #JPA配置
  jpa:
    database-platform: org.hibernate.dialect.MySQL5Dialect
    # 自动更新数据库表结构,也可以是 validate | update | create | create-drop
    properties:
      hibernate:
        hbm2ddl:
          auto: update
    # 显示sql语句
    show-sql: true

实体类

package com.learn.springdata.pojo;


import lombok.*;
import org.hibernate.Hibernate;

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

/**
 * 测试用户实体类
 *
 * @author itdragon
 */
@Table(name = "itdragon_user")
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserTest {
    @Id
    //GeneratedValue(生成的值)
    //strategy代表主键生成策略
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;                        // 自增长主键
    private String account;                    // 登录的账号
    //Column对一个字段进行标注,nullable:是否可为NULL
    //unique:值是否不能重复
    //name:数据库中的字段名
    @Column(nullable = false,unique = false,name = "user_name")
    private String userName;                // 注册的昵称
    //transient(暂时的) 标注此注解后在创建数据表的时候将会忽略该属性
    @Transient
    private String isTest;
    // Temporal(时间的) :向数据库映射日期(Date)属性时用来调整映射的精度。Date 类型的数据有 DATE, TIME, 和 TIMESTAMP 三种精度(即单纯的日期,时间,或者两者兼备).
    @Temporal(TemporalType.DATE)
    private Date birth;
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
        UserTest userTest = (UserTest) o;
        return id != null && Objects.equals(id, userTest.id);
    }

    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
}

效果

在这里插入图片描述

接口的springdata的书写(重点)

知识点2
  * 重点知识:SpringData 查询方法定义规范
 * 1. 查询方法名一般以 find | read | get 开头,建议用find
 * findByAccount : 通过account查询User
 * account是User的属性,拼接时首字母需大写
 * 2. 支持的关键词有很多比如 Or,Between,isNull,Like,In等
 * findByEmailEndingWithAndCreatedDateLessThan : 查询在指定时间前注册,并以xx邮箱结尾的用户
 * And : 并且
 * EndingWith : 以某某结尾
 * LessThan : 小于
 * 注意
 * 若有User(用户表) Platform(用户平台表) 存在一对一的关系,且User表中有platformId字段
 * SpringData 为了区分:
 * findByPlatFormId 	表示通过platformId字段查询
 * findByPlatForm_Id 	表示通过platform实体类中id字段查询
 * <p>
 * 开发建议
 * 表的设计,尽量做单表查询,以确保高并发场景减轻数据库的压力。
知识点3
  • 重点知识:使用 @Query 注解
    *


    * 上面的方法虽然简单(不用写sql语句),但它有最为致命的问题-----不支持复杂查询,其次是命名太长
    * 1. 使用@Query 注解实现复杂查询,设置 nativeQuery=true 使查询支持原生sql
    * 2. 配合@Modifying 注解实现创建,修改,删除操作
    * 3. SpringData 默认查询事件为只读事务,若要修改数据则需手动添加事务注解
    *


    * 注意
    * 若@Query 中有多个参数,SpringData 提供两种方法:
    * 第一种 ?1 … ?2 要求参数顺序一致
    * 第二种 :xxx … :yyy xxx 和 yyy 必须是实体类对应的属性值,不要求参数顺序但参数前要加上@Param(“xxx”)
    * 模糊查询可使用 %xxx%
    *


    * 开发建议
    * 1. 参数填写的顺序要保持一致,不要给自己添加麻烦
    * 2. 建议使用@Query,可读性较高

接口清单

JpaRepository接口提供的方法与说明

方法 描述
List<T> findAll(); 查找所有实体。
List<T> findAll(Sort var1); 排序、查找所有实体。
List<T> findAllById(Iterable<ID> var1); 返回制定一组ID的实体。
<S extends T> List<S> saveAll(Iterable<S> var1); 保存集合。
void flush(); 执行缓存与数据库同步。
<S extends T> S saveAndFlush(S var1); 强制执行持久化。
void deleteInBatch(Iterable var1); 删除一个实体集合。
void deleteAllInBatch(); 删除所有实体。
T getOne(ID var1); 返回ID对应的实体。如果不存在,则返回空值。
<S extends T> List<S> findAll(Example<S> var1); 查询满足Example的所有对象。
<S extends T> List<S> findAll(Example<S> var1, Sort var2);
查询满足Example的所有对象,并且进行排序返回

CrudRepository接口提供的方法与说明:

方法 说明
<S extends T> S save(S var1); 保存实体。当实体中包含主键时,JPA会进行更新操作。
<S extends T> Iterable<S> saveAll(Iterable<S> var1); 保存所有实体。实体必须不为空。
Optional<T> findById(ID var1); 根据主键ID检索实体。
boolean existsById(ID var1); 根据主键ID检索实体,返回是否存在。值为布尔类型。
Iterable<T> findAll(); 返回所有实体。
Iterable<T> findAllById(Iterable<ID> var1); 根据给定的一组ID值返回一组实体。
long count(); 返回实体的数量
void deleteById(ID var1); 根据ID删除数据。
void delete(T var1); 删除给定的实体。
void deleteAll(Iterable<? extends T> var1); 删除实体。
void deleteAll(); 删除所有实体。
开发建议

  1. 这里列出的是常用方法
  2. CrudRepository 中的findAll() 方法要慎用。当数据库中数据量大,多线程脚本调用findAll方法,系统可能会宕机。
  3. CrudRepository 中的deletAll()方法要慎用。这是物理删除,现在企业一般采用逻辑删除。
  4. PagingAndSortingRepository 和 JpaSpecificationExecutor 能满足大部分业务需求。

简单的增删查改

接口

public interface UserRepository extends PagingAndSortingRepository<UserTest, Long>,
        JpaSpecificationExecutor<UserTest> {
}

测试代码

    @Autowired
    UserRepository us;

    //查找所有用户
    @Test
    public void findAllUser() {
        Iterable<UserTest> usAll = us.findAll();
        usAll.forEach(System.out::println);
    }

    // 新增用户
    @Test
    public void saveUser() {
        UserTest u=new UserTest();
        u.setUserName("张三四次");
        u.setAccount("你爹");
        UserTest byAccount = us.save(u);
        System.out.println(byAccount);
    }
    //删除用户
    @Test
    public void deleteUser(){
        //方法1
        Optional<UserTest> us1 = us.findById(1L);
        UserTest test;
        //Present为存在之意,isPresent表示us1中是否存在值
        if (us1.isPresent()) {
            //没有返回值奥,和mp不一样
            us.deleteById(1L);
            System.out.println("删除成功!");
        }
        else {
            System.out.println("删除失败!");
        }
        //方法2
        try
        {
            us.deleteById(1L);
            System.out.println("删除成功!");
        }
        catch(Exception ex)
        {
            System.out.println("删除失败!");
        }
    }
    //更新用户
    @Test
    public void updateUser(){
        UserTest u=new UserTest();
        u.setUserName("张fd三四次");
        u.setAccount("你df爹");
        u.setId(2L);
        //使用的方法和新增一样
        UserTest save = us.save(u);
        System.out.println(save);
    }

使用类SQL(注解开发)

适用于复杂的业务场景

使用JPQL语句(HQL)

1 查询时使用的是实体类的字段,而不是数据库中的字段
2 变量使用:变量名的形式,在方法参数中还有使用@Param("xx")
3 更新操作需要加上 @Modifying

–接口代码–

    //查找用户id通过用户名
    @Query("select id from UserTest where userName=:name")
    List<Long> findUserIdByName(@Param("name") String name);

    //查找所有用户并排序(升)
    @Query("select userName from UserTest order by userName")
    List<String> findAllUserNameSort();
    //查找所有用户并排序(降)
    @Query("select userName from UserTest order by userName desc ")
    List<String> findAllUserNameSortDesc();

–测试代码–

    //查找用户id通过用户名
    @Test
    void findUserIdByName(){
        List<Long> ids = us.findUserIdByName("张fd三四次");
        System.out.println(ids);
    }
    //查找所有用户名并对用户名排序
    @Test
    void findAllUserName(){
        List<String> userSort = us.findAllUserNameSort();
        List<String> userSort2 = us.findAllUserNameSortDesc();
        System.out.println(userSort);
        System.out.println(userSort2);
    }

使用SQL语句

提示:
1这里的占位符使用的是?与jdbc相似,1表示第几个参数
2使用sql查询是SQL语句中的字段必须要和数据库对应
–接口代码–

    //使用SQL
    @Query(value = "select id from itdragon_user where user_name=?1",nativeQuery = true)
    List<Long> findUserIdByNameUserSQL(String name);

–测试代码–

    //使用SQL语句
    @Test
    void UserSQLTest(){
        List<Long> sql = us.findUserIdByNameUserSQL("张fd三四次3");
        System.out.println(sql);
    }

使用接口查询语法

献上一张图,内容全在其中
在这里插入图片描述
–接口–

    //使用接口查询语法
    // 1 通过账号查用户信息
    List<UserTest> findByAccount(String account);

    //2 对用户名模糊查询
    List<UserTest> findByUserNameLike(String name);

    //3 批量查找特定id的用户
    List<UserTest> findByIdIn(List<Long> ids);

    //4 查找用户名为:张fd三四次1,昵称为你df爹的用户
    UserTest findByUserNameAndAccount(String userName, String account);

–测试–

    @Test
    void UserTSTest(){
        List<UserTest> a = us.findByAccount("你df爹");
        System.out.println(a);

        List<UserTest> a1 = us.findByUserNameLike("你");
        System.out.println(a1);

        UserTest b = us.findByUserNameAndAccount("张fd三四次3", "你df爹");
        System.out.println(b);

        List<Long> ids=new ArrayList<>();
        ids.add(2L);
        ids.add(3L);
        List<UserTest> c = us.findByIdIn(ids);
        System.out.println(c);
    }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

node与node-sass版本对应

node&#xff1a;14.0.0 npm install sass-loader7.3.1 node-sass4.14.1 --savenode-sass对应node https://github.com/sass/node-sass/releases node-sass 和 sass-loader 的对应关系一般的情况下4.XX.YY&#xff0c;XX就是对应Node XX 版本 参考

Java常用工具类方法(下)

8. IOUtilsIO流在我们日常工作中也用得比较多&#xff0c;尽管java已经给我们提供了丰富的API。但我们不得不每次读取文件&#xff0c;或者写入文件之后&#xff0c;写一些重复的的代码。手动在finally代码块中关闭流&#xff0c;不然可能会造成内存溢出。有个好消息是&#xf…

一文搞懂Linux 环境变量

一文搞懂Linux 环境变量1.环境变量分类2.读取环境变量3.环境变量修改在 Linux 系统中&#xff0c;环境变量是用来定义系统运行环境的一些参数&#xff0c;比如每个用户不同的主目录&#xff08;HOME&#xff09;。 1.环境变量分类 按照作用域来分&#xff0c;环境变量可以简单…

【阶段三】Python机器学习13篇:机器学习项目实战:支持向量机分类的算法原理

本篇的思维导图: 支持向量机分类的算法原理 支持向量机分类算法的基本思路 1.最大间隔 支持向量机说到底就是一种“线性分类器”,它以“间隔”作为损失的度量,目标通过不断调整多维的“直线”——超平面,使得间隔最大化。所谓“支持向量”,就是所有数据点中直接参…

Lichee_RV学习系列---移植dhrystone

系列文章目录 Lichee_RV学习系列—认识Lichee_RV、环境搭建和编译第一个程序 文章目录系列文章目录一、dhrystone简介二、dhrystone源码下载三、dhrystone移植1、移植官方源码2、移植GitHub开源代码a&#xff1a;修改Makefile文件b&#xff1a;编译3、执行dhrstone代码总结一、…

Flink源码解析一之RPC原理解析

在阅读 Flink 源码过程中,如果你见到有这种类型的代码,其实就是在发送 RPC 请求 // resourceManagerGateway 就可以理解成: 当前节点中,对于 ResourceManager 代理对象的封 装 resourceManagerGateway.requestSlot(); // 代码跳转到:resourceManager.requestSlot()…

C++20标准下的左值与右值

C20标准下的左值与右值一、什么是左值与右值二、左值引用三、右值引用四、值类别五、标准库 move 函数5.1 用 static_cast将左值转换为右值5.2 使用 std::move 将左值转换为右值一、什么是左值与右值 左值&#xff1a;左值可以出现在赋值语句的左边或者右边右值&#xff1a;右…

Java设计模式-装饰者模式Decorator

介绍 装饰者模式的核心思想是通过创建一个装饰对象&#xff08;即装饰者&#xff09;&#xff0c;动态扩展目标对象的功能&#xff0c;并且不会改变目标对象的结构&#xff0c;提供了一种比继承更灵活的替代方案。需要注意的是&#xff0c;装饰对象要与目标对象实现相同的接口&…

VisualBox解决CentOS中yum安装失败的问题

怎么说呢&#xff0c;花了一个下午一个上午的时间&#xff0c;总算把这条命令运行成功了&#xff1a; yum install wget -y 打怪兽途中遇到了几个问题&#xff0c;总结一下&#xff1a; 1.ping 啥ip都是unkown&#xff0c;还有一种情况&#xff0c;就是ping之后就一直卡在那…

C++计算机课程设计 学生成绩管理系统 研究报告

课程设计内容 2.1 学生成绩管理系统 2.1.1 内容 主菜单模块 该模块主要用来实现整个系统的流程。主界面提供用户选择并调用各个子模块。 输入模块 当初次使用系统时&#xff0c;学生信息需要从键盘逐个输入。学生信息由学生的学号、姓名、性别、高等数学、英语、计算机和平均…

Qt基于CTK Plugin Framework搭建插件框架--CTK服务工厂

一、前言 注册服务的时候能够用服务工厂来注册&#xff1b; 访问服务getServeice中的plugin参数是执行ctkPluginContext::getService(const ctkServiceReference&)的插件&#xff0c;从而工厂根据执行的不同插件名称返回不同的服务实现 服务工厂的作用 在服务中可以知道…

达摩院2023十大科技趋势发布,生成式AI将进入应用爆发期

1月11日&#xff0c;达摩院2023十大科技趋势发布&#xff0c;生成式AI、Chiplet模块化设计封装、全新云计算体系架构等技术入选。达摩院认为&#xff0c;全球科技日趋显现出交叉融合发展的新态势&#xff0c;尤其在信息与通信技术&#xff08;ICT&#xff09;领域酝酿的新裂变&…

【关于Linux中----进程间通信方式之管道】

文章目录一、什么是管道二、匿名管道三、命名管道一、什么是管道 进程间通信主要目的为以下几点 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享同样的资源。 通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息…

STL forward_list 模拟实现

forward_list 概述 forward_list 是 C 11 新增的容器&#xff0c;它的实现为单链表。 forward_list 是支持从容器中的任何位置快速插入和移除元素的容器&#xff0c;不支持快速随机访问。forward_list 和 list 的主要区别在于&#xff0c;前者的迭代器属于单向的 Forward Ite…

二分法讲解

目录 一、前言 二、二分法理论 1、引导&#xff1a;猜数游戏 2、理论背景&#xff1a;非线性方程的求根问题 1&#xff09;非线性方程的近似解 2&#xff09;搜索法和二分法 3、用二分的两个条件 4、二分法复杂度 三、整数二分 1、在单调递增序列中找 x 或者 x 的后继…

使用python-pptx创建PPT演示文档功能实践

python对PPT演示文档读写&#xff0c;是通过第三方库python-pptx实现的&#xff0c;python-pptx是用于创建和更新 PowerPoint&#xff08;.pptx&#xff09;文件的 Python 库。 关于PPT演示文档与幻灯片模板的内容不是本文的重点&#xff0c;在此略过。 1. PPT基本结构在pyth…

Sophus降维、升维与欧拉角、旋转向量的爱恨情仇

0. 简介 在面对二维与三维之间的转换时&#xff0c;我们常常会困惑该如何去转换&#xff0c;在G2O中存在有理想的坐标转换工具&#xff0c;但是在Sophus中却缺乏这样的手段。之前在Sophus处简要的介绍了一下SE(2)与SE(3)的转换&#xff0c;最近发现之前的文章这部分需要拿出来…

Leetcode:654. 最大二叉树(C++)

目录 问题描述&#xff1a; 实现代码与解析&#xff1a; 直接模拟&#xff08;递归)&#xff1a; 原理思路&#xff1a; 索引版本&#xff1a; 问题描述&#xff1a; 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&a…

Thymeleaf从入门到清晰使用

文章目录什么是thymeleaf&#xff1f;第一个Thymeleaf程序Thymeleaf详解配置常用标签最后什么是thymeleaf&#xff1f; 模板引擎&#xff1a; 前端交给我们的页面&#xff0c;是html页面&#xff0c;如果是以前开发&#xff0c;我们需要把他们转成jsp页面&#xff0c;jsp的好处…

ABB AC500 系列 PLC 与上位机iFix 的通讯配置

ABB PLC IP 及 MODBUS TCP/IP 协议设置 通过 IP config tool 配置设备 IP 在 软件中&#xff0c;有 3 种方式可以进入 IP config tool 的配置界面  双击 IP_settings&#xff0c;点击 IP config tool&#xff0c;即可进入 IP config tool 界面 点击菜单栏的 Tool→IP confi…