
主流数据库驱动连接方式
1.mongodb数据库
connect函数用于建立连接,mgo.Dial的入参为MongoDB的连接地址,完整的规则如下:
mongodb://myuser:mypass@localhost:40001,otherhost:40001/mydb可以根据自己的需要进行相应的配置。每次进行连接时需要指定表名,既MongoDB中的cllection
服务端基于MongoDB的存储方式实践
package main import ( "fmt" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "html/template" "log" "net/http" ) type User struct { Id string Name string Habits string CreatedTime string } var tpl = `<html> <head> <title></title> </head> <body> <form action="/info" method="post"> 用户名:<input type="text" name="username"> 兴趣爱好:<input type="text" name="habits"> <input type="submit" value="提交"> </form> </body> </html>` func connect(cName string) (*mgo.Session, *mgo.Collection) { session, err := mgo.Dial("mongodb://admin:[email protected]:27017") //Mongodb's connection checkErr(err) session.SetMode(mgo.Monotonic, true) //return a instantiated collect return session, session.DB("user").C(cName) } func queryByName(name string) []User { var user []User s, c := connect("user") defer s.Close() err := c.Find(bson.M{"name": name}).All(&user) checkErr(err) return user } func checkErr(err error) { if err != nil { panic(err) } } func submitForm(w http.ResponseWriter, r *http.Request) { fmt.Println("method:", r.Method) //获取请求的方法 var t *template.Template t = template.New("Products") //创建一个模板 t, _ = t.Parse(tpl) log.Println(t.Execute(w, nil)) } func store(user User) error { //插入数据 s, c := connect("user") defer s.Close() user.Id = bson.NewObjectId().Hex() return c.Insert(&user) } func userInfo(w http.ResponseWriter, r *http.Request) { //请求的是登录数据,那么执行登录的逻辑判断 _ = r.ParseForm() if r.Method == "POST" { user1 := User{Name: r.Form.Get("username"), Habits: r.Form.Get("habits")} store(user1) fmt.Fprintf(w, " %v", queryByName("aoho")) //这个写入到w的是输出到客户端的 } } func main() { http.HandleFunc("/form", submitForm) //设置访问的路由 http.HandleFunc("/info", userInfo) //设置访问的路由 err := http.ListenAndServe(":8080", nil) //设置监听的端口 if err != nil { log.Fatal("ListenAndServe: ", err) } }插入数据时,指定了记录的id,需要注意的是,如果在定义时将ID类型定义为bson.ObjectID,并指定bson标签为_id,mongodb将不会为它分配新的id。但是这样的结构与JSON做交互时不是很方便
在做记录的查询时,需要新建一个同类型的结构体或结构体数组,然后执行Find操作,如果参数为空,则返回全部记录
2.redis数据库
[Redis 编程入门] https://www.opsxdev.com/articles/2020/11/10/1604980762120 Redis 编程入门
Conn 接口是与 Redis 协作的主要接口,可以使用 Dial,DialWithTimeout 或者 NewConn 函数来创建连接,当任务完成时,应用程序必须调用 Close 函数来完成操作。
新建 go 文件(demo10_redis_open.go),示例代码:
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) func main() { conn, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("connect redis error :", err) return } fmt.Println("connect success ...") defer conn.Close() }
3.es数据库
参考此文档:Go接入Elasticsearch
4.mysql数据库
Go语言定义的标准接口:
接口名称 说明 sql.Register 当第三方开发者开发数据库驱动时,都会实现Init函数,在init里面会调用这个Register(name string,driver driver.Driver)完成本驱动的注册 driver.Driver Driver是一个数据库驱动的接口,它定义了一个method:Open(name string),这个方法返回一个数据库的Conn接口 dirver.Conn Conn是一个数据库连接的接口 driver.Stmt Stmt是一种准备好的状态,和Conn相关联,而且只能应用于一个goroutine中 dirver.Tx 事务处理一般就两个过程:递交或者回滚 driver.Result 执行Update/Insert等操作返回的结果接口定义 database/sql database/sql在database/sql/driver提供的接口基础上定义了一些更高阶的方法,用以简化数据库操作,同时内部还建议性地实现一个conn pool 参考此文档:Mysql 编程入门
- 首先导入包
import ( "database/sql" _ "github.com/go-sql-driver/mysql" )database/sql,是 golang 的标准库之一,它提供了一系列接口方法,用于访问关系数据库。它并不会提供数据库特有的方法,那些特有的方法交给数据库驱动去实现。
我们正在加载的驱动是匿名的,将其限定符别名为_。当导入了一个数据库驱动后, 此驱动会自行初始化并注册自己到 Golang 的 database/sql 上下文中, 因此我们就可以通过 database/sql 包提供的方法访问数据库了。
- 建立连接
使用 Open 函数
func Open(driverName, dataSourceName string) (*DB, error) /* 其中的两个参数: drvierName,这个名字其实就是数据库驱动注册到 database/sql 时所使⽤用的名字. "mysql" dataSourceName,数据库连接信息,这个连接包含了数据库的用户名, 密码, 数据库主机以及需要 连接的数据库名等信息. 用户名:密码@协议(地址:端口)/数据库?参数=参数值 */ db, err := sql.Open("mysql", "⽤用户名:密码@tcp(IP:端口)/数据库?charset=utf8mb4")例如:
db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True")说明:
- sql.Open 并不会立即建立一个数据库的网络连接, 也不会对数据库链接参数的合法性做检验, 它仅仅是初始化一个 sql.DB 对象。 当真正进行第一次数据库查询操作时, 此时才会真正建立网络连接;
- sql.DB 表示操作数据库的抽象接口的对象,但不是所谓的数据库连接对象, sql.DB 对象只有当需要使用时才会创建连接,如果想立即验证连接,需要用 Ping() 方法;
- sql.Open 返回的 sql.DB 对象是协程并发安全的。
- sql.DB 的设计就是用来作为长连接使用的。不要频繁 Open, Close。比较好的做法是,为每个不同的 datastore 建一个 DB 对象,保持这些对象 Open。如果需要短连接,那么把 DB 作为参数传入 function,而不要在 function 中 Open, Close。
package main import ( "database/sql" "fmt" ) // DB 声明全局的DB对象 var DB *sql.DB // initMySQL 初始化全局的DB对象 func initMySQL() error { dsn := "root:root1234@tcp(127.0.0.1:3306)/s2?charset=utf8mb4&parseTime=True" var err error DB, err = sql.Open("mysql", dsn) // 不会真正连接MySQL,也不会校验用户名密码 if err != nil { fmt.Printf("open MySQL failed, err:%v\n", err) return err } // 通过Ping()去判断连通性 if err := DB.Ping(); err != nil { fmt.Printf("connect to MySQL failed, err:%v\n", err) return err } fmt.Println("connect to MySQL success") return nil }
5.oracle数据库
待补充
5.postgresql数据库
待补充