Пойди поразмышляй с библиотекой Горм

Я использую пакет gorm ( https://github.com/jinzhu/gorm) в качестве библиотеки базы данных в golang. У меня есть много классов (таблиц базы данных), таких как "Отель" или "Пакет". Дублирование кода не является хорошей практикой программирования. В качестве глупого примера - предположим, я хочу получить первый объект из каждой таблицы. Я могу написать этот метод (GetFirstHotel, GetFirstPackage...) для каждого объекта. Но лучше было бы иметь только один метод GetFirstItemгде я использовал бы первый параметр для создания объекта с тем же классом, что и у параметра, затем передал бы его в gorm, который заполнит его данными из базы данных, а затем вернет его как interface{}, Я пытался использовать отражение для этого, но не получилось, потому что я, наверное, не очень понимаю.

Возможно, я просто не обнаружил какую-то функцию в библиотеке gorm, или я не могу правильно использовать отражающий пакет. Как я должен реализовать GetFirstItem функция. Возможно ли реализовать это, или мне лучше повторить мой код?

package main

import (
    "github.com/jinzhu/gorm"
)

var db gorm.DB

type Hotel struct {
    ID   int64
    Name string
    Lat  float64
    Lon  float64
}

type Package struct {
    ID   int64
    Name string
    Text string
}

func GetFirstHotel() (hotel Hotel) {
    db.First(&hotel)
}

func GetFirstPackage() (pack Package) {
    db.First(&pack)
}

func main() {
    var firstHotel, firstPackage interface{}

    //first method
    firstHotel = GetFirstHotel()
    firstPackage = GetFirstPackage()

    //method i want to use
    firstHotel = GetFirstItem(Hotel{})
    firstPackage = GetFirstItem(Package{})
}

func GetFirstItem(item interface{}) interface{} {
    //how to implement this?
    //probably with some use of reflect package
}

1 ответ

Решение

Метод db.First возвращает ссылку на db и переводит строку в переданную структуру.

Наиболее близким к вашему желаемому методу является

func GetFirstItem(item interface{}) error {
    return db.First(item).Error
}

Это просто требует, чтобы вы сохранили ссылку на параметр

var firstHotel &Hotel{}
err := GetFirstItem(firstHotel)

Возвращение гидратированного объекта для всех типов потребовало бы параметров типа (обобщений). Я думаю, вы найдете, что текущая ситуация работоспособна в определенных пределах.

см. также: почему нет генериков в Go?

Другие вопросы по тегам