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

基于Gin+Gorm框架搭建MVC模式的Go语言企业级后端系统

文/朱季谦

环境准备:安装Gin与Gorm

本文搭建准备环境:Gin+Gorm+MySql。

Gin是Go语言的一套WEB框架,在学习一种陌生语言的陌生框架,最好的方式,就是用我们熟悉的思维去学。作为一名后端Java开发,在最初入门时,最熟悉的莫过于MVC分层结构,可以简单归纳成controller层,model层,dao层,而在SpringBoot框架里,大概也经常看到以下的分层结构——

image

这个结构分为java根目录与resources资源目录。

在学习Go语言的Gin框架时,是否也可以参照这样的分层结构来搭建一套简单的后端系统呢。

答案是,肯定的。

接下来,我们就按照这个MVC分层结构,搭建一套基于Gin+Gorm框架的Go语言后端。

搭建之前,先简单介绍一下Gin和Gorm分别是什么。

Gin是一个golang的WEB框架,很轻量,依赖到很少,有些类似Java的SpringMVC,通过路由设置,可以将请求转发到对应的处理器上。

Gorm是Go语言的ORM框架,提供一套对数据库进行增删改查的接口,使用它,就可以类似Java使用Hibernate框架一样,可对数据库进行相应操作。

若要用到这两套框架,就需要import依赖进来,依赖进来前,需要Go命令安装Gin和Gorm。

go get -u github.com/gin-gonic/gin
go get -u github.com/jinzhu/gorm

最好放在GOPATH目录下。

我的GOPATH目录在C:\Users\Administrator\go下:

image

通过Go命令安装的依赖包放在这个目录底下C:\Users\Administrator\go\src下:

image

现在,我们就参考SpringBoot的分层结构,搭建一套MVC分层结构系统。
 

一、搭建根目录与资源目录。

先创建一个Go项目,这里,我取名为go-admin,底下创建一个go目录,用于存放Go代码;一个resources资源目录,存放配置文件,结构如下——
 

image


go根目录底下,创建controller、service、dao、entity包,另外,还需要一个router包,用于存放路由文件,可能你对路由文件不是很理解,那么,你可以简单理解为,这个路由的作用,就类似SpringMVC的@RequestMapping("/user")和@GetMapping("/list")注解组合起到的作用,通过路由,就可以找到需要调用的后端方法。创建完这些包后,若在SpringBoot项目里,是否还缺少一个xxxxxApplication.java的启动类,没错,在Go里,同样需要一个启动类,该启动类文件可以直接命名为main.go。

创建以上包与类后,go根目录底下结构如下:

image

接下来,是在resources资源目录创建一个application.yaml配置文件,当然,这个配置文件可以随便命名,不用像SpringBoot那样需要考虑其命名背后所代表的优先级。
 

image


这个配置文件里,就存放需要用到的Mysql数据库连接信息:

url: 127.0.0.1
userName: root
password: root
dbname: example
post: 3306

这些基础工作做好后,就可以填充代码了。

二、dao层的搭建。

在dao层下,建立一个mysql.go文件,这个文件在dao的包下,最初的效果如下

image

按照以往jdbc连接数据库的步骤,首先需要加载jdbc驱动程序,然后再创建数据库的连接,其实,在Go连接数据库,同样需要类似这样的操作。

首先,需要导入数据库驱动程序。

Gorm已经包含了驱动程序,只需要将它导入进来即可:

import _ "github.com/jinzhu/gorm/dialects/mysql"

进入到这个依赖包的源码,根据命名就可以看到出,这是一个go语言的mysql驱动包——

image

除此之外,还提供了mssql、postgres、sqlite的驱动包。

底层使用到的是GORM 框架,自然也要把它依赖进来:

import  "github.com/jinzhu/gorm"

另外,还需要依赖以下几个包,用于读取yaml配置文件数据与拼接成url字符串:

import "io/ioutil"
import "gopkg.in/yaml.v2"
import "fmt"

当依赖的包过多时,我们可以统一放到一个()号里,例如这样:

import ("github.com/jinzhu/gorm"_ "github.com/jinzhu/gorm/dialects/mysql""io/ioutil""gopkg.in/yaml.v2""fmt"
)

到这一步,效果如下:

image

这里爆红色是正常的,Go语言与Java不同的一个地方是,若依赖进来的包,没有被用到话,会直接出现红色异常提示,后面写到用到它们的代码时,就正常了。

接下来,定义一个用于接收yaml配置参数的struct结构体,你可以简单将它理解为Java的类。

type conf struct {Url string `yaml:"url"`UserName string `yaml:"userName"`Password string `yaml:"password"`DbName string `yaml:"dbname"`Port string `yaml:"post"`
}

然后提供一个读取解析该yaml配置的方法,将读取到的配置参数数据转换成上边的结构体conf

func (c *conf) getConf() *conf {//读取resources/application.yaml文件yamlFile, err := ioutil.ReadFile("resources/application.yaml")//若出现错误,打印错误提示if err != nil {fmt.Println(err.Error())}//将读取的字符串转换成结构体conferr = yaml.Unmarshal(yamlFile, c)if err != nil {fmt.Println(err.Error())}return c
}

后面可以通过debug观察一下,这个返回的c变量,它就类似Java的对象,里边是key-value形式的值——

image

最后,就可以根据这些解析到的配置参数,用来驱动连接数据库了。

创建一个类似旧版mybatis全局的SqlSession变量,就取名为SqlSession即可,该变量起到作用于mybatis的SqlSession实例类似,在数据库驱动连接成功后,即可提供select/insert/update/delete方法。

var SqlSession *gorm.DB

然后定义一个初始化连接数据库的方法,该方法用于在启动项目时执行——

func InitMySql()(err error)  {var c conf//获取yaml配置参数conf:=c.getConf()//将yaml配置参数拼接成连接数据库的urldsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",conf.UserName,conf.Password,conf.Url,conf.Port,conf.DbName,)//连接数据库SqlSession,err =gorm.Open("mysql",dsn)if err !=nil{panic(err)}//验证数据库连接是否成功,若成功,则无异常return SqlSession.DB().Ping()
}

最后,还需要提供一个可以关闭数据库连接的方法——

func Close()  {SqlSession.Close()
}

到这里,我们就完成了Dao层的搭建,该层里的代码主要负责连接数据库,创建一个取名为SqlSession全局的*gorm.DB变量,该变量作用类似SqlSession,提供了操作数据库的方法,最后,整块dao层的mysql.go代码就如下:

package daoimport ("github.com/jinzhu/gorm""io/ioutil"
)import ("github.com/jinzhu/gorm"_ "github.com/jinzhu/gorm/dialects/mysql""io/ioutil""gopkg.in/yaml.v2""fmt"
)
//指定驱动
const DRIVER = "mysql"var SqlSession *gorm.DB//配置参数映射结构体
type conf struct {Url string `yaml:"url"`UserName string `yaml:"userName"`Password string `yaml:"password"`DbName string `yaml:"dbname"`Port string `yaml:"post"`
}//获取配置参数数据
func (c *conf) getConf() *conf {//读取resources/application.yaml文件yamlFile, err := ioutil.ReadFile("resources/application.yaml")//若出现错误,打印错误提示if err != nil {fmt.Println(err.Error())}//将读取的字符串转换成结构体conferr = yaml.Unmarshal(yamlFile, c)if err != nil {fmt.Println(err.Error())}return c
}//初始化连接数据库,生成可操作基本增删改查结构的变量
func InitMySql()(err error)  {var c conf//获取yaml配置参数conf:=c.getConf()//将yaml配置参数拼接成连接数据库的urldsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",conf.UserName,conf.Password,conf.Url,conf.Port,conf.DbName,)//连接数据库SqlSession,err =gorm.Open(DRIVER,dsn)if err !=nil{panic(err)}//验证数据库连接是否成功,若成功,则无异常return SqlSession.DB().Ping()
}
//关闭数据库连接
func Close()  {SqlSession.Close()
}

三、entity层定义模型。

Gorm是全特性的ORM框架,即对象关系映射,这样,就需要类似Java那样建立与数据库映射的类,在Go语言当中,我们称之为结构体。

首先,先创建一张用于验证的数据库表结构——

CREATE TABLE `sys_user` (`id` int(50) unsigned NOT NULL AUTO_INCREMENT,`name` varchar(50) NOT NULL COMMENT '用户名',`nick_name` varchar(150) DEFAULT NULL COMMENT '昵称',`avatar` varchar(150) DEFAULT NULL COMMENT '头像',`password` varchar(100) DEFAULT NULL COMMENT '密码',`email` varchar(100) DEFAULT NULL COMMENT '邮箱',`mobile` varchar(100) DEFAULT NULL COMMENT '手机号',`create_time` bigint(50) DEFAULT NULL COMMENT '更新时间',`del_status` tinyint(4) DEFAULT '0' COMMENT '是否删除 -1:已删除   0:正常',PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COMMENT='用户表';

然后创建一个User.go文件,里边定义一个User结构体——

type User struct {Id int `json:"id"`Name string `json:"name"`NickName string `json:"nickName"`Avatar string `json:"avatar"`Password string `json:"password"`Email string `json:"email"`Mobile string `json:"mobile"`DelStatus int `json:"delStatus"`CreateTime int64 `json:"createTime"`
}

注意一点,这里需要明确指出,其struct结构体映射到哪一张表,如果没有显示指出,它会默认生成一张命名为users的数据库表——

// 数据库表明自定义,默认为model的复数形式,比如这里默认为 users
func (User) TableName() string {return "sys_user"
}

到这一步,我们就完成了user模型关系建立。

package entity// 数据库表明自定义,默认为model的复数形式,比如这里默认为 users
func (User) TableName() string {return "sys_user"
}type User struct {Id int `json:"id"`Name string `json:"name"` NickName string `json:"nickName"`Avatar string `json:"avatar"`Password string `json:"password"`Email string `json:"email"`Mobile string `json:"mobile"`DelStatus int `json:"delStatus"`CreateTime int64 `json:"createTime"`
}

四、service层建立增删改查业务逻辑。

在service层建立一个User的service类,命名为UserService.go。

这里,需要引入两个依赖,一个是dao层创建的全局SqlSession,用于操作数据库;一个是User类,用于接收数据库对应表结构的数据。

import ("go-admin/go/dao""go-admin/go/entity"
)

接下来,就可以基于SqlSession获取到的API接口,对数据库进行简单的增删改查操作了。

1.添加User信息

/**
新建User信息*/
func CreateUser(user *entity.User)(err error)  {if err = dao.SqlSession.Create(user).Error;err!=nil{return err}return
}

2.查询所有的User记录

/**
获取user集合*/
func GetAllUser()(userList []*entity.User,err error)  {if err:=dao.SqlSession.Find(&userList).Error;err!=nil{return nil,err}return
}

3.根据id删除对应的User信息

/**
根据id删除user*/
func DeleteUserById(id string)(err error){err = dao.SqlSession.Where("id=?",id).Delete(&entity.User{}).Errorreturn
}

4.根据id查询用户User

/**
根据id查询用户User*/
func GetUserById(id string)(user *entity.User,err error)  {if err = dao.SqlSession.Where("id=?",id).First(user).Error;err!=nil{return nil,err}return
}

5.更新用户信息

/**
更新用户信息*/
func UpdateUser(user * entity.User)(err error)  {err = dao.SqlSession.Save(user).Errorreturn
}

UserService.go的完整代码如下:

package serviceimport ("go-admin/go/dao""go-admin/go/entity"
)/**
新建User信息*/
func CreateUser(user *entity.User)(err error)  {if err = dao.SqlSession.Create(user).Error;err!=nil{return err}return
}/**
获取user集合*/
func GetAllUser()(userList []*entity.User,err error)  {if err:=dao.SqlSession.Find(&userList).Error;err!=nil{return nil,err}return
}/**
根据id删除user*/
func DeleteUserById(id string)(err error){err = dao.SqlSession.Where("id=?",id).Delete(&entity.User{}).Errorreturn
}/**
根据id查询用户User*/
func GetUserById(id string)(user *entity.User,err error)  {if err = dao.SqlSession.Where("id=?",id).First(user).Error;err!=nil{return nil,err}return
}/**
更新用户信息*/
func UpdateUser(user * entity.User)(err error)  {err = dao.SqlSession.Save(user).Errorreturn
}

五、controller层建立User的controller类。

在controller层建立一个UserController.go类,类似Java的controller,主要用于根据url跳转执行到对应路径的方法。

首先,引入需要用到的依赖包,

import (//需要用到的结构体"go-admin/go/entity"//gin框架的依赖"github.com/gin-gonic/gin"//http连接包"net/http"//service层方法"go-admin/go/service"
)

接下来,可以实现增删改查的controller方法了。

1.实现新增User的方法

func CreateUser(c *gin.Context)  {//定义一个User变量var user entity.User//将调用后端的request请求中的body数据根据json格式解析到User结构变量中c.BindJSON(&user)//将被转换的user变量传给service层的CreateUser方法,进行User的新建err:=service.CreateUser(&user)//判断是否异常,无异常则返回包含200和更新数据的信息if err!=nil{c.JSON(http.StatusBadRequest,gin.H{"error":err.Error()})}else {c.JSON(http.StatusOK,gin.H{"code":200,"msg":"success","data":user,})}
}

2.查询User的方法

func GetUserList(c *gin.Context)  {todoList,err :=service.GetAllUser()if err!=nil{c.JSON(http.StatusBadRequest,gin.H{"error":err.Error()})}else {c.JSON(http.StatusOK,gin.H{"code":200,"msg":"success","data":todoList,})}
}

六、routes层增加路由文件,用于根据请求url进行转发。

routes层新建一个Routers.go文件。

首先,同样需要引入需要用到的依赖——

import (
"go-admin/go/controller"
"github.com/gin-gonic/gin"
)

然后搭建一个初始化路由的操作,将路由统一存放到数据user的group组里,这样可以比较方便区分这些路由数据哪个controller类的。

Routers.go文件完整代码如下:

package routesimport (
"go-admin/go/controller"
"github.com/gin-gonic/gin"
)func SetRouter() *gin.Engine  {r :=gin.Default()/**用户User路由组*/userGroup :=r.Group("user"){//增加用户UseruserGroup.POST("/users",controller.CreateUser)//查看所有的UseruserGroup.GET("/users",controller.GetUserList)//修改某个UseruserGroup.PUT("/users/:id",controller.UpdateUser)//删除某个UseruserGroup.DELETE("/users/:id",controller.DeleteUserById)}return r
}

七、main启动类。

最后一步,就是建立main的启动类了,需要注意一点是,go的启动类,必须命名在package main的包下,否则无法进行启动。

首先,还是需要先引入依赖,main启动类需要用到dao、entity、routers以及mysql驱动包。

import ("go-admin/go/dao""go-admin/go/entity""go-admin/go/routes"_ "github.com/jinzhu/gorm/dialects/mysql"
)

启动方法里的代码主要如下,即前边搭建的东西,这里都有用到了——

func main()  {//连接数据库err :=dao.InitMySql()if err !=nil{panic(err)}//程序退出关闭数据库连接defer dao.Close()//绑定模型dao.SqlSession.AutoMigrate(&entity.User{})//注册路由r :=routes.SetRouter()//启动端口为8085的项目r.Run(":8081")
}

到这一步,就可以启动项目了,正常情况下,启动成功会显示以下日志信息——

image

到这一步,基于Gin+Gorm框架搭建MVC模式的Go后端系统,就初步搭建完成了。

最后,代码已经上传到GitHub:GitHub - z924931408/go-admin: 这是个人Go语言基于Gin+gorm框架搭建的MVC结构的后端模块。

相关文章:

基于Gin+Gorm框架搭建MVC模式的Go语言企业级后端系统

文/朱季谦 环境准备:安装Gin与Gorm 本文搭建准备环境:GinGormMySql。 Gin是Go语言的一套WEB框架,在学习一种陌生语言的陌生框架,最好的方式,就是用我们熟悉的思维去学。作为一名后端Java开发,在最初入门…...

【开源】基于Vue和SpringBoot的固始鹅块销售系统

项目编号: S 060 ,文末获取源码。 \color{red}{项目编号:S060,文末获取源码。} 项目编号:S060,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 鹅块类型模块2.3 固…...

Windows11怎样投屏到电视上?

电视屏幕通常比电脑显示器更大,能够提供更逼真的图像和更震撼的音效,因此不少人也喜欢将电脑屏幕投屏到电视上,缓解一下低头看电脑屏幕的烦恼。 Windows11如何将屏幕投射到安卓电视? 你需要在电脑和电视分贝安装AirDroid Cast的电…...

ubuntu中用docker部署jenkins,并和码云实现自动化部署

1.部署jenkins docker network create jenkins docker run --name jenkins-docker --rm --detach \--privileged --network jenkins --network-alias docker \--env DOCKER_TLS_CERTDIR/certs \--volume jenkins-docker-certs:/certs/client \--volume jenkins-data:/var/jen…...

for,while,do-while,死循环,嵌套循环,跳转关键字,随机数

1.for循环 public class ForDemo1 {public static void main(String[] args) {for (int i 0; i < 5; i) {System.out.println("HelloWorld");}System.out.println("--------------------------------------------");for (int i 1; i <10 ; i) {Sy…...

【六袆 - MySQL】SQL优化;Explain SQL执行计划分析;

Explain SQL执行计划分析 概念:English Unit案例分析1.分析的SQL2.执行计划分析 【如图】MySQL执行计划参数以及它们的影响或意义:概念: MySQL执行计划(Execution Plan)是数据库系统根据查询语句生成的一种执行策略,用于指导数据库引擎执行查询操作。 English Unit This…...

【AI视野·今日NLP 自然语言处理论文速览 第六十二期】Wed, 25 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 25 Oct 2023 (showing first 100 of 112 entries) Totally 100 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers MuSR: Testing the Limits of Chain-of-thought with Multistep Soft R…...

各种符号地址,可以直接复制粘贴使用

字符符号 - 文本数字工具 | 偷懒工具 toolight.cn...

C语言测试题:用冒泡法对输入的10个字符由小到大排序 ,要求数组做为函数参数。

编写一个函数&#xff1a; 用冒泡法对输入的10个字符由小到大排序 &#xff0c;要求数组做为函数参数。 冒泡排序是一种简单的排序算法&#xff0c;它会多次遍历要排序的数列&#xff0c; 每次遍历时&#xff0c;依次比较相邻的两个元素&#xff0c;如果它们的顺序不符合要求…...

uni-app开发微信小程序 vue3写法添加pinia

说明 使用uni-app开发&#xff0c;选择vue3语法&#xff0c;开发工具是HBliuderX。虽然内置有vuex&#xff0c;但是个人还是喜欢用Pinia&#xff0c;所以就添加进去了。 Pinia官网连接 添加步骤 第一步&#xff1a; 在项目根目录下执行命令&#xff1a; npm install pinia …...

centos三台主机配置互信ssh登录

1. 修改hosts信息 1.1三台主机上分别修改hosts文件 vi /etc/hosts1.2 三台主机分别填入如下内容&#xff0c;ip地址需要检查正确 192.168.126.223 node1 192.168.126.224 node2 192.168.126.225 node32. 秘钥生成和分发 2.1 在三台主机上分别生成秘钥 命令输入后&#xff…...

验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信你对这篇博客也感兴趣o (ˉ▽ˉ&#xff1b;) &#x1f4dc;表白墙/留言墙 —— 中级SpringBoot项目&#xff0c;MyBatis技术栈MySQL数据库开发&#xff0c;练手项目前后端开发(带完整源码) 全方位全步骤手…...

js/jQuery 的一些常用操作(js/jQuery获取表单元素值 以及 清空元素值的各种实现方式)——附测试例子,拿来即能实现效果

js/jQuery 的一些常用操作&#xff08;js/jQuery获取表单元素值 以及 清空元素值的各种实现方式&#xff09;——附测试例子&#xff0c;拿来即能实现效果 1. 前言2. 获取表单元素的值2.1 简单获取元素中的值2.1.1 根据 id 简单取值2.2.2 根据name 简单取值2.1.3 获取单选按钮的…...

h5(react ts 适配)

一、新建项目并放在码云托管 1、新建项目&#xff1a;react ts h5 考虑到这些 用 create-react-app 脚手架来搭建项目。 首先&#xff0c;确保你已经安装了 Node.js。如果没有安装&#xff0c;请先从官方网站 https://nodejs.org/ 下载并安装 Node.js。打开命令行工具&#x…...

计算机视觉:驾驶员疲劳检测

目录 前言 关键点讲解 代码详解 结果展示 改进方向&#xff08;打哈欠检测疲劳方法&#xff09; 改进方向&#xff08;点头检测疲劳&#xff09; GUI界面设计展示 前言 上次博客我们讲到了如何定位人脸&#xff0c;并且在人脸上进行关键点定位。其中包括5点定位和68点定…...

Vue向pdf文件中添加二维码

&#x1f680; 场景一&#xff1a;利用vue向pdf文件中写入二维码图片或其他图片 &#x1f680; 场景二&#xff1a;向pdf中添加水印 思路&#xff1a; 1、先通过url链接生成二维码&#xff0c;二维码存在于dom中 2、使用html2canvas库将二维码的dom转为一个canvas对象 3、根据c…...

idea一键打包docker镜像并推送远程harbor仓库的方法(包含spotify和fabric8两种方法)--全网唯一正确,秒杀99%水文

我看了很多关于idea一键打包docker镜像并推送harbor仓库的文章&#xff0c;不论国内国外的&#xff0c;基本上99%都是瞎写的&#xff0c; 这些人不清楚打包插件原理&#xff0c;然后就是复制粘贴一大篇&#xff0c;写了一堆垃圾&#xff0c;然后别人拿来也不能用。 然后这篇文…...

程序设计:C++11原子 写优先的读写锁(源码详解二:操作跟踪)

本文承接程序设计&#xff1a;C11原子 写优先的读写锁&#xff08;源码详解&#xff09;-CSDN博客 上文已经列出了完整代码&#xff0c;完整代码里面增加了操作跟踪&#xff0c;这里就讲解一下这部分是如何实现的。 操作跟踪有两个层面&#xff1a;进程层面和线程层面。 由于这…...

Django视图层解析

Django视图&#xff08;View&#xff09;是Django Web框架中负责处理HTTP请求和返回HTTP响应的组件。视图是一段Python代码&#xff0c;接收HTTP请求作为输入&#xff0c;处理请求并返回HTTP响应作为输出。Django视图的主要目的是实现Web应用程序的业务逻辑&#xff0c;将模型和…...

JAVA使用RXTXcomm进行串口通信(一)

首先下载相应的jar文件 压缩包包括:RXTXcomm.jar(64位环境)、win32com.dll和javax.comm.properties。 下载地址:https://www.aliyundrive.com/s/JSeSQsAyYeZ 点击链接保存&#xff0c;或者复制本段内容&#xff0c;打开「阿里云盘」APP &#xff0c;无需下载极速在线查看&#…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件&#xff0c;这个上传文件是整体功能的一部分&#xff0c;文件在上传的过程中…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重&#xff0c;适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解&#xff0c;并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...

相关类相关的可视化图像总结

目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系&#xff0c;可直观判断线性相关、非线性相关或无相关关系&#xff0c;点的分布密…...