go入门(1)访问关系数据库mysql

访问关系数据库mysql

在工作空间中新建一个包data-access,使用

go mod init example/data-access

进行初始化;

在data-access包中新建main.go文件内容如下:

package main

import (
    "database/sql"
    "fmt"
    "log"
    "os"

    "github.com/go-sql-driver/mysql"
)
var db *sql.DB

func main() {
    // Capture connection properties.
    cfg := mysql.Config{
        User:   os.Getenv("DBUSER"),
        Passwd: os.Getenv("DBPASS"),
        Net:    "tcp",
        Addr:   "***.***.***.***:3306",
        DBName: "{要连接的数据库中已存在的库名}",
    }
    // Get a database handle.
    var err error
    db, err = sql.Open("mysql", cfg.FormatDSN())
    if err != nil {
        log.Fatal(err)
    }

    pingErr := db.Ping()
    if pingErr != nil {
        log.Fatal(pingErr)
    }
    fmt.Println("Connected!")
}

使用

go mod tidy

自动添加"github.com/go-sql-driver/mysql"依赖,此依赖为MySQL驱动程序模块用于连接映射数据库;

上面代码中

cfg := mysql.Config{
    User:   os.Getenv("DBUSER"),
    Passwd: os.Getenv("DBPASS"),
    Net:    "tcp",
    Addr:   "***.***.***.***:3306",
    DBName: "{要连接的数据库中已存在的库名}",
}

cfg即是数据库连接的配置,DBUSER与DBPASS为go中配置的环境变量,不能直接填入数据库用户名与密码,因为此为敏感信息,必须储存在环境变量中才能够让go编译识别;

在命令行中通过set设置对应环境变量

set DBUSER=username
set DBPASS=password

之后

go run .

运行程序,命令行输出为

Connected!

则连接正常;

增查操作

先定义一个结构体用于数据传输

// 定义Student结构体
type Student struct {
id int64
name string
age int64
gender string
}

创建三个函数

func studentByName(name string)

func studentByID(id int64) (Student, error)

func addStudent(alb Student) (int64, error)

分别用于多条查询,单条查询,单条插入的简单操作;

每个函数通用操作步骤为:

  • 定义一个结构体实例;
  • 通过数据库语柄的内置函数执行mysql语句;
  • 对返回值进行判断,若报错则返回报错,否则就存入切片或者变量中,作为返回值返回。

"database/sql""github.com/go-sql-driver/mysql"必须同时使用。

最终代码如下:

package main

import (
  "database/sql"
  "fmt"
  "log"
  "os"
  "github.com/go-sql-driver/mysql"
)
// 定义数据库语柄
var db *sql.DB

// 定义Student结构体
type Student struct {
  id   int64
  name  string
  age   int64
  gender string
}
func main() {
  // 数据库连接配置
  cfg := mysql.Config{
​    User:  os.Getenv("DBUSER"),
​    Passwd: os.Getenv("DBPASS"),
​    Net:   "tcp",
​    Addr:  "118.25.40.30:3307",
​    DBName: "dewu",
  }
  // 连接数据库
  var err error
  db, err = sql.Open("mysql", cfg.FormatDSN())
  if err != nil {
​    log.Fatal(err)
  }
  // 检查连接
  pingErr := db.Ping()
  if pingErr != nil {
​    log.Fatal(pingErr)
  }
  fmt.Println("Connected!")

  // 多条查询
  student, err := studentByName("张三")
  if err != nil {
​    log.Fatal(err)
  }
  fmt.Printf("Students found: %v\n", student)

  // 单条查询
  alb, err := studentByID(2)
  if err != nil {
​    log.Fatal(err)
  }
  fmt.Printf("Student found: %v\n", alb)

  // 单条插入
  albID, err := addStudent(Student{
​    id:888,
​    name:  "苟八",
​    age: 18,
​    gender:  "4",
  })
  if err != nil {
​    log.Fatal(err)
  }
  fmt.Printf("ID of added student: %v\n", albID)
}

func studentByName(name string) ([]Student, error) {
  // 储存查询结果的切片
  var students []Student
  // Query多条查询
  rows, err := db.Query("SELECT * FROM student WHERE name = ?", name)
  if err != nil {return nil, fmt.Errorf("studentByName %q: %v", name, err)
  }
  defer rows.Close()
  for rows.Next() {var alb Student
​    if err := rows.Scan(&alb.id, &alb.name, &alb.age, &alb.gender); err != nil {return nil, fmt.Errorf("studentByName %q: %v", name, err)}
​    students = append(students, alb)
  }
  if err := rows.Err(); err != nil {return nil, fmt.Errorf("studentByName %q: %v", name, err)
  }
  return students, nil
}

func studentByID(id int64) (Student, error) {
  var alb Student
  row := db.QueryRow("SELECT * FROM student WHERE id = ?", id)
  if err := row.Scan(&alb.id, &alb.name, &alb.age, &alb.gender); err != nil {if err == sql.ErrNoRows {return alb, fmt.Errorf("studentsById %d: no such student", id)}return alb, fmt.Errorf("studentsById %d: %v", id, err)
  }
  return alb, nil
}

func addStudent(alb Student) (int64, error) {
  result, err := db.Exec("INSERT INTO student (id,name, age, gender) VALUES (?,?, ?, ?)",alb.id, alb.name, alb.age, alb.gender)
  if err != nil {return 0, fmt.Errorf("addStudent: %v", err)
  }
  id, err := result.LastInsertId()
  if err != nil {return 0, fmt.Errorf("addStudent: %v", err)
  }
  return id, nil
}

输出结果为:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值