## 1.數據庫初始化
上一節講了模型的定義,但是沒有講數據庫的操作,數據庫的連接,沒辦法看出效果,這一節開始前先對數據庫進行初始化。
- 定義數據庫配置信息
conf/database.ini
```ini
[mysql]
host=127.0.0.1
port=3306
database=test
username=root
password=root
```
- 定義數據庫配置文件
pkg/config/database.go
```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
```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()
}
}
```
測試結果
```shell
=== RUN TestMysql
&{127.0.0.1 3306 test root root 0xc000116000}
--- PASS: TestMysql (0.00s)
PASS
```
- 初始化 `Mysql` 配置
pkg/config/init.go
``` golang
package config
func init() {
...
// 添加 Mysql 配置初始化
Mysql = (&mysql{}).Load("conf/database.ini").Init()
...
}
```
- 初始化數據庫
models/init.go
```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
```go
package models
type User struct {
ID uint `gorm:"primary_key"`
Username string
Password string
}
```
模型簡單定義了兩個字段,后面我們基于這個模型進行數據操作。
## 3.模型的增刪改查
repositories/user_repository.go
```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
```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()
}
}
```
測試結果:
```shell
=== 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層,但是整合數據操作并不難,這里就不展開了,后面的實例實戰再介紹。
> 更多內容請關注我的博客[SOCKSTACk](https://www.sockstack.cn)