当前位置: 首页 > news >正文

【Go】Go Gorm 详解

1. 概念

Gorm 官网:https://gorm.io/zh_CN/docs/

GormThe fantastic ORM library for Golang aims to be developer friendly,这是官网的介绍,简单来说 Gorm 就是一款高性能的 Golang ORM 库,便于开发人员提高效率

那么 ORM(Object Relation Mapping) 又是什么呢?在 Golang 语言中,Object指的就是 struct 结构体对象,Relation 就是数据库当中的关系,Mapping则表示两者具有映射关系,具体表现如下:

  • Go当中的结构体声明 <-> 数据库层面的表结构
  • Go当中的结构体实例 <-> 数据库层面的一条表记录

2. 数据库连接

2.1 安装依赖

想要在 Go 代码中使用 gorm 我们需要先引入对应的依赖:

  • gorm 库依赖:gorm.io/gorm
  • 特定数据库驱动依赖:gorm.io/driver/mysql

然后使用 go mod 包管理工具加载对应的依赖:

  1. go mod init first_gorm:初始化
  2. go mod tidy:加载依赖

然后就可以开始编写代码了!

2.2 连接数据库

在操作数据库之前,我们还需要与指定的数据库建立连接,此处以 MySQL数据库为例:

基本语法:db, err := gorm.Open(mysql.Open(dsn语句), &gorm.Config{})

  • 其中 dsn 语句为特定的连接格式,形式如下:user:pwd@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)func main() {var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {fmt.Println("数据库连接失败!", err)}fmt.Println(db)
}

程序运行结果:

控制台打印出 db 对象,说明我们已经成功与数据库建立连接(必须保证数据库中存在指定的数据库)

3. 数据库基本操作

3.1 创建表(表关系映射)

3.1.1 基本使用

我们可以使用 gorm 提供的 API 来创建指定的表,需要关注的是 结构体声明 <=> 数据库表结构,因此我们想要创建一个表结构实则只需要定义一个结构体类型

-- 创建user表 --
create table t_user (user_id bigint primary key auto_increment,user_name varchar(32) not null,user_pwd varchar(128) not null,user_phone varchar(32) unique
) 

使用上述 SQL 语句创建表的行为等价于在 Go 语言当中定义下列结构体对象:

// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}

创建表基本语法:err := db.AutoMigrate(&特定结构体{})

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {fmt.Println("数据库连接失败!", err)}err = db.AutoMigrate(&User{})if err != nil {fmt.Println("数据库表迁移失败!", err)}
}

程序运行结果:

3.1.2 自定义表名

我们发现定义结构体名称为 “User” 时会创建 “users” 的表名,但是如果我就希望叫做 “t_user” 应该怎么办呢?我们可以定义一个名为 TableName的方法接收器,格式如下:

func (*User) TableName() string {return "t_user"
}

删除原先的表后再次运行,可以发现此时表名称已经指定为t_user

3.2 新增记录

我们还可以使用 gorm 提供的 API 进行表记录的插入,这里我们需要关注** 结构体实例 <=> 表记录** 之间的映射关系,也就意味着我们可以通过创建一个结构体实例,实现插入一条记录的效果

3.2.1 单条数据插入

基本语法:db.Create(&结构体实例)

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {fmt.Println("数据库连接失败!", err)}// 插入单条数据var user = User{UserName: "wjj", UserPwd: "123", UserPhone: "111"}db.Create(&user)// 再次打印userfmt.Println(user)
}

数据库表结果:

程序运行结果:

💡 提示:从中我们还可以发现,插入数据之后,还会将数据库表中记录回显到结构体实例当中!这也是为什么需要传递地址的原因!

3.2.2 批量插入数据

当我们需要批量插入多条数据的时候,循环调用 db.Create(&结构体实例)这个方法效率就太低了!因为数据库连接会话频繁创建销毁耗时比较高,更合适的方法就是进行批量插入

基本语法:db.Create(&结构体实例切片),仍旧是 Create 函数,但是参数我们可以传递结构体实例切片

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 批量插入多条数据var users = []User{{UserName: "th", UserPwd: "123", UserPhone: "222"},{UserName: "lhf", UserPwd: "123", UserPhone: "333"},{UserName: "zcy", UserPwd: "123", UserPhone: "444"},}db.Create(&users)// 打印结果fmt.Println(users)
}

数据库表结果:

程序运行结果:

3.3 查询记录

3.3.1 查询所有记录

基本语法:db.Find(&结构体实例切片)

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 查询全部记录var users []Userdb.Find(&users)// 打印结果fmt.Println(users)
}

程序运行结果:

3.3.2 按照条件查询

我们可以使用 Where 指定查询条件进行过滤

基本语法:db.Where("user_id > ?", 2).Find()表示想要查询 user_id > 2 的所有记录

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 按照条件查询var users []Userdb.Where("user_id > ?", 2).Find(&users)// 打印fmt.Println(users)
}

程序运行结果:

3.3.3 查询单条记录

查询单条记录有以下两种情况:

  • 查询第一条记录:db.First(&结构体实例)
  • 查询最后一条记录:db.Last(&结构体实例)
package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}
func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 查询第一条记录var firstUser Userdb.First(&firstUser)// 查询最后一条记录var lastUser Userdb.Last(&lastUser)fmt.Println(firstUser, lastUser)
}

程序运行结果:

3.3.4 查询记录总数

基本语法:db.Find(&结构体实例切片).Count(&整型变量)

package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 查询总数var users []Uservar totalSize int64db.Find(&users).Count(&totalSize)fmt.Println("记录总数:", totalSize)
}

程序运行结果:

3.4 修改记录

3.4.1 按照默认主键修改

基本语法:db.Save(&结构体实例)会按照结构体实例当中的主键字段找到对应数据库记录进行修改

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 查询user_id为1的记录var stu Userdb.Where("user_id = ?", 1).Find(&stu)// 修改stu姓名为wjj1stu.UserName = "wjj1"// 修改(按照主键修改)db.Save(&stu)
}

程序运行结果:

3.4.2 修改指定字段

上述按照默认主键修改的方式修改了全部字段,如果我们只想修改特定单个字段可以使用以下方式:

基本语法:db.Model(&结构体实例).Where(条件).Update(字段, 修改值)

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 修改user_id为1的记录 user_name为wjjvar stu Userdb.Model(&stu).Where("user_id = ?", 1).Update("user_name", "wjj")
}

程序运行结果:

3.4.3 修改多个字段

我们还可以指定多个字段进行修改

基本语法:db.Model(&结构体实例).Where(条件).updates(修改实例),其中修改实例可以是结构体也可以是map对象

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 修改user_id为1的记录 user_name为WJJ, user_pwd为"999"var stu Uservar fields = map[string]interface{}{"user_name": "WJJ", "user_pwd": "999"}db.Model(&stu).Where("user_id = ?", 1).Updates(fields)
}

程序运行结果:

3.5 删除记录

3.5.1 按照默认主键删除

基本语法:db.Delete(&结构体实例)会自动按照主键找到表中记录,然后删除

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 按照默认主键删除var user = User{UserId: 1}db.Delete(&user)
}

程序运行结果:

3.5.2 指定条件删除

我们想更加精细化的控制删除条件就需要借助 Where 函数:

基本语法:db.Where(条件).Delete(&结构体实例)

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 结构体声明
type User struct {UserId    int64  `gorm:"primaryKey;autoIncrement"`UserName  string `gorm:"not null;type:varchar(32)"`UserPwd   string `gorm:"not null;type:varchar(128)"`UserPhone string `gorm:"unique;type:varchar(32)"`
}func (*User) TableName() string {return "t_user"
}func main() {// 连接数据库var dsn = "root:QWEzxc123456@tcp(127.0.0.1:3306)/gorm_test"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 按照条件删除db.Where("user_id = ?", 10).Delete(&User{})
}

程序运行结果:

相关文章:

【Go】Go Gorm 详解

1. 概念 Gorm 官网&#xff1a;https://gorm.io/zh_CN/docs/ Gorm&#xff1a;The fantastic ORM library for Golang aims to be developer friendly&#xff0c;这是官网的介绍&#xff0c;简单来说 Gorm 就是一款高性能的 Golang ORM 库&#xff0c;便于开发人员提高效率 那…...

【IDEA版本升级JDK21报错方法引用无效 找不到符号】

java: 方法引用无效 找不到符号 符号: 方法 getFirst() 位置: 接口 java.util.List 升级JDK21版本遇到问题&#xff0c;报错找不到符号 但是点进去又能发现这个函数&#xff0c;证明能够找到这个方法&#xff0c;但是就是报错 java: 方法引用无效 找不到符号 符号: …...

Node.js 版本管理工具完全指南

Node.js 版本管理工具完全指南 目录 1. nvm (Node Version Manager)2. n (Node Package Manager)3. fnm (Fast Node Manager)4. Volta5. 工具对比 1. nvm (Node Version Manager) 1.1 安装指南 macOS/Linux # 使用 curl 安装 curl -o- https://raw.githubusercontent.com…...

JavaSE学习心得(多线程与网络编程篇)

多线程-网络编程 前言 多线程&JUC 多线程三种实现方式 第一种实现方式 第二种实现方式 第三种实现方式 常见成员方法 买票引发的安全问题 同步代码块 同步方法 Lock锁 生产者和消费者 常见方法 等待唤醒机制 练习 抢红包 抽奖 多线程统计并求最…...

平均精确率均值(mAP)

mAP&#xff08;mean Average Precision&#xff0c;平均精确率均值&#xff09; 并不是传统意义上的“精度”&#xff08;Accuracy&#xff09;&#xff0c;而是一种专门用于评估目标检测、图像分割或信息检索等任务的性能指标。它更全面地反映了模型在不同类别和不同置信度阈…...

VUE学习笔记1__创建VUE实例

核心步骤 <div id"app"><!-- 这里存放渲染逻辑代码 --><h1>{{ msg }}</h1><a href"#">{{count}}</a> </div><!-- 引入在线的开发版本核心包 --> <!-- 引入核心包后全局可使用VUE构造函数 --> <…...

Inxpect毫米波安全雷达:精准检测与动态保护,工业自动化可靠选择

Inxpect毫米波安全雷达具备“精准检测、动态区域保护、环境适应性”三大核心功能。在工业自动化和机器人系统里&#xff0c;这些功能发挥着重要作用,有助于提升安全性与效率。Inxpect雷达运用毫米波技术&#xff0c;在诸如存在灰尘、烟雾或碎屑等复杂环境中&#xff0c;也能保持…...

基于禁忌搜索算法的TSP问题最优路径搜索matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于禁忌搜索算法的TSP问题最优路径搜索&#xff0c;旅行商问题&#xff08;TSP&#xff09;是一个经典的组合优化问题。其起源可以追溯到 19 世纪初&#xff0c;…...

C51交通控制系统的设计与实现

实验要求&#xff1a; 本题目拟设计一个工作在十字路口的交通信号灯控制系统&#xff0c;设东西方向为主干道A&#xff0c;南北方向为辅助干道B。要求&#xff1a;&#xff08;1&#xff09;用发光二极管模拟交通灯信号&#xff1b;&#xff08;2&#xff09;灵活控制主、辅干…...

深度学习的超参数

1. 引言 1.1 什么是超参数&#xff1f; 在机器学习和深度学习中&#xff0c;超参数&#xff08;Hyperparameter&#xff09; 是在模型训练前由开发者设置的参数&#xff0c;这些参数决定了模型的训练过程和模型的结构。例如&#xff1a; 神经网络的层数和每层神经元的数量。…...

网络安全面试题及经验分享

本文内容是i春秋论坛面向专业爱好者征集的关于2023年面试题目和答案解析&#xff0c;题目是真实的面试经历分享&#xff0c;具有很高的参考价值。 shiro反序列化漏洞的原理 Shiro反序列化漏洞的原理是攻击者通过精心构造恶意序列化数据&#xff0c;使得在反序列化过程中能够执…...

【Golang 面试题】每日 3 题(三十一)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…...

微服务架构:挑战与机遇并存

微服务架构在提升系统灵活性、可扩展性和容错性的同时&#xff0c;也引入了一系列挑战。微服务带来的挑战主要有以下几点&#xff1a; 1. 系统复杂性增加&#xff1a;想象一下&#xff0c;你原本有一个大厨房&#xff08;单体应用&#xff09;&#xff0c;里面有几个大厨&…...

Vue语音播报功能

使用Web Speech API的SpeechSynthesis接口来实现文本转语音 Web Speech API可能不在所有浏览器中都能完美支持 特别是旧浏览器 在生产环境中&#xff0c;你可能需要添加功能检测和后备方案。<template><div><textarea v-model"text" placeholder&quo…...

【Java设计模式-4】策略模式,消灭if/else迷宫的利器

各位Java编程小伙伴们&#xff01;今天咱们要一起探索一个超级厉害的Java设计模式——策略模式&#xff0c;它就像是一把神奇的魔法剑&#xff0c;专门用来斩断那些让我们代码变得乱糟糟的if/else语句迷宫&#xff01; 一、if/else的烦恼 在编程的奇妙世界里&#xff0c;我们…...

citrix netscaler13.1 重写负载均衡响应头(基础版)

在 Citrix NetScaler 13.1 中&#xff0c;Rewrite Actions 用于对负载均衡响应进行修改&#xff0c;包括替换、删除和插入 HTTP 响应头。这些操作可以通过自定义策略来完成&#xff0c;帮助你根据需求调整请求内容。以下是三种常见的操作&#xff1a; 1. Replace (替换响应头)…...

【AI学习】地平线首席架构师苏箐关于自动驾驶的演讲

在地平线智驾科技畅想日上&#xff0c;地平线副总裁兼首席架构师苏箐&#xff08;前华为智驾负责人&#xff09;做了即兴演讲&#xff0c;以下是其演讲的主要内容&#xff1a; 对自动驾驶行业的看法 自动驾驶的难度与挑战&#xff1a;苏箐表示自动驾驶非常难&#xff0c;他做自…...

QILSTE H11-D212HRTCG/5M高亮红绿双色LED灯珠 发光二极管LED

型号&#xff1a;H11-D212HRTCG/5M&#xff0c;一款由QILSTE&#xff08;HongKong&#xff09;Technology Co., Ltd精心打造的高亮度红绿双色LED产品&#xff0c;其尺寸仅为2.01.251.1 mm&#xff0c;却蕴含着强大的光电特性。这款产品采用透明平面胶体封装&#xff0c;不仅外观…...

2️⃣java基础进阶——多线程、并发与线程池的基本使用

一、概念介绍 什么是线程&#xff0c;什么是进程&#xff0c;两者有什么关系&#xff1f; 进程是操作系统资源分配的独立单位&#xff1b;而线程是操作系统能够进行调度和分派的最小单位&#xff1b;线程包含于进程之中&#xff0c;是进程中的实际运作单位。 例如&#xff1a…...

RAG多路召回

什么是多路召回&#xff1f; 多路召回&#xff08;Multi-Route Retrieval&#xff09; 是指在信息检索系统中&#xff0c;为了提升检索的全面性和准确性&#xff0c;通过多条不同的检索路径或不同的检索策略来获取信息的技术。多路召回的核心思想是&#xff0c;单一的检索路径…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...