命令记不住

登陆

主流数据库驱动连接方式

主流数据库驱动连接方式

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 编程入门

  1. 首先导入包
import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

database/sql,是 golang 的标准库之一,它提供了一系列接口方法,用于访问关系数据库。它并不会提供数据库特有的方法,那些特有的方法交给数据库驱动去实现。
我们正在加载的驱动是匿名的,将其限定符别名为_。

当导入了一个数据库驱动后, 此驱动会自行初始化并注册自己到 Golang 的 database/sql 上下文中, 因此我们就可以通过 database/sql 包提供的方法访问数据库了。

  1. 建立连接

使用 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数据库

待补充

推荐阅读