Gin框架结合gorm使用

2023-11-07

Gin框架结合Gorm使用


目录

Gin框架结合Gorm使用

前言

一、介绍

二、使用步骤

1.创建项目

2.开始main.go

3.router的初始化

4.controller的初始化

5.services的初始化

6.models的初始化

7.my.init的初始化

8.开始测试

总结


前言

笔者为golang语言的初学者,之前一直是使用beego框架和框架中自带的orm,使用这一套框架做项目也有大半年了,总的来说对于初学者来讲入门也是可以的。在使用了一段时间当中,渐渐的发现beego框架中有很多自带的插件根本用不上,也许这就是大家说的框架重的原因。于是,最近开始学习另一个轻量级的框架 gin ,并结合 gorm 用来操作数据库使用,实测gin框架下载的插件库比beego框架少了一半。


一、介绍

  • Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点

  • 对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错

  • 借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范

二、使用步骤

1.创建项目

因笔者之前做java开发,习惯使用mvc架构,因此,在转型为golang开发的使用中沿用了这种开发模式。

  • main.go 文件为整个项目的入口,gin框架的初始化和启动等我都放在这了
  • app/consts:该层存放常量的定义文件
  • app/controllers:该层存放控制层的文件
  • app/model:该层存放实体类文件,以及数据库的初始化文件,我将所有对数据库的操作方法都放在其独自的实体类中
  • app/router:该层存放所有的路由,经过路由可以跳转到controller层
  • app/services:该层为业务层(接口类),所有的业务逻辑都写在这一层类中
  • app/utils:该层为自己写的工具类方法
  • configure:配置文件放在这里
  • database:sqlite3的数据库

目前就只添加这些文件夹,后续有其它需求可根据个人自行添加。

 

2.开始main.go

代码如下(示例):

package main

import (
	"awesomeProject/app/controllers"
	"awesomeProject/app/models"
	"awesomeProject/app/router"
	"github.com/gin-gonic/gin"
	"gopkg.in/ini.v1"
	"log"
)

func main() {
	r := gin.Default()

	// 读取配置文件
	conf, err := ini.Load("./config/my.ini")
	if err != nil {
		log.Fatal("配置文件读取失败, err = ", err)
	}

	// 初始化路由路径
	router.InitRouter(r)

	// 初始化数据库
	db := models.InitDB(conf)
	defer db.Close()

	// 项目的启动端口在这儿设置,也可以从配置文件中读取到这儿
	port := ":" + conf.Section("").Key("httpport").String()
	if err := r.Run(port); err != nil {
		log.Fatal("程序启动失败:", err)
	}
}

可能会有朋友会有这么一个疑问,为什么我没有把各种初始化的类文件放在同一个文件夹下进行管理,原因是我在另创的一个文件夹下完成初始化数据库的并返回个一个db,在model包中的实体类调用不到这个包中的db这个库,当通过其它的方式调用尝试

后反而出现一个循环导包的错误,因此在目前我没找到其它方法的情况下我将初始化数据的方法类放在model中,这样model中的实体类可直接调用。(后续找到方法后再来改进,也希望大佬们提出您的宝贵意见)

beego会有所不同,只要在一开始进行了数据库的初始化,那么在代码的其它地方就可以通过orm.NewOrm()直接调用操作数据库。

 

3.router的初始化

代码如下(示例):

package router

import (
	"github.com/gin-gonic/gin"
)

// 将每个模块的路由路径进行拆分,在这儿统一初始化,gin框架的路由启动
func InitRouter(r *gin.Engine) {
	// 用户表的路由
	UserRouter(r)
	// xxx的路由

}
package router

import (
	"awesomeProject/app/controllers"
	"github.com/gin-gonic/gin"
)

func UserRouter(r *gin.Engine)  {
    // 因为我在controller将每个controller类实现了初始化,完成多态的实现,这样即使多个不同类中的方法名一样也没有问题,详情见controller层代码
	r.GET("/prod", controllers.UserContro.FindAllUser)

	r.POST("/prod", controllers.UserContro.SaveUser)
}

4.controller的初始化

代码如下(示例):

package controllers

var (
    // 所有的controller类声明都在这儿
	UserContro = &UserController{}
)
package controllers

import (
	"awesomeProject/app/consts"
	"awesomeProject/app/models"
	"awesomeProject/app/services"
	"github.com/gin-gonic/gin"
	"log"
)

type UserController struct {
}

func (t *UserController) FindAllUser(c *gin.Context) {

}

func (t *UserController) SaveUser(c *gin.Context) {
	var user models.User

    // 将前端穿过来的json数据绑定存储在这个实体类中,BindJSON()也能使用
	if err := c.ShouldBindJSON(&user); err != nil {
		log.Fatal(consts.BIND_PARAM_ERROR)
	}

    // 调用业务层的方法
	if err := services.UserService.SaveUser(&user);err != nil {
		c.JSON(400, err)
	}
	c.JSON(200, "成功")
}

5.services的初始化

代码如下(示例):

package services

var (
    // 所有的业务类都在这儿声明
	UserService = &UserMgr{}
)
package services

import (
	"awesomeProject/app/models"
)

type  UserServices interface {
	// 查询所有用户信息
	FindAllUser()
	// 添加用户信息
	SaveUser(user *models.User) error
}

type UserMgr struct {
}

func (p *UserMgr) FindAllUser() {
}

func (p *UserMgr) SaveUser(user *models.User) error {
	return models.AddUser(user)
}

6.models的初始化

代码如下(示例):

package models

import (
	"awesomeProject/app/consts"
	_ "github.com/go-sql-driver/mysql"
	"github.com/gogf/gf/os/gfile"
	"github.com/jinzhu/gorm"
	_ "github.com/mattn/go-sqlite3"
	"gopkg.in/ini.v1"
	"log"
	"os"
	"path"
)

// 在其它model的实体类中可直接调用
var db *gorm.DB

func InitDB(conf *ini.File) *gorm.DB {
	var err error

	// 数据库的类型
	dbType := conf.Section("").Key("db_type").String()

	// Mysql配置信息
	mysqlName := conf.Section("mysql").Key("db_name").String()
	mysqlUser := conf.Section("mysql").Key("db_user").String()
	mysqlPwd := conf.Section("mysql").Key("db_pwd").String()
	mysqlHost := conf.Section("mysql").Key("db_host").String()
	mysqlPort := conf.Section("mysql").Key("db_port").String()
	mysqlCharset := conf.Section("mysql").Key("db_charset").String()

	// sqlite3配置信息
	sqliteName := conf.Section("sqlite3").Key("db_name").String()

	var dataSource string
	switch dbType {
	case "mysql":
		dataSource = mysqlUser + ":" + mysqlPwd + "@tcp(" + mysqlHost + ":" +
			mysqlPort + ")/" + mysqlName + "?charset=" + mysqlCharset

		db, err = gorm.Open(dbType, dataSource)
	case "sqlite3":
		dataSource = "database" + string(os.PathSeparator) + sqliteName
		if !gfile.Exists(dataSource) {
			os.MkdirAll(path.Dir(dataSource), os.ModePerm)
			os.Create(dataSource)
		}
		db, err = gorm.Open(dbType, dataSource)
	}

	if err != nil {
		db.Close()
		log.Fatal(consts.CONN_DATABASE_ERROR, err)
	}

	// 设置连接池,空闲连接
	db.DB().SetMaxIdleConns(50)
	// 打开链接
	db.DB().SetMaxOpenConns(100)

	// 表明禁用后缀加s
	db.SingularTable(true)

	return db
}
package models

import (
	"awesomeProject/app/consts"
	"log"
)

type User struct {
	ID       int    `gorm:"column:id; parimary_key", json:"id"`
	Name     string `gorm:"column:name" json:"name"`         // 用户名
	Accounts string `gorm:"column:accounts" json:"accounts"` // 帐号
	PassWord string `gorm:"column:password" json:"password"` // 密码
}

func FindAllUser()  {

}

func AddUser(user *User) error {
	if err := db.Create(user).Error; err != nil {
		log.Fatal(err)
		return consts.ADD_DATA_ERROR
	}
	return nil
}

7.my.init的初始化

代码如下(示例):

appname = "gin框架测试"

httpport = 9898

#开启JSON请求
copyrequestbody = true


#数据库类型:mysql/sqlite3
db_type = "mysql"

[mysql]
db_alias = "default"
db_name = "gin_test"
db_user = "root"
db_pwd = "root"
db_host = "127.0.0.1"
db_port = 3306
db_charset = "utf8"

[sqlite3]
db_alias = "default"
db_name = "gin_test.db"

8.开始测试

启动项目后,开始使用postman进行测试。

查看数据库中数据

 


总结

这里只是笔者经过自己的理解和测试,而构建出的一个简单的层次,后续也会继续学习进行改进,也希望有错误的地方能有各位大佬指正,有宝贵的意见也希望您能提出,共同学习。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Gin框架结合gorm使用 的相关文章

随机推荐

  • 黑盒测试中的等价类和边界值

    黑盒测试时基于程序规格说明书 找出程序不符合格则说明书的地方 也就是我们常说的点点点 在进行黑盒测试时 我们可以利用一下几种方法来写出测试用例 尽量用科学的方法来找出更多的缺陷 等价类划分 等价类划分是一种重要的 常用的黑盒测试方法 不需要
  • js打开新的窗口window_前端必备基础知识:window.location 详解

    作者简介 李中凯 八年多工作经验 前端负责人 擅长JavaScript Vue 掘金文章专栏 KaysonLi 的个人主页 专栏 掘金 前端开发人员对 window location对象应该不陌生 通过它不但可以获取当前页面的地址信息 还可
  • android mtk6732 camera otp 加载流程

    在android的hal层获取属性节点信息值 Get Property char value PROPERTY VALUE MAX 0 property get camcaldrv log value 0 MINT32 dumpEnable
  • Java垃圾回收【GC】详解

    什么是垃圾 垃圾是内存中没有任何引用指向它 并且没有引用的对象无法使用 所以就可以认为这个对象是垃圾 需要被回收释放其占用的内存空间 垃圾定位 1 引用计数法 RefrenceCount 堆中每个对象实例都有一个引用计数 每当有一个引用指向
  • 六轴机器人轨迹规划(直线轨迹规划,弧线轨迹规划)——C#实现+ABB为例(规划直接下发离线程序运动)

    机器人直线插补算法 弧线插补算法 离线编程转换 空间直线插补规划 空间弧线插补规划 离线编程 ABB二次开发 六轴机器人控制 C 一 通过对空间点的插补 形成空间点轨迹 1 插补算法原理简述 1 直线插补时 指定起止坐标与速度 2 确定要插
  • 安装多版本java

    系统变量 JAVA HOME JAVA8 HOME JAVA8 HOME C java jdk8 JAVA11 HOME C java jdk11 JAVA17 HOME C java jdk17 Path 新增 移到最上面 重新打开Pat
  • 像素和毫米怎么换算

    像素和毫米怎么换算 像素和毫米是不能直接转换的 只有在分辩率 dpi 下才能进行转换 因此 像素与毫米的转换 需要知道参数 DPI 每英寸多少点 象素数 DPI 英寸数 英寸数 25 4 毫米数 对于显示设备 不管是打印机还是屏幕 都有一种
  • Linux中如何使用命令修改文件所属用户组?

    先来了解一下文件属性 在shell环境里输入 ls l 可以查看当前目录文件 如 drwxr xr x 2 nsf users 1024 12 10 17 37 下载文件备份 分别对应的是 文件属性 连接数 文件拥有者 所属群组 文件大小
  • Docker部署Nginx(window)

    安装Nginx docker pull nginx 运行Nginx docker run p 80 80 name nginx d nginx 进入Nginx docker exec it nginx bash 配置Nginx cd etc
  • 手机有什么副业做?用手机能做啥副业?

    随着手机移动互联网的越来越流行 用户越来越多 手机赚钱也成为现在的一大优势 很多企业开始开发手机赚钱的软件和应用 当你还用手机娱乐的时候 别人已经用手机赚钱了 你知道手机有什么副业可以做吗 1 苹果APP试玩 就是用苹果手机下载一个试玩AP
  • libcore.io.ErrnoException: open failed: EINVAL (Invalid argument)

    出现异常 04 16 17 58 52 714 W System err 23703 Caused by libcore io ErrnoException open failed EINVAL Invalid argument 04 16
  • 什么是游戏测试?

    在很多外行甚至行内非测试岗位人的眼里 游戏测试是很没有技术含量的活儿 门槛低 不过就是不断玩游戏 反馈问题 纯粹是体力活 如果真是这样 那我们到网吧随便拉几个玩家都可以做 早期的一些游戏测试确实是这样做的 但如今这样做已经不可能保证游戏的品
  • 算法应该怎样学习

    算法背景 了解该算法的背景知识 该算法要解决的问题 算法流程 了解该算法的流程 包括输入和输出 算法核心部分的具体实现 时间复杂度 了解该算法的时间复杂度 说明算法的执行效率 空间复杂度 了解该算法的空间复杂度 说明算法所需的存储空间 优点
  • MySQL提权篇

    一 Mysql提权必备条件 1 服务器安装Mysql数据库 利用Mysql提权的前提就是服务器安装了mysql数据库 且mysql的服务没有降权 Mysql数据库默认安装是以系统权限继承的 并且需要获取Mysql root账号密码 2 判断
  • 14:00面试,14:06就出来了,问的问题有点变态。。。

    从小厂出来 没想到在另一家公司又寄了 到这家公司开始上班 加班是每天必不可少的 看在钱给的比较多的份上 就不太计较了 没想到5月一纸通知 所有人不准加班 加班费不仅没有了 薪资还要降40 这下搞的饭都吃不起了 还在有个朋友内推我去了一家互联
  • 【生成式网络】入门篇(二):GAN的 代码和结果记录

    GAN非常经典 我就不介绍具体原理了 直接上代码 感兴趣的可以阅读 里面有更多变体 https github com rasbt deeplearning models tree master pytorch ipynb gan GAN 在
  • Kafka消费者Relance机制和分区机制

    kafka消费者Relance rebalance就是说如果消费组里的消费者数量有变化或消费的分区数有变化 kafka会重新分配消费者消费分区的关系 比如consumer group中某个消费者挂了 此时会自动把分配给他的分区交给其他的消费
  • MySQL如何删除#sql开头的临时表

    1 现象 巡检时发现服务器磁盘空间不足 通过查看大文件进行筛选是发现有几个 sql开头的文件 且存在超过100G及10G以上的文件 2 原因 如果MySQL在一个 ALTER TABLE操作 ALGORITHM INPLACE 的中间退出
  • MMdetection系列之Config配置文件(V3更新后)

    1 了解配置 MMDetection 和其他 OpenMMLab 存储库使用MMEngine 的配置系统 模块化 继承性设计 便于进行各种实验 2 配置文件的查看 在配置系统中采用模块化和继承性设计 便于进行各种实验 如果你想查看配置文件
  • Gin框架结合gorm使用

    Gin框架结合Gorm使用 目录 Gin框架结合Gorm使用 前言 一 介绍 二 使用步骤 1 创建项目 2 开始main go 3 router的初始化 4 controller的初始化 5 services的初始化 6 models的初