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

gorm基本操作

一、gorm安装

1.下载gorm

go get -u gorm.io/gorm //gorm框架
go get -u gorm.io/driver/mysql //驱动

2.mysql准备工作

mysql> create database godb;
mysql> grant all on *.* to 'admin'@'%' identified by 'golang123!';
mysql> flush privileges;

3.导入gorm框架

import ("gorm.io/gorm""gorm.io/driver/mysql"
)

4.连接mysql

这里单独创建一个连接mysql的包,

package mysqldbimport ("gorm.io/driver/mysql""gorm.io/gorm"
)func Mysql_connect() *gorm.DB {dsn := "admin:golang123!@tcp(192.168.1.23:3306)/godb?charset=utf8mb4&parseTime=True&loc=Local"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})return db
}

5.引入连接包函数

package mainimport ("fmt""gorm/mysqldb"
)func main() {db := mysqldb.Mysql_connect()fmt.Println(db)
}

此时如果没有报错,说明连接mysql已经成功了

二、基本使用

1.创建和表对应的结构体

这里新建了一个db.go 也属于mysqldb包

package mysqldbimport "time"//共用结构体,其它结构体直接继承即可,字段是所有表共用字段,所有做一个基础结构体,减少重复定义。
//反撇号中的内容是"标签"。标签的含义结构体转换成另外一种格式的时候,传递过去一些信息
//其实在gorm中有一个自带的gorm.Model结构体,和这里自建的BaseModule 基本一致
type BaseModule struct {Id         int        `gorm:"primarykey"`CreateTime *time.Time `gorm:"autoCreateTime"`UpdateTime *time.Time `gorm:"autoCreateTime"`
}//创建老师表
type Teacher struct {BaseModule        //继承共用结构体,这里使用了匿名字段,使用数据类型(结构体类型)作为字段名称Name       string        `gorm:"type:varchar(32);unique;not null"`Tno        int    //账号Pwd        string //密码Tel        string //电话
}

2.teacher表

在main.go中开始初始Teacher表

package mainimport ("gorm/mysqldb"
)func main() {db := mysqldb.Mysql_connect()//开始初始化表db.AutoMigrate(&mysqldb.Teacher{})
}

查看数据库内容teachers表已经创建好。这里可以看到 BaseModel 不用初始化为数据库表。teacher表中也会继承了它的字段

mysql> use godb
Database changed
mysql> show tables;
+----------------+
| Tables_in_godb |
+----------------+
| teachers       |
+----------------+
1 row in set (0.00 sec)mysql> desc teachers;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| create_time | datetime(3) | YES  |     | NULL    |                |
| update_time | datetime(3) | YES  |     | NULL    |                |
| name        | varchar(32) | NO   | UNI | NULL    |                |
| tno         | bigint(20)  | YES  |     | NULL    |                |
| pwd         | longtext    | YES  |     | NULL    |                |
| tel         | longtext    | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

2.1 手动插入数据

这里手动插入数据。ID列是自增长列,在手动插入数据的时候写NULL就可以了。两个时间字段用now()函数就可以了

mysql>insert into  teachers values(NULL,now(),now(),"teacher wang",3123,"wang!","13312312311");
mysql> select * from teachers;
+----+-------------------------+-------------------------+--------------+------+-------+-------------+
| id | create_time             | update_time             | name         | tno  | pwd   | tel         |
+----+-------------------------+-------------------------+--------------+------+-------+-------------+
|  1 | 2023-07-20 22:37:20.000 | 2023-07-20 22:37:20.000 | teacher wang | 3123 | wang! | 13312312311 |
+----+-------------------------+-------------------------+--------------+------+-------+-------------+
1 row in set (0.00 sec)

2.2 在次初始化

go run main.go

此时发现数据没有受到任何影响。
但是会重复生成: UNIQUE KEY. 通过show create table 表名查看

2.3 表名变复数

结构体的名称为teacher 但是创建的表变成了teachers 多了一个s 这是在迁移过程中库自己加的。如果不影响使用可以忽略。

3.class表

class表对应结构体如下

type Class struct {BaseModuleName string `gorm:"type:varchar(32);unique;not null"`Num  intTId  intT    Teacher
}

注意:

TId  int 
这个字段是外键字段,字段的值指向 teacher表的 id 字段值
T    Teacher
这个成员变量不会在mysql中产生字段。这是设置的 TId字段的 外键关联语句,相当于 foreign key 字段名 refences 主表(id)1.T的意思是:gorm会根据这个名字(T)自动在后边加上Id,然后在结构体中找这个变量,并且将这个字段设置为外键。 也就是说 T = TId. 如果你的外键字段在命名时,那将设置外键关联失败
2.Teacher的意思是: 它是Teacher表, gorm在管理的时候 会自动关联到Teacher的ID字段这中简写方式是gorm 提供的语法糖

1.开始迁移

package mainimport ("gorm/mysqldb"
)func main() {db := mysqldb.Mysql_connect()db.AutoMigrate(&mysqldb.Class{})}

2.查看表

mysql> show tables;
+----------------+
| Tables_in_godb |
+----------------+
| classes        |
| teachers       |
+----------------+
2 rows in set (0.00 sec)mysql> desc classes;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| create_time | datetime(3) | YES  |     | NULL    |                |
| update_time | datetime(3) | YES  |     | NULL    |                |
| name        | varchar(32) | NO   | UNI | NULL    |                |
| num         | bigint(20)  | YES  |     | NULL    |                |
| t_id        | bigint(20)  | YES  | MUL | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)mysql> show create table classes;| classes | CREATE TABLE `classes` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`create_time` datetime(3) DEFAULT NULL,`update_time` datetime(3) DEFAULT NULL,`name` varchar(32) NOT NULL,`num` bigint(20) DEFAULT NULL,`t_id` bigint(20) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`),KEY `fk_classes_t` (`t_id`),//这里已经创建好了外键关联CONSTRAINT `fk_classes_t` FOREIGN KEY (`t_id`) REFERENCES `teachers` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

三、新增数据

1.Teacher表新增数据

package mainimport ("gorm/mysqldb""gorm.io/gorm"
)func Insert(db *gorm.DB) {t1 := mysqldb.Teacher{Name: "wang", Tno: 1, Pwd: "123!", Tel: "11012341235"}db.Create(&t1)
}func main() {db := mysqldb.Mysql_connect()Insert(db)}

1.1.注意事项1

t1 := mysqldb.Teacher{Name: "wang", Tno: 1, Pwd: "123!", Tel: "11012341235"}
实例化的时候使用键值对的方式赋值,不要使用{"wang",1,"123!","11012341235"}这种方式,因为我们继承了BaseModule

1.2.注意事项2

db.Create(&t1)
在新增数据的时候,一定要传入结构体实例的指针,因为gorm要把主键值回写到结构体实例

1.3 新增结果

这里可以看到,在新增的的时候,没有新增BaseModule的数据,但是在数据里自动生成了。并且ID是自增长的

mysql> select * from teachers;
+----+-------------------------+-------------------------+------+------+------+-------------+
| id | create_time             | update_time             | name | tno  | pwd  | tel         |
+----+-------------------------+-------------------------+------+------+------+-------------+
|  1 | 2023-08-03 10:21:03.551 | 2023-08-03 10:21:03.551 | wang |    1 | 123! | 11012341235 |
+----+-------------------------+-------------------------+------+------+------+-------------+
1 row in set (0.00 sec)

2.Class新增数据

func InsertClass(db *gorm.DB) {c1 := mysqldb.Class{Name: "python", Num: 30, TId: 1}db.Create(&c1)}

插入数据如下:

mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+
1 row in set (0.00 sec)

2.1 插入多条数据

func InsertClass(db *gorm.DB) {c2 := mysqldb.Class{Name: "java", Num: 30, TId: 1}c3 := mysqldb.Class{Name: "go", Num: 30, TId: 1}c4 := mysqldb.Class{Name: "shell", Num: 30, TId: 1}class_list := []mysqldb.Class{c2, c3, c4}db.Create(&class_list)}

插入数据如下:

mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
|  2 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | java   |   30 |    1 |
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | go     |   30 |    1 |
|  4 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | shell  |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+

四、单表查询

1.查询全部 db.Find()

func selectdata(db *gorm.DB) {// 这里定义切片的含义:// 1. 因为返回是多条数据,所以定义Class类型切片// 2. db.find函数是根据这里result的类型来判定去库里查找对应的哪张表var result []mysqldb.Class// 将查询结果集回写到result切片当中db.Find(&result)for i, v := range result {fmt.Println("i = ", i)fmt.Println("v = ", v.Name)}
}

执行结果如下:

E:\code\project\后端项目\go_project\gin框架学习>go run main.go
i =  0
v =  python
i =  1
v =  java
i =  2
v =  go
i =  3
v =  shell

2.查询单条

func selectdata(db *gorm.DB) {//三个变量设置的都是结构体实例,不是切片,因为查询结果是一条。var result mysqldb.Classvar result1 mysqldb.Classvar result2 mysqldb.Classdb.Take(&result)     //获取第一条记录,没有指定排序字段db.First(&result1)  //获取第一条记录(主键升序)db.Last(&result2)   //获取最后一条记录,主键降序fmt.Println("result = ", result)fmt.Println("result1 = ", result1)fmt.Println("result2 = ", result2)}

3.where查询

注意: where条件查询的时候,条件参数不能直接写,必须使用? 然后在将参数传递给?

3.1.等值查询

func selectdata(db *gorm.DB) {var result []mysqldb.Classdb.Where("Name = ?", "java").Find(&result)fmt.Println("result = ", result)
}

3.2 大于查询

func selectdata(db *gorm.DB) {var result []mysqldb.Classdb.Where("update_time > ?", "2023-08-08 13:40:00").Find(&result)fmt.Println("result = ", result)
}

3.3 and

func selectdata(db *gorm.DB) {var result []mysqldb.Classdb.Where("num = ? and name = ?", 30, "go").Find(&result)fmt.Println("result = ", result)
}

4. db.select

查询结果返回部分字段,而不是全部字段.

func selectdata(db *gorm.DB) {var result []mysqldb.Classdb.Select("Name,num").Where("num = ? and name = ?", 30, "go").Find(&result)fmt.Println("result = ", result)
}

这里只返回了Name和Num两个字段,其他字段内容没有进行回写

5.db.Omit

除了Name和Num字段 其他的字段其全部返回

func selectdata(db *gorm.DB) {var result []mysqldb.Classdb.Omit("Name,Num").Where("num = ? and name = ?", 30, "go").Find(&result)fmt.Println("result = ", result)
}

五、更新

数据库数据如下:

mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
|  2 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | java   |   30 |    1 |
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | go     |   30 |    1 |
|  4 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | shell  |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+

1.修改单个字段

将go 改为golang
这里的db.Model 是用来指定表对应的结构体。

func update_data(db *gorm.DB) {db.Model(&mysqldb.Class{}).Where("id = ?", 3).Update("name", "golang")
}

修改成功

mysql> select * from classes where id = 3;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | golang |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+
1 row in set (0.00 sec)

2.修改多个字段

注意这里用的是updates,上边用的是update

func update_data(db *gorm.DB) {db.Model(&mysqldb.Class{}).Where("id = ?", 3).Updates(mysqldb.Class{Name: "c++", Num: 20})}

修改成功

mysql> select * from classes where id = 3;
+----+-------------------------+-------------------------+------+------+------+
| id | create_time             | update_time             | name | num  | t_id |
+----+-------------------------+-------------------------+------+------+------+
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | c++  |   20 |    1 |
+----+-------------------------+-------------------------+------+------+------+
1 row in set (0.00 sec)

3.更新表达式gorm.Expr

func update_data(db *gorm.DB) {db.Model(&mysqldb.Class{}).Where("id = ?", 3).Update("num", gorm.Expr("num + 1"))}

更改结果如下:

mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
|  2 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | java   |   30 |    1 |
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | c++    |   21 |    1 |
|  4 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | shell  |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+
4 rows in set (0.00 sec)

相关文章:

gorm基本操作

一、gorm安装 1.下载gorm go get -u gorm.io/gorm //gorm框架 go get -u gorm.io/driver/mysql //驱动2.mysql准备工作 mysql> create database godb; mysql> grant all on *.* to admin% identified by golang123!; mysql> flush privileges;3.导入gorm框架 impo…...

华为OD机试 - 排队游戏(Java JS Python)

题目描述 新来的老师给班里的同学排一个队。 每个学生有一个影力值。 一些学生是刺头,不会听老师的话,自己选位置,非刺头同学在剩下的位置按照能力值从小到大排。 对于非刺头同学,如果发现他前面有能力值比自己高的同学,他不满程度就增加,增加的数量等于前面能力值比…...

滚动条样式更改

::-webkit-scrollbar 滚动条整体部分,可以设置宽度啥的 ::-webkit-scrollbar-button 滚动条两端的按钮 ::-webkit-scrollbar-track 外层轨道 ::-webkit-scrollbar-track-piece 内层滚动槽 ::-webkit-scrollbar-thumb 滚动的滑块 ::-webkit-scrollbar…...

掌握Python的X篇_33_MATLAB的替代组合NumPy+SciPy+Matplotlib

numPy 通常与 SciPy( Scientific Python )和 Matplotlib (绘图库)一起使用,这种组合广泛用于替代 MatLab,是一个强大的科学计算环境,有助于我们通过 Python 学习数据科学或者机器学习。 文章目录 1. numpy1.1 numpy简介1.2 矩阵类型的nparra…...

Python解决-力扣002-两数相加

两数相加:链表表示的逆序整数求和 在这篇技术博客中,我们将讨论一个力扣(LeetCode)上的编程题目:两数相加。这个问题要求我们处理两个非空链表,它们表示两个非负整数。每个链表中的数字都是逆序存储的&…...

nginx基于源码安装的方式对静态页面、虚拟主机(IP、端口、域名)和日志文件进行配置

一.静态页面 1.更改页面内容 2.更改配置文件 3.测试 二.虚拟主机配置 1.基于IP (1)在html目录下新建目录存放测试文件 (2)修改nginx.conf文件,在htttp模块中配置两个server模块分别对应两个IP (3&am…...

[FPAG开发]使用Vivado创建第一个程序

1 打开Vivado软件,新建项目 选择一个纯英文路径 选择合适的型号 产品型号ZYNQ-7010xc7z010clg400-1ZYNQ-7020xc7z010clg400-2 如果型号选错,可以单击这里重新选择 2 创建工程源文件 可以看到文件创建成功 双击文件打开,插入代码 modul…...

使用 Python 在 NLP 中进行文本预处理

一、说明 自然语言处理 (NLP) 是人工智能 (AI) 和计算语言学的一个子领域,专注于使计算机能够理解、解释和生成人类语言。它涉及计算机和自然语言之间的交互,允许机器以对人类有意义和有用的方式处理、分析…...

[足式机器人]Part3机构运动微分几何学分析与综合Ch03-1 空间约束曲线与约束曲面微分几何学——【读书笔记】

本文仅供学习使用 本文参考: 《机构运动微分几何学分析与综合》-王德伦、汪伟 《微分几何》吴大任 Ch01-4 平面运动微分几何学 3.1 空间曲线微分几何学概述3.1.1 矢量表示3.1.2 Frenet标架 连杆机构中的连杆与连架杆构成运动副,该运动副元素的特征点或特…...

pytest框架快速进阶篇-pytest前置和pytest后置,skipif跳过用例

一、Pytest的前置和后置方法 1.Pytest可以集成unittest实现前置和后置 importunittestimportpytestclassTestCase(unittest.TestCase):defsetUp(self)->None:print(unittest每个用例前置)deftearDown(self)->None:print(unittest每个用例后置)classmethoddefsetUpClass…...

Python 基础语法 | 常量表达式,变量,注释,输入输出

常量和表达式 我们可以把 Python 当成一个计算器,来进行一些算术运算 print(1 2 - 3) # 0 print(1 2 * 3) # 7 print(1 2 / 3) # 1.6666666666666665注意: print 是一个 Python 内置的 函数可以使用 - * / () 等运算符进行算术运算,先…...

SQL | 分组数据

10-分组数据 两个新的select子句:group by子句和having子句。 10.1-数据分组 上面我们学到了,使用SQL中的聚集函数可以汇总数据,这样,我们就能够对行进行计数,计算和,计算平均数。 目前为止&#xff0c…...

软件测试技术之如何编写测试用例(6)

四、客户端兼容性测试 1、平台测试 市场上有很多不同的操作系统类型,最常见的有Windows、Unix、Macintosh、Linux等。Web应用系统的最终用户究竟使用哪一种操作系统,取决于用户系统的配置。这样,就可能会发生兼容性问题,同一个应…...

论文阅读——Adversarial Eigen Attack on Black-Box Models

Adversarial Eigen Attack on Black-Box Models 作者:Linjun Zhou, Linjun Zhou 攻击类别:黑盒(基于梯度信息),白盒模型的预训练模型可获得,但训练数据和微调预训练模型的数据不可得&#xff…...

自然语言处理从入门到应用——LangChain:记忆(Memory)-[自定义对话记忆与自定义记忆类]

分类目录:《自然语言处理从入门到应用》总目录 自定义对话记忆 本节介绍了几种自定义对话记忆的方法: from langchain.llms import OpenAI from langchain.chains import ConversationChain from langchain.memory import ConversationBufferMemoryllm…...

【C/C++】STL queue 非线程安全接口,危险!

STL 中的 queue 是非线程安全的,一个组合操作:front(); pop() 先读取队首元素然后删除队首元素,若是有多个线程执行这个组合操作的话,可能会发生执行序列交替执行,导致一些意想不到的行为。因此需要重新设计线程安全的…...

执行Lua脚本后一直查询不到Redis中的数据(附带问题详细排查过程,一波三折)

文章目录 执行Lua脚本后一直查询不到Redis中的数据(附带详细问题排查过程,一波三折)问题背景问题1:Lua脚本无法切库问题2:RedisTemlate切库报错问题3:序列化导致数据不一致问题4:Lua脚本中单引号…...

[高光谱]PyTorch使用CNN对高光谱图像进行分类

项目原地址: Hyperspectral-Classificationhttps://github.com/eecn/Hyperspectral-ClassificationDataLoader讲解: [高光谱]使用PyTorch的dataloader加载高光谱数据https://blog.csdn.net/weixin_37878740/article/details/130929358 一、模型加载 在…...

jmeter获取mysql数据

JDBC Connection Configuration Database URL: jdbc:mysql:// 数据库地址 /库名 JDBC Driver class:com.mysql.jdbc.Driver Username:账号 Password:密码 JDBC Request 字段含义 字段含义 Variable Name Bound to Pool 数据库连接池配置…...

Dedecms V110最新版RCE---Tricks

前言 刚发现Dedecms更新了发布版本,顺便测试一下之前的day有没有修复,突然想到了新的tricks去实现RCE。 文章发布的时候估计比较晚了,一直没时间写了。 利用 /uploads/dede/article_string_mix.php /uploads/dede/article_template_rand.…...

Visual Studio 项目属性页开发完全教程:从基础到高级

Visual Studio 项目属性页开发完全教程:从基础到高级 【免费下载链接】project-system The .NET Project System for Visual Studio 项目地址: https://gitcode.com/gh_mirrors/pr/project-system Visual Studio 项目属性页是开发者管理项目配置的核心界面&a…...

Qwen3-Coder-30B-A3B-Instruct-FP8:终极代码模型对比分析指南

Qwen3-Coder-30B-A3B-Instruct-FP8:终极代码模型对比分析指南 【免费下载链接】Qwen3-Coder-30B-A3B-Instruct-FP8 项目地址: https://ai.gitcode.com/hf_mirrors/Qwen/Qwen3-Coder-30B-A3B-Instruct-FP8 在当今AI代码生成领域,Qwen3-Coder-30B-…...

Lampiao 靶场

Lampiao 靶场完整渗透解析一、靶场环境信息攻击机(Kali)IP:192.168.146.128靶机 IP:192.168.146.129目标:获取靶机 root 权限与 flag二、步骤 1:信息收集(端口与服务扫描)nmap -p- -…...

从入门到上岗,Java+AI 复合型人才养成攻略

当下编程行业格局正在悄然改变,纯 Java 后端岗位内卷日趋严重,薪资增长逐步放缓;纯粹的 AI 算法岗门槛居高不下,对学历、数理功底要求严苛,普通开发者很难入局。 而Java+AI 复合型开发顺势成为行业刚需岗位,既依托成熟的 Java 体系承接业务开发,又能融入人工智能技术实…...

户外实用|艾迪欧 R6000 测评 —— 户外 / 自驾 / 露营的通讯好搭档

户外出行,通讯工具的核心是稳定、清晰、耐用、续航久、功能全。艾迪欧 R6000 作为一款兼顾专业与户外的 DMR 对讲机,全频段覆盖、双模通讯、自定义功能、长续航,完美适配自驾、露营、登山、越野等户外场景,是户外爱好者的靠谱通讯…...

AI圈内火热的Agent、MCP、Skill、CLI是啥?用装修房子讲透,看完秒懂

本文用装修房子的比喻,详细解释了AI领域的四个核心概念:Agent如同会自主规划任务的私人助理;MCP是AI与外部工具数据的统一接口,类似USB-C;Skill是指导AI按标准操作执行的手册;CLI则是不依赖图形界面的命令行…...

风控系统如何全维度识别爬虫:IP、账号与行为的协同决策机制

1. 这不是“反爬失败”,而是风控系统在对你做全维度画像你写完一段 requests BeautifulSoup 的代码,本地跑通了,开开心心部署到服务器,结果第二天早上发现:所有请求返回 403,日志里全是空响应;…...

JWT弱密钥爆破实战:从HS256签名原理到CTF权限提升

1. 这不是密码学考试,而是一场“密钥猜谜”实战JWT(JSON Web Token)在现代Web系统中早已不是可选项,而是默认配置。登录成功后返回一串形如eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMjMsIm5hbWUiOiLnlKjliYkiLCJpYX…...

别再纠结了!给激光焊接新手讲透单模和多模激光到底怎么选(附M²因子解读)

激光焊接设备选型指南:单模与多模激光的实战抉择 当你第一次站在激光焊接设备采购的十字路口,面对"单模"和"多模"这两个专业术语时,那种迷茫感我深有体会。五年前,我作为产线技术负责人,需要为汽车…...

解决claude code频繁封号与token不足的taotoken接入方案

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 解决Claude Code频繁封号与Token不足的Taotoken接入方案 1. 问题背景:Claude Code用户面临的挑战 对于依赖Claude Cod…...