初始化一个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. 轮询方式 轮询方式指的是客户端定时向服务器请求数据的方式,通过一定的时间间隔去请求最新数据。具体的实现方法包括: 客户端定时向服务器发送请求,获取最新数据&…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...