函数式编程
SQLite 驱动程序无法从内存(例如从字节片)读取数据库文件。但是您可以将数据写入临时文件,然后打开该文件://go:generate go run gen.gopackage mainimport ( "database/sql" "fmt" "io/ioutil" "log" "os" _ "github.com/mattn/go-sqlite3")func main() { // Create temporary file for database. tmpDB, err := ioutil.TempFile("", "db*.sqlite3") if err != nil { log.Fatal(err) } // Remove this file after on exit. defer func() { err := os.Remove(tmpDB.Name()) if err != nil { log.Print(err) } }() // Write database to file. _, err = tmpDB.Write(sqlDB) if err != nil { log.Print(err) } err = tmpDB.Close() if err != nil { log.Print(err) } // Open DB. db, err := sql.Open("sqlite3", tmpDB.Name()+"?mode=ro") if err != nil { log.Fatal(err) } // Make sure it's loaded correct. rows, err := db.Query("select * from test") if err != nil { log.Fatal(err) } for rows.Next() { var c string err := rows.Scan(&c) if err != nil { log.Fatal(err) } fmt.Println(c) }}db.go您可以使用以下内容写入数据库:// +build generatepackage mainimport ( "fmt" "io/ioutil" "log" "os" "strings")func main() { // Read source database file. d, err := ioutil.ReadFile("source.sqlite3") if err != nil { log.Fatal(err) } fp, err := os.Create("db.go") if err != nil { log.Fatal(err) } _, err = fmt.Fprintf(fp, "// Code generated by gen.go; DO NOT EDIT.\n\n"+ "package main\n\n"+ "var sqlDB = %s\n", asbyte(d)) if err != nil { log.Fatal(err) }}// Write any data as byte array.func asbyte(s []byte) string { var b strings.Builder for i, c := range s { if i%19 == 0 { b.WriteString("\n\t\t") } b.WriteString(fmt.Sprintf("%#x, ", c)) } return "[]byte{" + b.String() + "}"}如果您愿意,也可以使用 go-bindata 或 packr,但我并没有真正看到优势。另一种方法是使用内存数据库,这可能会更快,具体取决于您想要执行的操作。将您想要的 SQL 架构和行作为字符串嵌入到 Go 二进制文件中。当程序启动时打开一个新的内存数据库(sql.Open("sqlite3",:memory:`)并创建模式并插入行。此方法没有磁盘访问,因此查询它可能会更快一点,但代价是启动时间较慢(当然是基准!)