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

初始化一个Gin框架的Go-Web项目

使用到的第三方库

  • gin Gin 框架
  • viper 配置文件管理
  • cors 跨域资源请求配置
  • gorm ORM 库
  • zap 日志记录

main 包

Go 语言程序的入口点

main.go 文件

  1. 使用 flag 读取配置文件路径参数,默认当前目录下
  2. 使用 viper 读取 config.ini 配置文件初始化初始数据
  3. 初始化随机数种子
  4. 初始化数据库
  5. 声明启动程序模式
  6. 配置启动参数并启动服务
package mainimport ("flag""log""math/rand""project/dao""project/routers""time""github.com/gin-gonic/gin""github.com/spf13/viper"
)var (ServiceHost  stringServicePort  string
)func init() {var configPath stringflag.StringVar(&configPath, "config-path", ".", "path to config file")flag.Parse()viper.SetConfigName("config")   // 设置配置文件名为“config”viper.SetConfigType("ini")      // 设置配置文件类型为“ini”viper.AddConfigPath(configPath) // 设置在configPath中查找配置文件if err := viper.ReadInConfig(); err != nil {if _, ok := err.(viper.ConfigFileNotFoundError); ok {// Config file not found; ignore error if desiredlog.Panic("没有找到配置文件")} else {// Config file was found but another error was producedlog.Panic("初始化配置出错", err.Error())}}ServiceHost = viper.GetString("service.host")ServicePort = viper.GetString("service.port")dao.DatabaseUser = viper.GetString("database.user")dao.DatabasePwd = viper.GetString("database.pwd")dao.DatabaseHost = viper.GetString("database.host")dao.DatabasePort = viper.GetString("database.port")dao.DatabaseName = viper.GetString("database.name")
}
func main() {rand.Seed(time.Now().Unix())mode := "release"err := dao.InitMySQL()if err != nil {log.Println("初始化数据失败", err.Error())return}switch mode {case "debug":gin.SetMode(gin.DebugMode)case "release":gin.SetMode(gin.ReleaseMode)case "test":gin.SetMode(gin.TestMode)}r := routers.SetupRouter()s := &http.Server{Addr:         ServiceHost + ":" + ServicePort,Handler:      r,ReadTimeout:  5 * time.Second,WriteTimeout: 10 * time.Second,}err = s.ListenAndServe()if err != nil {panic(err)}
}

dao 包

通常被用于数据存储层的实现,可将底层数据库访问操作封装隐藏细节以简化数据库操作

mysql.go 文件

使用 gorm 初始化 MySQL 数据库连接

package daoimport ("fmt""log""gorm.io/driver/mysql""gorm.io/gorm"
)var (Db           *gorm.DBDatabaseUser stringDatabasePwd  stringDatabaseHost stringDatabasePort stringDatabaseName string
)func InitMySQL() (err error) {dsn := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True&loc=Local",DatabaseUser, DatabasePwd, DatabaseHost, DatabasePort, DatabaseName)Db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {log.Panic("连接数据库失败", err.Error())}// 测试数据库连接err = Db.Exec("SELECT 1").Errorif err != nil {log.Panic("数据库连接失败", err.Error())}return
}

routers 包

通常用于路由器配置,这个包中包含的代码需要读取 HTTP 请求并将该请求发送到相应后端的处理程序,然后从处理程序获取响应

routers.go 文件

  1. 创建日志记录器
  2. 初始化 gin 引擎
  3. 配置 cors 跨域请求
  4. 设置一个默认路由,及无请求到路由时返回的数据
package routersimport ("net/http""project/controller""github.com/gin-contrib/cors""github.com/gin-gonic/gin""go.uber.org/zap"
)func SetupRouter() *gin.Engine {// 创建一个生产级别的日志记录器logger, err := zap.NewProduction()if err != nil {panic(err)}// 在函数结束后刷新缓冲区defer logger.Sync()r := gin.Default()// 将 logger 存储在 Gin 的中间件中r.Use(func(c *gin.Context) {c.Set("logger", logger)c.Next()})r.Use(cors.New(cors.Config{AllowOrigins:     []string{"*"},AllowMethods:     []string{"POST, GET, PUT, DELETE, OPTIONS"},AllowHeaders:     []string{"Content-Type, Content-Length"},ExposeHeaders:    []string{"Access-Control-Allow-Headers"},AllowCredentials: true,}))r.GET("/first", controller.FirstHandler)// 下面有两个配置// 如果将前端服务与后端服务同时启动可以设置第一种,将前端打包的文件放到 public 文件夹内// 我这里设置的使用 vite 打包,所以就下面这种设置,可以自行更改// 当直接访问的时候,就相当于请求"/"路由,就会访问 index.html 页面// 设置静态文件服务目录r.Static("public", "public")r.Static("assets", "public/assets")r.GET("/", func(c *gin.Context) {c.File("public/index.html")})r.NoRoute(func(c *gin.Context) {c.File("public/index.html")})// 如果前后端分离模式,可以设置为请求到没有的路由就返回 Not Foundr.NoRoute(func(c *gin.Context) {c.JSON(http.StatusNotFound, gin.H{"msg": "Not Found",})})return r
}

controller 包

负责维护业务逻辑的实现,同时调用 Dao 对象实现数据存储、检索等功能,通常与用户交互并处理相关活动

controller.go 文件

  1. 创建初始默认路由函数,使用 info 级别的日志记录并返回数据
package controllerimport ("net/http""github.com/gin-gonic/gin""go.uber.org/zap"
)func FirstHandler(c *gin.Context) {c.MustGet("logger").(*zap.Logger).Info("这是一个Info日志")c.JSON(http.StatusOK, gin.H{"code": 1,"data": "Hello World","msg":  "成功",})
}

config.ini 文件

外部配置文件

[service]
host=127.0.0.1
port=8000
[database]
user=root
pwd=123456
host=127.0.0.1
port=3306
name=databasename

build.bat 文件

打包脚本,不用每次修改环境变量,不用手动输入打包命令
脚本内容:修改环境变量为 arm64 架构 Linux 系统,打包,还原为 amd64 架构 Windows 系统,我这里使用 Windows 做开发,需要部署到 arm64 架构的 Linux 服务器上,所以这样写,根据需要自行更改

@echo offgo env -w CGO_ENABLED=0
go env -w GOOS=linux
go env -w GOARCH=arm64
go build -ldflags "-w -s"
go env -w CGO_ENABLED=1
go env -w GOOS=windows
go env -w GOARCH=amd64

相关文章:

初始化一个Gin框架的Go-Web项目

使用到的第三方库 gin Gin 框架viper 配置文件管理cors 跨域资源请求配置gorm ORM 库zap 日志记录 main 包 Go 语言程序的入口点 main.go 文件 使用 flag 读取配置文件路径参数,默认当前目录下使用 viper 读取 config.ini 配置文件初始化初始数据初始化随机数种子初…...

Mybatis日期检索格式报错

问题复现 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String ##…...

如何把Android Framework学彻底?一条龙学习

Framework通俗易懂 平时学习 Android 开发的第一步就是去学习各种各样的 API,如 Activity,Service,Notification 等。其实这些都是 Framework 提供给我们的。Framework 层为开发应用程序提供了非常多的API,我们通过调用这些 API …...

uview indexList 按字母跳转不了

点击字母跳转不到位的问题&#xff1a;在<u-index-list>添加方法select“clickSelect“ 锚点要加id&#xff0c;用对应的字母做为id值&#xff0c; <u-index-anchor :id"key" :index"key"/> <template><view><view class&qu…...

安全模型中的4个P

引言&#xff1a;在安全模型中&#xff0c;经常会碰到PDR,PPDR&#xff0c;IPDRR&#xff0c;CARTA-PPDR等模型&#xff0c;其中的P&#xff0c;是predict&#xff1f;是prevent&#xff1f;还是protect&#xff1f;还是policy呢&#xff1f; 一、4P字典意思解释 1、predict&a…...

网站优化搜索引擎与关键词

网站优化搜索引擎与关键词 人们不应该高估搜索引擎的智商。这不利于seo的研究&#xff0c;事实上&#xff0c;搜索引擎是非常愚蠢的&#xff0c;让我们举一个非常简单的例子&#xff0c;你在搜索引擎中输入“教师”这个词&#xff0c;搜索引擎就会给出一个准确的搜索列表。我们…...

aws-msk-托管kafka集群的简单使用(VPC内部访问:无验证和SASL认证)

1.使用控制台创建即可 根据实例类型创建需要至少15分以上&#xff0c;可以提前创建好ec2实例和Secrets Manager,一会会使用到 2. 创建Secrets Manager &#xff08;使用无认证时请跳过&#xff09; 官方文档&#xff1a;https://docs.aws.amazon.com/zh_cn/msk/latest/deve…...

Unity UGUI(二)核心组件

Unity Canvas相关知识学习 文章目录 Unity Canvas相关知识学习1. Canvas&#xff1a;1.1 Render Mode1.2 多个Canvas的显示顺序 2.Canvas Scaler&#xff1a;屏幕分辨率自适应2.1 UI Scale Mode 3. EventSystem4. Standalone Input Module5. Graphic Raycaster&#xff1a;图形…...

代码随想录二刷第二天(Python)

27. 移除元素 题目链接&#xff1a;https://leetcode.cn/problems/remove-element/ 题目描述&#xff1a;给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。不要使用额外的数组空间&#xff0c;你必…...

Mybatis学习笔记1 Mybatis入门

差不多根据mybatis中文文档:创建第一个mybatismaven项目,将它跑起来 入门_MyBatis中文网 新建库 建表 创建项目 重启之后 配置下Maven与encoding 成习惯了 新建模块 注意:这个GroupId和ArtifactId version是之后,你用Maven install时候后存放的包路径和包名 目录结构:虽然换…...

Spark 管理和更新Hadoop token 流程

Hadoop Token 管理 AM 通过 kerberos authenticationAM 获取 Yarn 和 HDFS TokenAM send tokens to containersContainers load tokens Enable debug message log4j.logger.org.apache.hadoop.securityDEBUG AM Generate tokens Logs: 23/09/07 22:38:50,375 INFO [main]…...

Android文件关联

用户需求:Android在系统文件夹找到一个文件想发送自己开发的app进行处理该怎么办? 这时候可以采用两个Activity,一个Activity用作Launcher,一个用于处理发送的文件;具体Activity intent-filter该怎么写了?可以参考下面的代码: <intent-filter><action androi…...

java操作adb查看apk安装包包名【搬代码】

Testpublic static void findadb() throws InterruptedException {String apkip"E:\\需求\\2023\\gql_1.0.1.apk";String findname1"cmd /c cd E:\\appium\\android-sdk\\build-tools\\27.0.2";//没有进到这里String s1 Cmd.exeCmd(findname1);System.out…...

【JAVA】Object类与抽象类

作者主页&#xff1a;paper jie_的博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JAVASE语法系列》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和…...

【设计模式】二、UML 类图概述

文章目录 常见含义含义依赖关系&#xff08;Dependence&#xff09;泛化关系&#xff08;Generalization&#xff09;实现关系&#xff08;Implementation&#xff09;关联关系&#xff08;Association&#xff09;聚合关系&#xff08;Aggregation&#xff09;组合关系&#x…...

百望云亮相服贸会 重磅发布业财税融Copilot

小望小望&#xff0c;我要一杯拿铁&#xff01; 好的&#xff0c;已下单成功&#xff0c;请问要开具发票嘛&#xff1f; 在获得确认的指令后&#xff0c; 百小望AI智能助手 按用户要求成功开具了一张电子发票&#xff01; 这是2023年服贸会国家会议中心成果发布现场&#x…...

vue 项目代码混淆配置(自定义插件适用)带配置项注释

文章目录 vue 项目代码混淆配置&#xff08;自定义插件适用&#xff09;带配置项注释一、概要二、混淆步骤1. 引入混淆插件2. 添加混淆配置3. 执行代码混淆 vue 项目代码混淆配置&#xff08;自定义插件适用&#xff09;带配置项注释 一、概要 本文章适用 vue-cli3/webpack4 …...

手写Spring:第7章-实现应用上下文

文章目录 一、目标&#xff1a;实现应用上下文二、设计&#xff1a;实现应用上下文三、实现&#xff1a;实现应用上下文3.1 工程结构3.2 Spring应用上下文和Bean对象扩展类图3.3 对象工厂和对象扩展接口3.3.1 对象工厂扩展接口3.3.2 对象扩展接口 3.4 定义应用上下文3.4.1 定义…...

Java(三)逻辑控制(if....else,循环语句)与方法

逻辑控制&#xff08;if....else&#xff0c;循环语句&#xff09;与方法 四、逻辑控制1.if...else(常用)1.1表达格式&#xff08;三种&#xff09; 2.switch...case(用的少)2.1表达式 3.while(常用)3.1语法格式3.2关键字beak&#xff1a;3.3关键字 continue&#xff1a; 4.for…...

通过API接口实现数据实时更新的方案(InsCode AI 创作助手)

要实现实时数据更新&#xff0c;需要采用轮询或者长连接两种方式。 1. 轮询方式 轮询方式指的是客户端定时向服务器请求数据的方式&#xff0c;通过一定的时间间隔去请求最新数据。具体的实现方法包括&#xff1a; 客户端定时向服务器发送请求&#xff0c;获取最新数据&…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

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

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

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...