初始化一个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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/73921.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Shell编程中Shift的用法

Shell编程中Shift的用法 位置参数可以用shift命令左移。比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1,$2, 3 , 3, 3,-丢弃,$ 0 不移动。不带参数的shift命令相当于shift 1。 非常有用的 Unix 命令:shift。我们知道&a…

【云原生】Kubeadmin部署Kubernetes集群

目录 ​编辑 一、环境准备 1.2调整内核参数 二、所有节点部署docker 三、所有节点安装kubeadm,kubelet和kubectl 3.1定义kubernetes源 3.2开机自启kubelet 四、部署K8S集群 4.1查看初始化需要的镜像 4.2在 master 节点上传 v1.20.11.zip 压缩包至 /opt 目录…

【Redis】Redis如何保证和MySQL数据库的数据一致性(带你一文了解)

目录 方法一:采用事务 方法二:订阅Mysql的Binlog文件(可借助Canal来进行) 方法三:基于消息队列的同步方案 方法一:采用事务 MySQL 支持事务,在需要保证一致性的操作中使用事务。通过将 Redis 和 MySQL 操作放在同一个…

np.concatenate

np.concatenate函数是numpy库中用来连接两个或多个数组的函数。这里有一个简单的例子演示np.concatenate的用法: ```python import numpy as np # 创建两个一维数组 array1 = np.array([1, 2, 3]) array2 = np.array([4, 5, 6]) # 使用np.concatenate进行连接 result = np.…

【多线程】线程安全 问题

线程安全 问题 一. 线程不安全的典型例子二. 线程安全的概念三. 线程不安全的原因1. 线程调度的抢占式执行2. 修改共享数据3. 原子性4. 内存可见性5. 指令重排序 一. 线程不安全的典型例子 class ThreadDemo {static class Counter {public int count 0;void increase() {cou…

蓝桥杯官网练习题(兰顿蚂蚁)

题目描述 兰顿蚂蚁,是于 1986 年,由克里斯兰顿提出来的,属于细胞自动机的一种。 平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只"蚂蚁"。 蚂蚁的头部朝向为:上下左右其中一方。 蚂蚁的移动规则十分…

Matlab之DICOM(数字图像和通信医学)格式图像数据读取函数dicomread

一、DICOM是什么? DICOM是数字图像和通信医学格式的图像数据,在MATLAB中,可以使用dicomread函数读取DICOM格式的图像数据。 二、dicomread函数 使用方法如下: imageData dicomread(filename);其中,filename表示DI…

Axure RP美容美妆医美行业上门服务交互原型图模板源文件

Axure RP美容美妆医美行业上门服务交互原型图模板源文件,原型内容属于电商APP,区别于一般电商,它的内容是‘美容美发美妆等’上门服务等。大致流程是线上买单,线下实体店核销消费。 附上预览演示:axure9.com/mobile/73…

GitHub two-factor authentication

1. 介绍 登录 GitHub 官网,会提示要开启双因子认证。 但推荐的 APP 都是国外了,国内用不了。 可以使用 “腾讯身份验证器” 微信小程序。 2. 操作 开启双因子认证: 打开 “腾讯身份验证器” 微信小程序,扫描 GitHub 那个二维…

Go语言网络编程(socket编程)http编程

1、http编程 1.1.1 web工作流程 Web服务器的工作原理可以简单地归纳为 客户机通过TCP/IP协议建立到服务器的TCP连接 客户端向服务器发送HTTP协议请求包,请求服务器里的资源文档 服务器向客户机发送HTTP协议应答包,如果请求的资源包含有动态语言的内容&…

博客程序系统其它功能扩充

一、注册功能 1、约定前后端接口 2、后端代码编写 WebServlet("/register") public class RegisterServlet extends HttpServlet {Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置…

Python编程练习与解答 练习112:删除异常值

在分析作为科学实验的一部分收集的数据时,在进行其他计算之前,最好先去掉最极端的值。编写一个函数,该函数接受一个值列表和一个非负整数n作为参数。该函数应该创建一个新的列表副本,删除其中n个最大元素和n个最小元素。然后他应该…

LeetCode 3. 无重复字符的最长子串

题目链接 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 题目解析 我们需要找的是含重复元素的最长子串,当然直接暴力求解固然简单。但是可能引发的情况是超时,而且面试官想看到的也不是让你去暴力解决这类问题。因此我们使…

Node.js 使用 officecrypto-tool 读取加密的 Excel (xls, xlsx) 和 Word( docx)文档

Node.js 使用 officecrypto-tool 读取加密的 Excel (xls, xlsx) 和 Word( docx)文档, 还支持 xlsx 和 docx 文件的加密(具体使用看文档)。暂时不支持doc文件的解密 传送门:officecrypto-tool 读取加密的 Excel 示例 一:xlsx-po…

面试求职-面试注意事项

面试技巧和注意事项有哪些? 面试是找工作过程中最重要的一个环节,因为面试成功,你才有可能得到一份工作。求职面试技巧有哪些呢?首先,我们来看看面试注意事项。 企业了解 1、面试前有没有仔细了解过对应企业的情况&#xff0c…

Tomcat安装及使用

这里写目录标题 Tomcat一.java基础1.java历史2.java组成3.实现动态网页功能serveltjsp 4.jdkJDK 和 JRE 关系安装openjdk安装oracle官方JDK 二.tomcat基础功能1.Tomcat介绍2.安装tomcat二进制安装Tomcat 3.配置文件介绍及核心组件配置文件组件 4.状态页5.常见的配置详解6.tomca…

React 学习笔记目录

学习使用的开发工具 编译器 VSCode 开发语言工具 TypeScript /JavaScript 重要程度分类 一般 这个程度的知识点主要是达到熟练掌握即可,不用太深入研究和学习。 重要 这个程度的知识点主要是达到熟练掌握,并且内部的原理切要熟记,因为会关…

strerror函数

目录 strerror 函数介绍&#xff1a; 举例&#xff1a; 使用案例&#xff1a; 优化&#xff1a; perror&#xff1a; strerror 函数介绍&#xff1a; 函数声明&#xff1a; char * strerror ( int errnum );头 文 件&#xff1a;#include <string.h>返 回 值&a…

SpringBoot+MP操作DM8

1. 达梦数据库介绍 达梦数据库管理系统是达梦公司推出的具有完全自主知识产权的国产高性能数据库管理系统&#xff0c;简称DM。当前最新版本是8.0版本&#xff0c;简称DM8。&#xff08;同时也是一款RDBMS&#xff0c;关系型数据库管理系统&#xff0c;和oracle比较像&#xff…

explicit 关键字

c 提供了关键字 explicit &#xff0c;禁止通过构造函数进行的隐式转换。声明为 explicit 的构造函数不能在隐式转换中使用。 [explicit 注意 ] explicit 用于修饰构造函数 , 防止隐式转化。 是针对单参数的构造函数 ( 或者除了第一个参数外其余参数都有默认值的多参构…