Вы, фактически, пытаетесь использовать паттерн проектирования Active Record. Почитайте про достоинства и недостатки этого паттерна, посмотрите как его лучше готовить, и можете смело применять, если это подходит вашей программе и вам это удобно.
Однако, лично я считаю этот паттерн вредным, потому что он намешивает всё в одну кучу. Это моё субъективное мнение, и я вам его не навязываю. Я бы отделил мух от котлет, и оставил бы структуру чистой, т.е. только данные и какие-то методы, которые работают конкретно с этими данными из структуры, а взаимодействие с базой данных организовал бы через паттерн проектирования Repository. Т.е. мы делаем уже отдельную структуру ProductRepository, которая содержит в себе методы, принимающие и отдающие структуру Product, и уже в этих методах реализуем вызов базы данных.
Я набросаю вам простенький интерфейс для использования этого паттерна, а конкретную структуру, реализующую этот интерфейс вы уже напишете сами. Интерфейсы использовать в таких случаях считаю вообще обязательным условием. Например, так нам будет гораздо проще тестировать код, всё становится гораздо гибче. Ведь структурку Product вы сможете без проблем использовать не только при работе с базой, но и при передаче данных в другие системы, не волнуясь о лишних методах, висящих на ней. Так же вы сможете легко менять реализации репозитория, не меняя бизнес-логику проекта. (Это позволит, например, легко заменить базу данных)
package models
type Product struct {
ID int `json:"id"`
Title string `json:"title"` //Название
Price int `json:"price"` //Цена
}
type ProductGetter interface {
GetAll() ([]Product, error)
GetByID(id int) (Product, error)
}
type ProductCreator interface {
Create(product Product) (Product, error)
}
type ProductUpdater interface {
Update(product Product) (Product, error)
}
type ProductDeleter interface {
Delete(id int) error
}
type ProductRepository interface {
ProductGetter
ProductCreator
ProductUpdater
}