Перейти к веб-программированию — применение ORM

Go

Go Web 编程--应用 ORM

Предыдущая статьяВ среде разработки, которую мы используем, мы добавилиMySQLконтейнер, затем вводит использованиеdatabase/sqlСтандартная библиотека в сочетании с пакетом драйверов базы данных для выполнения операций с базой данных. Но это относительно низкоуровневые пакеты. Реальная разработка часто использует некоторые пакеты, инкапсулированные на его основе.ORMбиблиотека.ORMЗапрос проще в использовании, а синтаксис более выразительный. В этой статье мы в основном исследуем следующее содержание.

  • gormосновное использование
  • как управлятьORMиспользование
  • Как разумно спланировать структуру каталогов проекта

Установить горм-пакет

gormотличный, удобный для разработчиковGolang ORMБиблиотеки, которые поддерживают функции, включают:

  • Полнофункциональный ORM (почти все функции)
  • Ассоциации моделей (один к одному, один ко многим, один ко многим (обратные), многие ко многим, полиморфные ассоциации)
  • Хуки (до/после создания/сохранения/обновления/удаления/поиска)
  • Предварительная загрузка
  • дела
  • составной первичный ключ
  • конструктор SQL
  • Автоматическая миграция
  • журнал

Установите с помощью следующей команды:

go get -u github.com/jinzhu/gorm

Добавить горм в проект

Планирование структуры каталогов модели данных

Мы создаем следующий каталог в корневом каталоге проекта:

http_demo
|
└───model
│   └───dao
│   │   init.go
│   └───────table
│           │   user.go

Пакеты в Go организованы в виде каталогов, поэтомуmodelВсе модели данных хранятся в пакете,daoПредставляет объект доступа к данным, в котором хранится база данныхCRUDинкапсуляция метода, гдеinit.goхранитьdaoФункция инициализации пакета в основном используется для подключения к базе данных после загрузки пакета.tableОпределение модели, соответствующее таблице данных, помещается в пакет (перед использованием ORM модель должна быть определена в соответствии с таблицей в базе данных).В примере мы определимUserмодель наuser.goв файле.

После планирования каталога вы можете написать соответствующий код в каждой части.Во-первых, давайте посмотрим на использованиеgormПодключиться к базе данных.

Подключиться к базе данных

мы вdaoупаковкаinit.goДобавьте логику инициализации пакета для подключения к базе данных, и функция инициализации будет вdaoвыполняется при первом импорте пакета из-заgormПример подключения документа к базе данных слишком прост и имеет мало справочной ценности, поэтому мы делаем простую инкапсуляцию в соответствии с потребностями проекта.init.goКод в следующем:

package dao

import (
   _ "github.com/go-sql-driver/mysql"
   "github.com/jinzhu/gorm"
   "time"
)

var _DB *gorm.DB

func DB() *gorm.DB {
   return _DB
}

func init() {
   _DB = initDB()
}

func initDB() *gorm.DB {
   // In our docker dev environment use
   // db, err := gorm.Open("mysql", "go_web:go_web@tcp(database:3306)/go_web?charset=utf8&parseTime=True&loc=Local")
   db, err := gorm.Open("mysql", "go_web:go_web@tcp(localhost:33063)/go_web?charset=utf8&parseTime=True&loc=Local")
   if err != nil {
      panic(err)
   }
   db.DB().SetMaxOpenConns(100)
   db.DB().SetMaxIdleConns(10)
   db.DB().SetConnMaxLifetime(time.Second * 300)
   if err = db.DB().Ping(); err != nil {
      panic(err)
   }
   return db
}

Код очень прост, когда вы практикуете его в соответствии со своими собственнымиMySQLКонфигурация изменяет конфигурацию в коде. Дело в том, что если вы используетеDockerсреде, при подключении к базе данныхhostизменить наdatabase:3306, потому что я помещаю в среду контейнераMySQLИмя службы контейнера определяется какdatabase, БегGoизappКонтейнерам нужны имена служб для доступа к другим контейнерам в сети контейнеров. Пожалуйста, ознакомьтесь с подробной конфигурацией среды контейнера.Перейти к веб-программированию — База данных приложенийописание в .

Определить модель

Прежде чем использовать модель для доступа к таблице базы данных, нам необходимо определить соответствующую модель. В нашем примере теперь только одинusersстол, следующий мы вtableпакет добавленusersМодель таблицы определена и помещена вuser.goв файле.

package table

import "time"

type User struct {
   Id        int64     `gorm:"column:id;primary_key"`
   UserName  string    `gorm:"column:username"`
   Secret    string    `gorm:"column:secret;type:varchar(1000)"`
   CreatedAt time.Time `gorm:"column:created_at"`
   UpdatedAt time.Time `gorm:"column:updated_at"`
}

// TableName sets the insert table name for this struct type
func (m *User) TableName() string {
   return "users"
}

Модель CRUD

Что касается CRUD модели, рекомендуется, чтобы CRUD отдельной моделиCRUDставитьdaoВ одном файле пакета это удобно для дальнейшего управления кодом. Позвольте мне сказать немного больше здесь, рекомендуется не использовать его напрямуюcontrollerили позвоните по телефонуhandlerпакет прямого доступаdaoпакет, но добавьте слой посерединеlogicpackage, поместите логику в этот слой. Это полезно для управления кодом и повторного использования.

Поскольку в базе данных существует множество операций CRUD, цель этой статьи — помочь вам быстро приступить к работе.gormПоэтому я просто поставил простой CRUD для демонстрации. Следуйте инструкциям здесь, чтобы импортироватьgormПосле использования других операций с базой данных перейдите непосредственно к официальной документации, чтобы проверить ее.

существуетdaoновый в упаковкеuser.goиспользуется для храненияUserКак работает модель.

package dao

import "example.com/http_demo/model/dao/table"

func CreateUser(user *table.User) (err error) {
	err = DB().Create(user).Error

	return
}

func GetUserById(userId int64) (user *table.User, err error) {
	user = new(table.User)
	err = DB().Where("id = ?", userId).First(user).Error

	return
}

func GetAllUser() (users []*table.User, err error) {
	err = DB().Find(&users).Error
	return
}

func UpdateUserNameById(userName string, userId int64) (err error) {
	user := new(table.User)
	err = DB().Where("id = ?", userId).First(user).Error
	if err != nil {
		return
	}

	user.UserName = userName
	err = DB().Save(user).Error

	return
}

func DeleteUserById(userId int64) (err error) {
	user := new(table.User)
	err = DB().Where("id = ?", userId).First(user).Error
	if err != nil {
		return
	}
	err = DB().Delete(user).Error

	return
}

Проверить метод ORM

После вышеперечисленных шагов мы можем использовать его в проектеgormдоступ к базе данных, благодаря нашему проектуmain goroutineвбегаетhttpсервис, поэтому мы используем тестовый пример для вышеуказанногоdaoТестируются несколько методов, определенных в пакете.

Из соображений экономии места я опубликую только одинGetAllUsersТестовый пример для метода:

func TestGetAllUser(t *testing.T) {
	tests := []struct {
		name      string
		wantErr   bool
	}{
		{
			name: "test",
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			gotUsers, err := GetAllUser()
			if (err != nil) != tt.wantErr {
				t.Errorf("GetAllUser() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			for _, user := range gotUsers {
				log.Info("user: %v", user)
			}

		})
	}
}

После запуска теста вы можете увидеть результаты:

INFO user: &{1   2020-02-15 14:14:46 +0800 CST 2020-02-15 06:44:17 +0800 CST}
--- PASS: TestGetAllUsers (0.00s)
    --- PASS: TestGetAllUsers/test (0.00s)
PASS

Process finished with exit code 0

Обратите внимание на публичный ответ в конце статьиgohttp05Полный код тестового примера можно получить, рекомендуетсяCRUDВсе тест-кейсы должны быть написаны для самотестирования с использованиемGoLandЛегко создавать тестовые функции и запускать тесты.

Перепланировка каталога проекта

представлятьORMПосле этого в нашем проекте есть еще коды, и все они размещены в корневом каталоге.mainПакет немного беспорядочный, поэтому мы просто делим каталог проекта в соответствии с функциями и обязанностями каждой части.Структура разделенных каталогов выглядит следующим образом:

http_demo
|
└───handler//route handler
|
└───logic//business logic
|
└───middleware
│
└───model
│   └───dao
│   │   init.go
│   └───table
│       │   user.go
└───router// router
|
|   main.go

Я чувствую, что сегодня еще много контента, особенно для тех, кто только начинает.GoСтуденты должны загрузить сегодняшний код и попрактиковаться, чтобы освоить его.gormПредусмотрено еще много функций, и каждая функция объясняется в официальной документации, поэтому мы не будем вводить здесь слишком много. Цель этой статьи в основном состоит в том, чтобы позволить всем быстро приступить к работе и в то же времяORMСоответствующие процессы управления кодом и инициализации стандартизированы, и эти организационные методы могут быть полностью применены к проектам производственного уровня.

Обратите внимание на публичный ответ в конце статьиgohttp05Получите полный исходный код в статье.Если вам понравилась моя статья, пожалуйста, поставьте лайк и добавьте ее в закладки.

Предыдущий отзыв

Глубокое погружение в написание HTTP-серверов в Go

Маршрутизация веб-сервера

Быстро создайте среду разработки Go с помощью Docker

Научитесь писать промежуточное программное обеспечение для веб-приложений на Go за десять минут

Перейти к веб-программированию — База данных приложений

Go Web编程--应用ORM