gpt4 book ai didi

go - 将接口(interface)与 golang 和数据库抽象结合使用

转载 作者:IT王子 更新时间:2023-10-29 01:44:33 25 4
gpt4 key购买 nike

我正在尝试弄清楚如何在 Go 中构建数据存储抽象。我想我了解接口(interface)的基础知识。但是,我遇到的问题是所有在线示例都只向您展示了最简单的情况,除此之外什么都没有。

我想做的是弄清楚如何以及在何处放置 SQL 代码。我试图编写最简单的代码来说明我正在尝试做什么(是的,没有错误代码,是的,路径结构不是惯用的)。我有一个包含两个表的数据库。一个用于存储圆圈,一个用于存储正方形。我在 Go 中有对象来制作这些。我的目录结构是:

project/main.go
project/test.db
project/shapes/shape.go
project/shapes/circle/circle.go
project/shapes/square/square.go
project/datastore/datastore.go
project/datastore/sqlite3/sqlite3.go

我能想到的唯一方法是将 SQL INSERT 和 SELECT 代码放入实际形状文件(circle.go 和 square.go)中。但这感觉真的不对。它似乎应该是 datastore/sqlite3 包的一部分。我只是不知道如何使它起作用。这是我目前所拥有的:

主.go

package main

import (
"fmt"
"project/datastore/sqlite3"
"project/shapes/circle"
"project/shapes/square"
)

func main() {
c := circle.New(4)
area := c.Area()
fmt.Println("Area: ", area)

s := square.New(12)
area2 := s.Area()
fmt.Println("Area: ", area2)

db := sqlite3.New("test.db")
db.Put(c)
db.Close()
}

形状/形状.go

package shapes

type Shaper interface {
Area() float64
}

形状/圆/circle.go

package circle

import (
"project/shapes"
)

type CircleType struct {
Radius float64
}

func New(radius float64) shapes.Shaper {
var c CircleType
c.Radius = radius
return &c
}

func (c *CircleType) Area() float64 {
area := 3.1415 * c.Radius * c.Radius
return area
}

形状/方形/方形.go

package square

import (
"project/shapes"
)

type SquareType struct {
Side float64
}

func New(side float64) shapes.Shaper {
var s SquareType
s.Side = side
return &s
}

func (s *SquareType) Area() float64 {
area := s.Side * s.Side
return area
}

数据存储/datastore.go

package datastore

import (
"project/shapes"
)

type ShapeStorer interface {
Put(shape shapes.Shaper)
Close()
}

数据存储/sqlite3/sqlite3.go

package sqlite3

import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
"log"
"project/datastore"
"project/shapes"
)

type Sqlite3DatastoreType struct {
DB *sql.DB
}

func New(filename string) datastore.ShapeStorer {
var ds Sqlite3DatastoreType

db, sqlerr := sql.Open("sqlite3", filename)
if sqlerr != nil {
log.Fatalln("Unable to open file due to error: ", sqlerr)
}
ds.DB = db

return &ds
}

func (ds *Sqlite3DatastoreType) Close() {
err := ds.DB.Close()
if err != nil {
log.Fatalln(err)
}
}

func (ds *Sqlite3DatastoreType) Put(shape shapes.Shaper) {
log.Println("Help")
// here you could either do a switch statement on the object type
// or you could do something like shape.Write(), if Write() was defined
// on the interface of shape/shapes.go Shaper interface and then
// implemented in the Square and Circle objects.
}

由于 Circle 和 Square 对象的数据库表不同,因此我需要为每个对象提供一个方法。如果我向 circle 包和 square 包添加一个方法来进行插入,我就可以让它工作。但是就像我上面说的,感觉我做错了。

提前致谢。

最佳答案

类型切换是正确的做法。您的逻辑代码(您编写的代码,因为之前没有其他人这样做过)应该对存储一无所知。

假设您想要为请求添加一个计数器,并且您决定对 Redis 上的请求进行计数。然后怎样呢?是否也将计数器集合名称添加到 Shape 中?

然后您应该创建一个新的 ShapeStorer 作为装饰器,并在 put 方法中调用 Redis ShapeStorer 和 sqlite ShapeStorer。

对于非 sql 数据库,您有时根本不关心架构,您只需序列化对象并保存它。

关于go - 将接口(interface)与 golang 和数据库抽象结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46901435/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com