我是Golang的初学者,无法理解这种语言中的一些概念。我非常喜欢它,但在网络上,每个例子都非常简单,并没有解释正确的开发方式。 所以,我想配置与MySQL的数据库连接。我使用文件dbconfig.go创建一个包dbconfig,使用interfaces文件创建包dastructure,使用实体文件创建另一个包init实体。 这是结构:
main.go:
import (
y "github.com/danyalov/shebeke/dbconfig"
"github.com/danyalov/shebeke/routes"
_ "github.com/go-sql-driver/mysql"
"github.com/labstack/gommon/log"
)
func main() {
db, err := y.InitDB("mysql", "root:root@tcp(localhost:3306)/dbtest?parseTime=true")
if err != nil {
log.Fatal(err)
}
e := routes.NewConnection(db)
e.Logger.Fatal(e.Start(":9898"))
}
routes.go:
import (
"github.com/danyalov/shebeke/datastructure"
y "github.com/danyalov/shebeke/dbconfig"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
)
func NewConnection(db *y.DB) *echo.Echo {
e := echo.New()
env := Env{db}
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.GET("/contracts", env.GetContracts)
e.GET("/contract/:id", env.GetContractByID)
return e
}
type Env struct {
contract datastructure.Contract
}
services.go:
import (
"github.com/labstack/echo"
"log"
"net/http"
"strconv"
)
func (env *Env) GetContracts(c echo.Context) error {
contracts, err := env.contract.GetContracts()
if err != nil {
log.Fatal(err)
}
return c.JSON(http.StatusOK, &contracts)
}
dbconfig.go:
import (
"database/sql"
"fmt"
"github.com/labstack/gommon/log"
)
type DB struct {
*sql.DB
}
//InitDB initialize mysql database
func InitDB(driver, path string) (*DB, error) {
db, err := sql.Open(driver, path)
if err != nil {
log.Fatal(err)
}
err = db.Ping()
if err != nil {
log.Fatal(err)
} else {
fmt.Println("Connected to DB")
}
return &DB{db}, err
}
数据结构/ contract.go:
import y "github.com/danyalov/shebeke/datastructure/entity"
type Contract interface {
GetContracts() (y.Contracts, error)
GetContractByID(id int) (y.Contract, error)
}
数据结构/实体/ contract.go:
import (
"github.com/labstack/gommon/log"
"time"
)
type Contract struct {
ID int `json:"id"`
State string `json:"state"`
StartDate time.Time `json:"start_date"`
FinishDate time.Time `json:"finish_date"`
}
type Contracts []Contract
func (db *DB) GetContracts() (c Contracts, err error) {
rows, err := db.Query("select * from contract")
if err != nil {
log.Fatal(err)
}
contract := Contract{}
for rows.Next() {
err = rows.Scan(&contract.ID, &contract.State, &contract.StartDate, &contract.FinishDate)
c = append(c, contract)
}
return c, err
}
为什么我不能将数据库类型从dbconfig包导入实体包作为方法接收器?我得到Unresolved type 'DB'
这是这个项目的my working copy(Git),我把dbconfig.go放在实体中,但是我不喜欢它,我认为这对dbconfig文件来说不正确。
在GO中配置db的正确文件结构是什么?也许你在Git或一些教程中有自己的例子?
答案 0 :(得分:5)
您只能在同一个包中定义的类型上定义方法。在这种情况下,您的DB
类型是在dbconfig
包中定义的,因此您的entity
包无法在其上定义方法。
在这种情况下,您的选择是使GetContracts成为函数而不是方法并将*dbconfig.DB
作为参数传递,或者通过在{{1中导入entity
包来反转依赖性并在那里写GetContracts(作为方法或函数,以任何方式工作)。第二个实际上可能是更好的选择,因为从设计的角度来看,它打破了抽象,使得除数据库包之外的包创建SQL查询字符串。