[spring] Spring JPA - Hibernate 多表联查 1
[spring] Spring JPA - Hibernate 多表联查 1
之前在 [spring] spring jpa - hibernate 名词解释&配置 和 [spring] spring jpa - hibernate CRUD 简单的学习了一下怎么使用 Hibernate 实现 CRUD 操作,不过涉及到的部分都是逻辑上比较简单的实现——只在一张表上进行操作
关于多表关联的部分,只是在关键字中提到了有提到过 Relationship 的注解,之后这三章内容就会对 Relationship 进行学习
基础概念
这里回顾一下数据库的基础概念,具体的使用方式在后面的笔记中会被提到,所以这里也就不 cv 代码了
-
主键(Primary Key)& 外键(Foreign Key)
主键是一个表中的一个或多个列,能够表示当前数据在当前表中的唯一性,每个表只能有一个主键
比较常见用一个列作为主键的情况有学生 id,课程 id,书籍 id,图书馆 id 等
用多个列作为主键的情况,一般代表单独的一个列无法完整表达对应信息,如学生选修的课程,这种情况下主键可以使用学生 id+课程 id+年份,或者图书的出借记录,可以使用学生 id+书籍 id+出借日期等
外键用于引用另一张表的主键,如上面多个列作为主键的情况中,学生 id、书籍 id 都是外键
-
级联(Cascade)
Cascade 是一种为了维护数据库完整性的机制,这里不会过多的设计到数据库的 Cascade,而是提一下 hibernate 中的 Cascade 类型,也就是
CascadeType
:-
PERSIST
代表当持久化一个实体时,其关联的实体也会被实体化 -
MERGE
代表会将 detached entity 的变更数据 复制到当前 管理中的 entity。如果数据库中已有该 entity,则会 更新 现有记录;如果没有,则会 插入 新记录。虽然说是
merge
操作,不过大多数情况下merge
操作被用来当做更新 -
REMOVE
代表当删除一个实体时,其关联的实体也会被删除 (如果启用CascadeType.REMOVE
) -
REFRESH
表从 数据库重新加载最新数据,并且 丢弃内存中未提交的更改 -
DETACH
代表当更新一个分离时,其关联的实体也会被分离这个主要代表当前的 entity 不再被持久层所管理
-
ALL
代表上述所有的操作都会被执行
默认情况下,hibernate 不会 cascade 任何操作
-
-
数据加载——eager & lazy
这代表的是两种数据的获取方式,
eager
代表当 entity 被获取时,其关联的所有实体也会被同时获取 -
关系
-
one to one
即一对一的关系,比如说 国家 和 首都,用户 和 用户信息 这种都是比较常见的一对一的关系
-
one to many
一对多,也是多对一的关系,比较常见的有 作者 和 书籍,学生 和 学校
-
many to many
多对多的关系,这应该是最常见的情况了,比如说 作者 和 出版商,学生 和 课
需要注意的是,不同的关系在不同的系统中都会有些微的差异,并非不可改变。比如说以电话系统为例,虽然日常生活中,常见的案例为 一号一人,设计上可能会偏好将 人 和 电话号码 以 一对多 的关系进行构建。但是在 ToB 的业务中就需要考虑到公司号码其实会被分拨到不同的客服手上的情况,相对于 ToC 端 one-to-many 的设计,toB 端可能就要进行 many-to-many 的设计修正
-
-
实体生命周期
hibernate session 中的生命周期有 4 个:
-
transient
new instance,如果没有引用就会被 GC 回收
-
persist
与 persistence context 关联,这个情况下,hibernate 会对数据的更新进行管理和同步
-
detached
hibernate 不再对数据进行管理
-
removed
准备彻底被删除
geeksforgeeks 上找到了个图描述了一下生命周期:
整体来说这个部分还是比较复杂的,简单的几句话很难描述整个生命周期的流程,图里也缺少了一些必要的 op,比如
rollback
之类的,有空再补充一下 hibernate 好了 -
这章笔记主要过一遍 1-1 的数据关联,以及原始笔记是很久之前写的了,我重新走了一下流程补充了点内容,所以项目名称会有点差异……
one-to-one uni-relational
uni-relational 的关系如上面图所示,即 A 能够找到 B 的关联,但是 B 无法回溯到 A
设置数据库
脚本如下:
DROP SCHEMA IF EXISTS `hb-01-one-to-one-uni`;CREATE SCHEMA `hb-01-one-to-one-uni`;use `hb-01-one-to-one-uni`;SET FOREIGN_KEY_CHECKS = 0;CREATE TABLE `instructor_detail` (`id` int NOT NULL AUTO_INCREMENT,`youtube_channel` varchar(128) DEFAULT NULL,`hobby` varchar(45) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;CREATE TABLE `instructor` (`id` int NOT NULL AUTO_INCREMENT,`first_name` varchar(45) DEFAULT NULL,`last_name` varchar(45) DEFAULT NULL,`email` varchar(45) DEFAULT NULL,`instructor_detail_id` int DEFAULT NULL,PRIMARY KEY (`id`),KEY `FK_DETAIL_idx` (`instructor_detail_id`),CONSTRAINT `FK_DETAIL` FOREIGN KEY (`instructor_detail_id`) REFERENCES `instructor_detail` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;SET FOREIGN_KEY_CHECKS = 1;
ER 图如下:
ER 图是 dbeaver(有免费版)根据对应的数据库自动生成的,有图就可以证明 ER 图生成的没问题了
配置项目
新建项目
依旧用 spring initializer 实现:
main 文件如下:
package com.example.demo;import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Beanpublic CommandLineRunner commandLineRunner(String[] args) {return runner -> {System.out.println("Hello World!");};}
}
这样就创建了一个终端 app
properties 文件修改
如下:
# JDBC properties
spring.datasource.url=jdbc:mysql://localhost:3306/hb-01-one-to-one-uni
spring.datasource.username=springstudent
spring.datasource.password=springstudent
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect# Disable Hibernate usage of JDBC metadata
# not having this can resolve error
spring.jpa.properties.hibernate.boot.allow_jdbc_metadata_access=false# turn of the banner and lower the logging level
spring.main.banner-mode=off
logging.level.root=warn
运行结果如下:
2025-03-17T17:58:18.452-04:00 WARN 62459 --- [demo-one-to-one-uni] [ main] org.hibernate.orm.deprecation : HHH90000025: MySQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
Hello World!Process finished with exit code 0
创建 entity
主要就是两个,InstructorDetail
对应 instructor_detail
, Instructor
对应 instructor
-
instructor details
package com.example.demo.entity;import jakarta.persistence.*; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString;@Entity @Table(name = "instructor_detail") @Data @NoArgsConstructor @ToString public class InstructorDetail {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private int id;@Column(name = "youtube_channel")private String youtubeChannel;@Column(name = "hobby")private String hobby;public InstructorDetail(String youtubeChannel, String hobby) {this.youtubeChannel = youtubeChannel;this.hobby = hobby;} }
-
instructor
package com.example.demo.entity;import jakarta.persistence.*; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString;@Entity @Table(name = "instructor") @Data @NoArgsConstructor @ToString public class Instructor {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private int id;@Column(name = "first_name")private String firstname;@Column(name = "last_name")private String lastname;@Column(name = "email")private String email;// set up mapping to InstructorDetail@OneToOne(cascade = CascadeType.ALL)@JoinColumn(name = "instructor_detail_id")private InstructorDetail instructorDetail;public Instructor(String firstname, String lastname, String email) {this.firstname = firstname;this.lastname = lastname;this.email = email;} }
基本上没什么新的东西,除了下面这段:
@OneToOne(cascade = CascadeType.ALL)@JoinColumn(name = "instructor_detail_id")private InstructorDetail instructorDetail;
具体内容最后补充
DAO & DAOimpl
这个的实现就比较简单了,因为只是做 demo,所以没打算分成几个文件去写,所有数据库的操作都会放在这里,并且调用 entityManager
中的方法去实现,而不会用 extend JpaRepository
的方法去实现
-
AppDAO
package com.example.demo.dao;import com.example.demo.entity.Instructor;public interface AppDAO {void save (Instructor instructor); }
-
AppDAOImpl
package com.example.demo.dao;import com.example.demo.entity.Instructor;import jakarta.persistence.EntityManager;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository;@Repositorypublic class AppDAOImpl implements AppDAO{private final EntityManager entityManager;@Autowiredpublic AppDAOImpl(EntityManager entityManager) {this.entityManager = entityManager;}@Override@Transactionalpublic void save(Instructor instructor) {// it will also save instructor detail due to cascadeentityManager.persist(instructor);}}
⚠️:这个
@Transactional
导入 spring 的就好,导入 jakara 的话,spring boot 就不会管理了
更新一下 main
主要是增加一下 logging 以及输出结果
package com.example.demo;import com.example.demo.dao.AppDAO;
import com.example.demo.entity.Instructor;
import com.example.demo.entity.InstructorDetail;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Beanpublic CommandLineRunner commandLineRunner(AppDAO appDAO) {return runner -> {createInstructor(appDAO);};}private void createInstructor(AppDAO appDAO) {// create the instructorInstructor instructor = new Instructor("John", "Doe", "johndoe@gmail.com");InstructorDetail instructorDetail = new InstructorDetail("http://www.example.com", "Coding");// associate the objectsinstructor.setInstructorDetail(instructorDetail);// NOTE: this will ALSO save the details object because of CascadeType.ALLSystem.out.println("Saving instructor: " + instructor);appDAO.save(instructor);System.out.println("Done!");}
}
运行结果:
可以看到,这里具体执行了 2 条 queries,一个是写入 instructor
,另一个是写入 instructor_details
数据库截图:
查询实例
这个操作很简单,主要修改三个文件:
-
DAO
public interface AppDAO {Instructor findInstructorById(int id); }
-
DAOImpl
@Repository public class AppDAOImpl implements AppDAO{@Overridepublic Instructor findInstructorById(int id) {return entityManager.find(Instructor.class, id);} }
-
main
@Beanpublic CommandLineRunner commandLineRunner(AppDAO appDAO) {return runner -> {findInstructor(appDAO);};}private void findInstructor(AppDAO appDAO) {int id = 1;System.out.println("Finding instructor id: " + id);Instructor instructor = appDAO.findInstructorById(id);System.out.println("Instructor: " + instructor);System.out.println("Associated Instructor Details: " + instructor.getInstructorDetail());}
效果如下:
删除实例
也是一样的操作,修改 3 个文件:
-
DAO
public interface AppDAO {void deleteInstructorById(int id); }
-
DAOImpl
@Override@Transactionalpublic void deleteInstructorById(int id) {Instructor instructor = this.findInstructorById(id);if (instructor != null) {entityManager.remove(instructor);}}
-
main
@Beanpublic CommandLineRunner commandLineRunner(AppDAO appDAO) {return runner -> {deleteInstructor(appDAO);};}private void deleteInstructor(AppDAO appDAO) {int id = 2;System.out.println("Deleting instructor id: " + id);appDAO.deleteInstructorById(id);System.out.println("Done!");}
结果如下:
one-to-one bi-directional
这个修改其实没必要动数据库,等到之后捋一遍就明白为什么了
更新查询实例
public class InstructorDetail {// ...// updated code@OneToOne(mappedBy = "instructorDetails", cascade = CascadeType.ALL)private Instructor instructor;// ...// remove @ToString annotation as null field(private Instructor instructor;) will throw error@Overridepublic String toString() {return "InstructorDetail: id = " + this.getId() + ", youtubeChannel: " + this.getYoutubeChannel()+ ", hobby: " + this.getHobby() + ".";}
}
@toString
空值会造成 lombok 的一些问题,在这个 ticket 有提到:@ToString formatting ‘language’. #1297。这里用 getId()
比较合适,否则的话会造成循环调用,形成无止尽的递归
DAO 和 DAOImpl 更新
主要是获取新的 InstructorDetails
,代码比较简单:
public interface AppDAO {InstructorDetail findInstructorDetailById(int id);
}
@Overridepublic InstructorDetail findInstructorDetailById(int id) {return entityManager.find(InstructorDetail.class, id);}
更新 main 方法
其实就是新增一个方法,去获取输出通过 findInstructorDetailById
获取的实例:
@Beanpublic CommandLineRunner commandLineRunner(AppDAO appDAO) {return runner -> {findInstructorDetail(appDAO);};}private void findInstructorDetail(AppDAO appDAO) {// find the instructor detail objectint id = 1;InstructorDetail instructorDetail = appDAO.findInstructorDetailById(id);System.out.println("Instructor Detail:" + instructorDetail);// print the associated instructorSystem.out.println("Associated instructor: " + instructorDetail.getInstructor());System.out.println("Done.");}
输出结果
删除实例更新
-
DAO
void deleteInstructorDetailById(int id);
-
DAO Impl
@Override@Transactionalpublic void deleteInstructorDetailById(int id) {InstructorDetail instructorDetail = this.findInstructorDetailById(id);if (instructorDetail != null) {entityManager.remove(instructorDetail);}}
-
main
@Beanpublic CommandLineRunner commandLineRunner(AppDAO appDAO) {return runner -> {deleteInstructorDetail(appDAO);};}private void deleteInstructorDetail(AppDAO appDAO) {int id = 1;System.out.println("Deleting instructor id: " + id);appDAO.deleteInstructorDetailById(id);System.out.println("Done!");}
结果:
只删除 instructor detail 但是不删除 instructor
这个方式可以通过修改 CascadeType
去实现,如:
@OneToOne(mappedBy = "instructorDetail", cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})private Instructor instructor;
修改 DAO Impl 去手动移除关联:
@Override@Transactionalpublic void deleteInstructorDetailById(int id) {InstructorDetail instructorDetail = this.findInstructorDetailById(id);// remove the associated object reference, break the bi-directional linkinstructorDetail.getInstructor().setInstructorDetail(null);entityManager.remove(instructorDetail);}
最后运行结果:
建立关联的注解
@JoinColumn
这个代表的是当前属性为 foreign key,并且可以通过当前的 foreign key 寻找到对应的实例
需要注意的是, @JoinColumn
无法单独使用,必须要搭配对应的关系——@OneToOne
、@OneToMany
、@ManyToMany
才能够正确工作
@OneToOne
这个注解只代表了当前的属性与当前的 entity 存在 1-to-1 的对应关系,参考两种用法:
@OneToOne(cascade = CascadeType.ALL)@JoinColumn(name = "instructor_detail_id")private InstructorDetail instructorDetail;// =====================================================@OneToOne(mappedBy = "instructorDetails", cascade = CascadeType.ALL)private Instructor instructor;
前者可以直接通过 foreign key 寻找对应的关系,写成 query 大体如下:
select * from instructor_detail where id = 1;
后者的 query 大体如下:
SELECT * FROM instructor_detail d
JOIN instructor i ON d.id = i.instructor_detail_id
WHERE d.id = 1;
对比起来的话,前者因为直接用 foreign key 去找,不用调用一个 join,所以表现上会稍微快一些
reference
-
mysql 权限问题
这个取决于 properties 文件中使用的用户,如果不是
root
,那么可能就会有无法访问的问题,这个时候跑一下下面的脚本就行了,用户名和 db 名称用数据库中的代替:mysql -u root -p USE dbname;# 如果用户不存在,直接 grant 会报错 CREATE USER 'username'@'%' IDENTIFIED BY 'your_password'; GRANT ALL PRIVILEGES ON `hb-01-one-to-one-uni`.* TO 'username'@'%';FLUSH PRIVILEGES;SHOW GRANTS FOR 'username'@'%';
-
properties 文件配置
来自官方的 repo: spring-lifecycle-smoke-tests
相关文章:
[spring] Spring JPA - Hibernate 多表联查 1
[spring] Spring JPA - Hibernate 多表联查 1 之前在 [spring] spring jpa - hibernate 名词解释&配置 和 [spring] spring jpa - hibernate CRUD 简单的学习了一下怎么使用 Hibernate 实现 CRUD 操作,不过涉及到的部分都是逻辑上比较简单的实现——只在一张表…...
在 Elasticsearch 中探索基于 NVIDIA 的 GPU 加速向量搜索
作者:来自 Elastic Chris Hegarty 及 Hemant Malik 由 NVIDIA cuVS 提供支持,此次合作旨在为开发者在 Elasticsearch 中的向量搜索提供 GPU 加速。 在 Elastic Engineering 组织内,我们一直致力于优化向量数据库的性能。我们的使命是让 Lucen…...
2025年图生视频模型技术全景解析
一、开源图生视频模型 阿里通义万象Wan2.1系列 I2V-14B-480P: 14B参数基础模型支持480P分辨率图生视频显存需求16GB以上 I2V-14B-720P: 高清增强版模型采用分帧渲染技术,输出分辨率达1280720 技术特性: 支持中文提示词自动解析内置…...
Docker build 会在本地产生巨大的文件
Docker build 会在本地产生巨大的文件, 比如 用 这个命令列出本地镜像 docker images 可见size都是很大的, 到docker目录下,看到ext4.vhdx的大小 80多G 那只能用这个命令把不用的镜像删掉了: (rmi后面是镜像id&a…...
使用LLaMA Factory微调导出模型,并用ollama运行,用open webui使用该模型
本篇记录学习使用llama factory微调模型的过程,使用ollama运行微调好的模型,使用open webui前端调用ollama的模型; 测试机信息: 系统:Ubuntu 24.04.2 LTS(桌面版) cpu:i9-14900KF …...
Git远程拉取和推送配置
Git进行远程代码拉取和推送时候提示配置user.name 和 user.email 背景:换新电脑后使用Git进行代码拉取和推送过程中,提示“Make sure you configure your “user.name” and “user.email” in git.”。这个配置针对git的正常使用仅需要配置一次…...
正则魔法:解码 return /^\d+$/.test(text) ? text : ‘0‘ 的秘密
🚀 正则魔法:解码 return /^\d$/.test(text) ? text : 0 的秘密 🌟 嘿,技术探险家们!👋 今天我们要破解一段看似简单的代码:return /^\d$/.test(text) ? text : 0。它藏在一个 Vue 前端组件中…...
[023-01-47].第47节:组件应用 - GetWay与 Sentinel 集成实现服务限流
SpringCloud学习大纲 一、需求说明: 实现网关cloudalibaba-sentinel-gateway9528模块保护cloudalibaba-provider-payment9001 二、编码实现: 2.1.建module: 新建模块,名称是:cloudalibaba-sentinel-gateway9528 2.2.改pom &l…...
【自用】NLP算法面经(5)
一、L1、L2正则化 正则化是机器学习中用于防止过拟合并提高模型泛化能力的技术。当模型过拟合时,它已经很好地学习了训练数据,甚至是训练数据中的噪声,所以可能无法在新的、未见过的数据上表现良好。 比如: 其中,x1和…...
AI视频生成产品体验分享(第2趴):Vidu、Hailuo、Runway、Pika谁更胜一筹?
hi,大家,继上次体验完可灵、即梦和pixverse,今天打算从产品经理的角度再研究下Vidu、Hailuo、Runway、Pika这几款产品!欢迎加入讨论! 一、产品简介 1. Vidu:国产自研的「一致性标杆」 📌官网…...
火绒终端安全管理系统V2.0——行为管理(软件禁用+违规外联)
火绒终端安全管理系统V2.0:行为管理策略分为软件禁用和违规外联两部分,能够管理终端用户软件的使用,以及终端用户违规连接外部网络的问题。 l 软件禁用 软件禁用策略可以选择软件名单的属性、添加软件名单以及设置发现终端使用禁用软件时的…...
台式机电脑组装---电脑机箱与主板接线
台式机电脑组装—电脑机箱与主板接线 1、机箱连接主板的跳线一般主要有USB 2.0、USB 3.0、前置音频接口(HD_AUDIO)以及POWER SW、RESET SW、POWER LED、HDD LED四个主板跳线,这些跳线分别的含义如下。 RESET SW:机箱重启按键;注:…...
【总结】常用API架构类型
引言 在现代软件开发中,API(应用程序编程接口)已经成为各类系统之间交互的核心。不同的 API 架构类型适用于不同的业务需求和技术场景,选择合适的架构可以提高系统的性能、可维护性和扩展性。本文将介绍几种常见的 API 架构类型,并分析它们的…...
ffmpeg库视频硬解码使用流程
FFmpeg 的硬解码(Hardware Decoding)通过调用 GPU 或专用硬件的编解码能力实现,能显著降低 CPU 占用率。 一、FFmpeg 支持的硬件解码类型 FFmpeg 原生支持多种硬件加速类型,具体由 AVHWDeviceType 定义,包括&…...
两个常用的用于读写和操作DXF文件C#库:netDxf 和 DXF.NET
netDxf 和 DXF.NET 是两个常用的C#库,用于读取、写入和操作DXF文件。以下是它们的详细介绍和用法示例。 1. netDxf 简介 netDxf 是一个开源的DXF文件读写库,支持AutoCAD DXF格式的读取和写入。它支持大多数DXF实体和对象,并且易于使用。 Gi…...
jmeter吞吐量控制器-Throughput Controller
jmeter吞吐量控制器-Throughput Controller 新增吞吐量控制器名词解释测试场景场景1:场景2:场景3场景4场景5场景6场景7场景8 测试结论 根据百分比执行不同的接口测试场景测试结果 新增吞吐量控制器 名词解释 Based on: Total Executions(总执行数)/Perc…...
windows 平台编译openssl
文章目录 准备环境安装perl安装NASM获取源码 源码编译配置编译 准备环境 安装perl 下载Perl 5.40.0.1 Portable zip strawberryperl 解压后设置系统环境变量 测试安装是否成功 perl --versionThis is perl 5, version 40, subversion 0 (v5.40.0) built for MSWin32-x64-m…...
【Linux】Makefile秘籍
> 🍃 本系列为Linux的内容,如果感兴趣,欢迎订阅🚩 > 🎊个人主页:【小编的个人主页】 >小编将在这里分享学习Linux的心路历程✨和知识分享🔍 >如果本篇文章有问题,还请多多包涵&a…...
Python散点图(Scatter Plot):数据探索的“第一张图表”
在数据可视化领域,散点图是一种强大而灵活的工具,它能够帮助我们直观地理解和探索数据集中变量之间的关系。本文将深入探讨散点图的核心原理、应用场景以及如何使用Python进行高效绘制。 后续几篇将介绍高级技巧、复杂应用场景。 Python散点图(Scatter Plot):高阶分析、散点…...
Spring AI Alibaba快速使用
AI 时代,Java 程序员也需要与时俱进,这两个框架必须掌握。 一个是 Spring AI一个是 Spring Alibaba AI。 Spring AI 是一个AI工程领域的应用程序框架,它的目标是将 Spring生态系统的设计原则应用于人工智能领域。 但是, Spring…...
Redis 跳表原理详解
一、引言 在 Redis 中,有序集合(Sorted Set)是一种非常重要的数据结构,它可以实现元素的有序存储和高效查找。而实现有序集合的底层数据结构之一就是跳表(Skip List)。跳表是一种随机化的数据结构ÿ…...
安全地自动重新启动 Windows 资源管理器Bat脚本
安全地自动重新启动 Windows 资源管理器脚本 可以直接运行的 Windows 批处理脚本,用于安全地自动重新启动 Windows 资源管理器。该脚本会在杀死资源管理器之前检查是否有其他进程正在使用资源管理器相关的文件。 Bat脚本 echo off title 资源管理器安全重启工具 co…...
【C++模板】
模板初阶 前言1.定义模板2.函数模板2.1定义2.2实例化函数模板2.3模板参数的匹配原则 3.类模板3.1类模板实例化 前言 模板是C中泛型编程的基础,一个模板就是一个创建类和函数的蓝图或公式。 1.定义模板 假定我们希望编写一个函数来比较两个值,并指出第…...
基于Debian搭建FTP服务器
操作系统 Debian-9.6.0-amd64,图形化安装 基础操作 1.软件安装管理 命令方式: 在线安装 sudo apt-get install vim/ifconfig 查看安装软件 dpkg -l 图形化桌面方式 : 通过“软件管理”工具管理 2.网络管理 /etc/network/interfaces 3.文本…...
如果我的项目是用ts写的,那么如何使用webpack的动态导入功能呢?
在 TypeScript 项目中使用 Webpack 的动态导入(Dynamic Imports)功能,需要结合 TypeScript 的语法和 Webpack 的配置。以下是具体实现方法和注意事项: 一、基础配置 1. 修改 tsconfig.json 确保 TypeScript 支持动态导入语法&am…...
构建高效的LinkedIn图像爬取工具
一. 项目背景与目标 LinkedIn上的用户头像数据可以用于多种场景,例如: 人才招聘:通过分析目标职位候选人的头像,了解其职业形象。市场调研:收集特定行业从业者的头像,用于分析职业群体的特征。学术研究&a…...
在windows下安装windows+Ubuntu16.04双系统(下)
这篇文章的内容主要来源于这篇文章,为正式安装windowsUbuntu16.04双系统部分。在正式安装前,若还没有进行前期准备工作(1.分区2.制作启动u盘),见《在windows下安装windowsUbuntu16.04双系统(上)》 二、正式安装Ubuntu …...
浅分析 PE3R 感知高效的三维重建
"近期,二维到三维感知技术的进步显著提升了对二维图像中三维场景的理解能力。然而,现有方法面临诸多关键挑战,包括跨场景泛化能力有限、感知精度欠佳以及重建速度缓慢。为克服这些局限,我们提出了感知高效三维重建框架&#…...
调和Django与Sql server2019的关系
数据库升级成sqlserver2019后,用户发现一些APP不能用了,检查发现是Django连接sqlserver的APP全部不能用了,页面打开都是500错误,进入Pycharm调试发现: 1.遇到错误1:django.db.backends.XXX错误 File "…...
【canvas】一键自动布局:如何让流程图节点自动找到最佳位置
一键自动布局:如何让流程图节点自动找到最佳位置 引言 在流程图、拓扑图和系统架构图设计中,节点布局往往是最令人头疼的问题。如果手动调整每个节点位置,不仅耗时费力,还难以保证美观性和一致性。本文将深入解析如何实现自动布…...
Flutter 学习之旅 之 flutter 使用 SQLite(sqflite) 实现简单的数据本地化 保存/获取/移除/判断是否存在 的简单封装
Flutter 学习之旅 之 flutter 使用 SQLite(sqflite) 实现简单的数据本地化 保存/获取/移除/判断是否存在 的简单封装 目录 Flutter 学习之旅 之 flutter 使用 SQLite(sqflite) 实现简单的数据本地化 保存/获取/移除/判断是否存在…...
[unity 组件] Content Size Fitter 横向填充不满解决办法
可以看到,当只有3个或者4个元素的时候,布局组件并没有将横向宽度占满来布局。之所以有此困惑的原因是我以为他的布局策略是,从左到右,从上至下,尽量占满空间,不够了再换行,其实不然。 5到6个元…...
Dify 项目开源大模型应用开发平台
Dify 是一款开源的大语言模型(LLM)应用开发平台,旨在简化生成式 AI 应用的创建、部署和持续优化流程。以下从多个维度对该项目进行详细介绍: 一、项目定义与核心功能 Dify 的核心定位是结合 后端即服务(BaaSÿ…...
使用 `pytest` 框架时,可以通过极限封装将 YAML 文件的读取、解析
在使用 pytest 框架时,可以通过极限封装将 YAML 文件的读取、解析和测试用例的通用逻辑封装成共享的方法或 fixture,从而减少重复代码。以下是详细的实现步骤和示例。 1. 封装 YAML 文件读取和解析 将 YAML 文件的读取和解析逻辑封装到一个工具函数中,供所有测试用例调用。…...
算法刷题记录——LeetCode篇(2) [第101~200题](持续更新)
(优先整理热门100及面试150,不定期持续更新,欢迎关注) 101. 对称二叉树 给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输入:root [1,2,2,3,4,4,3] 输出:true示例 2: 输入&am…...
ruoyi 小程序使用笔记
1.上传图片 页面 <uni-forms-item label"退休证明(退休证)" name"retire"><uni-file-picker ref"imageUploadRetire" :limit"1" :auto-upload"false" select"upload"/> </uni-forms-item>js …...
计算机网络——总结
01. 网络的发展及体系结构 网络演进历程 从1969年ARPANET的4个节点发展到如今覆盖全球的互联网,网络技术经历了电路交换到分组交换、有线连接到无线覆盖的革命性变革。5G时代的到来使得网络传输速度突破10Gbps,物联网设备数量突破百亿级别。 网络体系…...
Stable Diffusion lora训练(一)
一、不同维度的LoRA训练步数建议 2D风格训练 数据规模:建议20-50张高质量图片(分辨率≥10241024),覆盖多角度、多表情的平面风格。步数范围:总步数控制在1000-2000步,公式为 总步数 Repeat Image Epoch …...
再学:ERC20-Permit2、SafeERC20方法 详解ERC721,如何铸造一个NFT以及IPFS的作用
目录 1.Permit2 2.尽量使用Safe方法 3.ERC721 4. 铸造NFT 1.Permit2 针对没有permit的代币实现的线下签名方式 通过approve方法,让Permit2拿到无限次数的授权。拿到授权之后,Permit2会生成签名。 当用户需要转账的时候,Permit2会发送签…...
Docker 存储
目录挂载 在执行run时设置参数-v即可实现目录映射, 实现原理会在宿主机器创建一个空文件夹 # 挂载宿主机的 /data 目录到容器的 /app 目录 docker run -d -v /data:/app --name my-app my-image # 挂载 docker 内的 /usr/share/nginx/html 目录到本地机的 /app/nghtml docker…...
详细介绍VUE,带你了解VUE!!!
Vue.js 是一个渐进式的 JavaScript 框架,用于构建用户界面。它的核心库专注于视图层,易于与其它库或现有项目进行集成,同时也可以与现代工具链和支持库结合使用,成为一个完整的开发框架。 以下是关于 Vue.js 的详细资料ÿ…...
C++语法之命名空间二
A.h头文件中代码: namespace a {void 输出(); }; A.cpp源文件中代码: #include <iostream> #include "A.h" void a::输出() {std::cout << "A.h里的输出函数" << std::endl; } B.h头文件中代码: …...
【STM32】I²CC通信外设硬件I²CC读写MPU6050(学习笔记)
相关文章笔记: 【STM32】I2C通信协议&MPU6050芯片-学习笔记-CSDN博客 【江协科技STM32】软件I2C协议层读写MPU6050驱动层-CSDN博客 IC通信外设 IC外设简介 STM32内部集成了硬件I2C收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答…...
Android Room 框架公共模块源码深度剖析(四)
一、引言 在 Android 开发中,数据持久化是一个常见的需求。Android Room 框架作为 Android Jetpack 组件的一部分,为开发者提供了一个抽象层,使得在 SQLite 数据库上进行数据操作变得更加简单和高效。Room 框架包含多个模块,其中…...
NumPy系列 - 创建矩阵
目录 前传直接创建数组就只是创建数组1. np.array()2. np.arange()3. np.ones()4. numpy.ones_like()5. np.zeros()6. numpy.zeros_like() 定义数据类型 参考资料 前传 由于,某人在上智能相关课程的时候,总想着一大堆的事情,统计股市涨跌&am…...
能“嘎嘎提升”提升用户居住体验的智能家居物联网框架推荐!
智能家居在日常生活中给我们的带来了更多的便利,更让有些用户切实地体会到了科技的魅力,对于想要打造属于自己的智能家居氛围感的用户们,以下是一些能够帮助提升居住体验的智能家居物联网框架及应用: 1. 涂鸦智能(Tuy…...
python-leetcode 60.分割回文串
题目: 给定一个字符串S,请将S分割成一些子串,使每个子串都是回文串,返回S所有可能的分割方案 方法一:回溯深度优先搜索 1. 主要思想 使用 深度优先搜索(DFS) 遍历 s 的所有可能划分方式。使用 回溯&…...
Android Jetpack Compose介绍
Android Jetpack Compose Android Jetpack Compose 是 Google 推出的现代 UI 工具包,用于以声明式的方式构建 Android 应用的 UI。它摒弃了传统的 XML 布局方式,完全基于 Kotlin 编写,提供了更简洁、更强大的 UI 开发体验。以下是 Compose 的…...
文档搜索引擎项目测试
目录 设计测试用例 功能测试 文档搜索功能 具体的逻辑 文档显示搜索结果功能 自动化测试 功能类介绍 最终测试套件的测试结果 性能测试 查看聚合报告 每秒处理事务数/吞吐量(TPS) 响应时间 生成测试报告 界面测试 初始页面 搜索页面 总结 后续改进: 设计测试…...
Vue3项目技术点记录
vue3项目技术点笔记 1 环境变量 - 不同环境用不同的配置 环境变量命名:.env.produciton .env.development Vite.config.ts 配置 envDir:‘’ 链接: VUE3+Vite 环境变量配置 2 axios的封装 http请求拦截,响应拦截。 src下建立公共文件夹Utils下建立request.ts import axios…...