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
足够简单,性能也非常不错
借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范
因笔者之前做java开发,习惯使用mvc架构,因此,在转型为golang开发的使用中沿用了这种开发模式。
目前就只添加这些文件夹,后续有其它需求可根据个人自行添加。
代码如下(示例):
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()直接调用操作数据库。
代码如下(示例):
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)
}
代码如下(示例):
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, "成功")
}
代码如下(示例):
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)
}
代码如下(示例):
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
}
代码如下(示例):
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"
启动项目后,开始使用postman进行测试。
查看数据库中数据
这里只是笔者经过自己的理解和测试,而构建出的一个简单的层次,后续也会继续学习进行改进,也希望有错误的地方能有各位大佬指正,有宝贵的意见也希望您能提出,共同学习。