Gin框架结合gorm使用

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开发的使用中沿用了这种开发模式。

Gin框架结合gorm使用_第1张图片

  • 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进行测试。

Gin框架结合gorm使用_第2张图片

查看数据库中数据

Gin框架结合gorm使用_第3张图片

 


总结

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

你可能感兴趣的:(gin,go)