初始化一个Gin框架的Go-Web项目
使用到的第三方库
- gin Gin 框架
- viper 配置文件管理
- cors 跨域资源请求配置
- gorm ORM 库
- zap 日志记录
main 包
Go 语言程序的入口点
main.go 文件
- 使用 flag 读取配置文件路径参数,默认当前目录下
- 使用 viper 读取 config.ini 配置文件初始化初始数据
- 初始化随机数种子
- 初始化数据库
- 声明启动程序模式
- 配置启动参数并启动服务
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 文件
- 创建日志记录器
- 初始化 gin 引擎
- 配置 cors 跨域请求
- 设置一个默认路由,及无请求到路由时返回的数据
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 文件
- 创建初始默认路由函数,使用 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 按字母跳转不了
点击字母跳转不到位的问题:在<u-index-list>添加方法select“clickSelect“ 锚点要加id,用对应的字母做为id值, <u-index-anchor :id"key" :index"key"/> <template><view><view class&qu…...

安全模型中的4个P
引言:在安全模型中,经常会碰到PDR,PPDR,IPDRR,CARTA-PPDR等模型,其中的P,是predict?是prevent?还是protect?还是policy呢? 一、4P字典意思解释 1、predict&a…...
网站优化搜索引擎与关键词
网站优化搜索引擎与关键词 人们不应该高估搜索引擎的智商。这不利于seo的研究,事实上,搜索引擎是非常愚蠢的,让我们举一个非常简单的例子,你在搜索引擎中输入“教师”这个词,搜索引擎就会给出一个准确的搜索列表。我们…...

aws-msk-托管kafka集群的简单使用(VPC内部访问:无验证和SASL认证)
1.使用控制台创建即可 根据实例类型创建需要至少15分以上,可以提前创建好ec2实例和Secrets Manager,一会会使用到 2. 创建Secrets Manager (使用无认证时请跳过) 官方文档:https://docs.aws.amazon.com/zh_cn/msk/latest/deve…...

Unity UGUI(二)核心组件
Unity Canvas相关知识学习 文章目录 Unity Canvas相关知识学习1. Canvas:1.1 Render Mode1.2 多个Canvas的显示顺序 2.Canvas Scaler:屏幕分辨率自适应2.1 UI Scale Mode 3. EventSystem4. Standalone Input Module5. Graphic Raycaster:图形…...
代码随想录二刷第二天(Python)
27. 移除元素 题目链接:https://leetcode.cn/problems/remove-element/ 题目描述:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必…...

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类与抽象类
作者主页:paper jie_的博客 本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文录入于《JAVASE语法系列》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和…...

【设计模式】二、UML 类图概述
文章目录 常见含义含义依赖关系(Dependence)泛化关系(Generalization)实现关系(Implementation)关联关系(Association)聚合关系(Aggregation)组合关系&#x…...

百望云亮相服贸会 重磅发布业财税融Copilot
小望小望,我要一杯拿铁! 好的,已下单成功,请问要开具发票嘛? 在获得确认的指令后, 百小望AI智能助手 按用户要求成功开具了一张电子发票! 这是2023年服贸会国家会议中心成果发布现场&#x…...
vue 项目代码混淆配置(自定义插件适用)带配置项注释
文章目录 vue 项目代码混淆配置(自定义插件适用)带配置项注释一、概要二、混淆步骤1. 引入混淆插件2. 添加混淆配置3. 执行代码混淆 vue 项目代码混淆配置(自定义插件适用)带配置项注释 一、概要 本文章适用 vue-cli3/webpack4 …...

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

Java(三)逻辑控制(if....else,循环语句)与方法
逻辑控制(if....else,循环语句)与方法 四、逻辑控制1.if...else(常用)1.1表达格式(三种) 2.switch...case(用的少)2.1表达式 3.while(常用)3.1语法格式3.2关键字beak:3.3关键字 continue: 4.for…...
通过API接口实现数据实时更新的方案(InsCode AI 创作助手)
要实现实时数据更新,需要采用轮询或者长连接两种方式。 1. 轮询方式 轮询方式指的是客户端定时向服务器请求数据的方式,通过一定的时间间隔去请求最新数据。具体的实现方法包括: 客户端定时向服务器发送请求,获取最新数据&…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...