gin 数据库操作

1.数据库初始化

上一节讲了模型的定义,但是没有讲数据库的操作,数据库的连接,没办法看出效果,这一节开始前先对数据库进行初始化。

  • 定义数据库配置信息

    conf/database.ini

[mysql]
host=127.0.0.1
port=3306
database=test
username=root
password=root
  • 定义数据库配置文件

    pkg/config/database.go

package config

import (
	"cn.sockstack/gin_demo/pkg/helper"
	"gopkg.in/ini.v1"
)

var Mysql *mysql

type mysql struct {
	Host string `ini:"host"`
	Port int `ini:"port"`
	Database string `ini:"database"`
	Username string `ini:"username"`
	Password string `ini:"password"`

	source *ini.File
}

func (s *mysql) Load(path string) *mysql {
	var err error
	//判断配置文件是否存在
	exists, err := helper.PathExists(path)
	if !exists {
		return s
	}
	s.source, err = ini.Load(path)
	if err != nil {
		panic(err)
	}
	return s
}

func (s *mysql)Init() *mysql {
	//判断配置是否加载成功
	if s.source == nil {
		return s
	}
    
	//这里直接把配置映射到结构体
	err := s.source.Section("mysql").MapTo(s)
	if err != nil {
		panic(err)
	}
	return s
}
  • 测试配置

    pkg/config/database_test.go

package config

import (
	"fmt"
	"testing"
)

func TestMysql(t *testing.T) {
	Mysql = (&mysql{}).Load("../../conf/database.ini").Init()
	fmt.Println(Mysql)
	if Mysql == nil {
		t.Fail()
	}
}

测试结果

=== RUN   TestMysql
&{127.0.0.1 3306 test root root 0xc000116000}
--- PASS: TestMysql (0.00s)
PASS
  • 初始化数据库

models/init.go

package models

import (
	"cn.sockstack/gin_demo/pkg/config"
	"fmt"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

var (
	DB *gorm.DB
	err error
)

func Init() {
	DB, err = gorm.Open(
		"mysql",
		fmt.Sprintf(
			"%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local",
			config.Mysql.Username,
			config.Mysql.Password,
			config.Mysql.Host,
			config.Mysql.Port,
			config.Mysql.Database,
		),
	)
	if err != nil {
		panic(err)
	}
    
	//设置连接池
	DB.DB().SetMaxIdleConns(10)
	DB.DB().SetMaxOpenConns(100)

	//数据库迁移
	migrate()
}

func migrate()  {
	DB.AutoMigrate(&User{})
}

func Close()  {
	defer DB.Close()
}

2.模型定义

首先定义一个模型,方便我们后续对模型进行操作。

​ models/user.go

package models

type User struct {
    ID        uint `gorm:"primary_key"`
    Username string
    Password string
}

模型简单定义了两个字段,后面我们基于这个模型进行数据操作。

3.模型的增删改查

repositories/user_repository.go

package user

import (
	"cn.sockstack/gin_demo/dto"
	"cn.sockstack/gin_demo/models"
)

//CreateUser 创建用户
func CreateUser(dto dto.UserDto) error {
	user := models.User{}
	user.Username = dto.Username
	user.Password = dto.Password

	err := models.DB.Create(&user).Error

	return err
}

//GetUserByUsername 通过用户名查询用户
func GetUserByUsername(username string) models.User {
	user := models.User{}
	models.DB.Find(&user, models.DB.Where("username = ?",username))

	return user
}

//UpdateUser 更新用户信息
func UpdateUser(userDto dto.UserDto) error {
	user := models.User{}
	if userDto.Username != "" {
		user.Username = userDto.Username
	}

	if userDto.Password != "" {
		user.Password = userDto.Password
	}

	err := models.DB.Model(&user).Update(&user).Error

	return err
}

//DeleteUserById 通过Id删除用户
func DeleteUserById(id uint) error {
	err := models.DB.Delete(&models.User{ID: id}).Error
	return err
}

测试数据库操作:

repositories/user_repository_test.go

package user

import (
	"cn.sockstack/gin_demo/dto"
	"cn.sockstack/gin_demo/models"
	"cn.sockstack/gin_demo/pkg/config"
	"fmt"
	"testing"
)

const (
	username = "sockstack"
	password = "123456"
	update_username = "sockstack_update"
)

func init() {
	config.Mysql.Load("../../conf/database.ini").Init()
	models.Init()
}

func TestCreateUser(t *testing.T) {
	userDto := dto.UserDto{
		Username: username,
		Password: password,
	}
	err := CreateUser(userDto)
	if err != nil {
		t.Fail()
	}
}

func TestGetUserByUsername(t *testing.T) {
	user := GetUserByUsername(username)
	if user.Username == "" {
		t.Fail()
	}
	fmt.Println(user)
}

func TestUpdateUser(t *testing.T) {
	user := GetUserByUsername(username)
	userDto := dto.UserDto{
		ID:       user.ID,
		Username: update_username,
		Password: user.Password,
	}
	err := UpdateUser(userDto)
	if err != nil {
		fmt.Println(err.Error())
		t.Fail()
	}
}

func TestDeleteUserById(t *testing.T) {
	user := GetUserByUsername(username)
	err := DeleteUserById(user.ID)
	if err != nil {
		t.Fail()
	}
}

测试结果:

=== RUN   TestCreateUser
--- PASS: TestCreateUser (0.00s)
=== RUN   TestGetUserByUsername
{2 sockstack 123456}
--- PASS: TestGetUserByUsername (0.00s)
=== RUN   TestUpdateUser
--- PASS: TestUpdateUser (0.00s)
=== RUN   TestDeleteUserById
--- PASS: TestDeleteUserById (0.01s)
PASS

4.小结

这里只是简单的介绍gorm的增删改查,gorm还有许多高级的功能没有介绍到,感兴趣的可以去看文档了解。虽然这里没有把数据操作整合到service层,但是整合数据操作并不难,这里就不展开了,后面的实例实战再介绍。