Go的SQL操作:

一 :连接MySQL

示例1:

package main

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

	//数据库驱动
	_ "github.com/go-sql-driver/mysql"
	"strings"
)

type USER struct {
	UserName   string
	UserPasswd string
}

//mysql 信息

const (
	USERNAME = "xxxxx"
	PASSWORD = "xxxx"
	IP       = "xxxxx.com"
	PORT     = "3306"
	dbName   = "xxxx"
)

func main() {
	//初始化mysql连接
	InitDB()

	user := USER{
		UserName:   "李白",
		UserPasswd: "1234567",
	}
	//向表中插入数据
	InsertUser(user)
}

//初始化数据库连接方法

func InitDB() *sql.DB {
	//数据库连接字符串
	dsn := strings.Join([]string{USERNAME, ":", PASSWORD, "@tcp(", IP, ":", PORT, ")/", dbName, "?charset=utf8"}, "")
	//连接数据库
	DB, err := sql.Open("mysql", dsn)
	if err != nil {
		println("mysql open fail!")
		log.Fatal(err)
		return nil
	}
	//数据库最大连接数
	DB.SetConnMaxLifetime(100)
	//数据库最大空闲连接数
	DB.SetMaxIdleConns(10)
	//判断数据库是否连接成功
	if err := DB.Ping(); err != nil {
		fmt.Println("open database fail!")
		//记录日志
		log.Fatal(err)
		return nil
	}
	fmt.Println("数据库连接成功! ")
	return DB
}

//往user表插入数据(注意user表已建立)

func InsertUser(u USER) bool {

	//开启事务
	tx, err := InitDB().Begin()
	if err != nil {
		fmt.Println("tx fail!")
		log.Fatal(err)
		return false
	}

	//准备SQL语句
	stmt, err := InitDB().Prepare("INSERT INTO user (UserName,UserPasswd) values (?,?)")
	if err != nil {
		fmt.Println("Prepare fail!")
		log.Fatal(err)
		return false
	}

	defer stmt.Close()

	//将参数传递到sql语句中并且执行
	res, err := stmt.Exec(u.UserName, u.UserPasswd)
	if err != nil {
		fmt.Println("exec fail!")
		log.Fatal(err)
		return false
	}

	//将事务提交
	tx.Commit()

	//获得上一个插入自增的ID
	fmt.Println(res.RowsAffected())
	return true

}

提供对外访问方法连接示例:

mysql/conn.go

package mysql

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"os"
)

// 获取DB对象
var db *sql.DB

//初始化数据库连接

func init() {

	//数据库连接
	db, _ := sql.Open("mysql", "root:passwd@tcp(hostip:3306)/dbname?charset=utf8")

	//设置最大连接数
	db.SetMaxOpenConns(1000)
	//连接测试
	err := db.Ping()
	if err != nil {
		fmt.Println("Failed to connect to mysql,err: " + err.Error())
		//强制退出进程
		os.Exit(1)
	}
}

//提供对外部的访问方法

func DBConn() *sql.DB {
	return db
}

带有日志记录的连接示例:

mysql/conn.go

package mysql

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"log"
	"os"
)

//数据库初始化

func DBInit() *gorm.DB {

	//dsn: 数据库连接信息
	dsn := "root:passwd@tcp(hostip:3306)/dbname?charset=utf8&parseTime=True&loc=Local"

	//创建日志对象
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags), // io  write
		logger.Config{
			LogLevel: logger.Info, // Log level(日志级别)
		},
	)

	//获取db对象
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		//日志配置
		Logger: newLogger,
	})

	//判断错误
	if err != nil {
		panic("Failed to connect to database ...")
	}

	fmt.Println("数据库连接成功!!!", db)

	return db
}

二:连接 PostgreSQL

1. docker安装PG

docker search postgres
docker pull postgres
mkdir -p /data/postgres
#用户名为 postgres;密码为: password
docker run --name postgresql --privileged -e POSTGRES_PASSWORD=password -p 5432:5432 -v /data/postgres:/var/lib/postgresql/data -d postgres

2. go连接pg

建库:

CREATE DATABASE gopgtest;

连接:

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/lib/pq"
	"log"
)

type Product struct {
	Name      string
	Price     float64
	Available bool
}

func main() {

	//数据库连接信息
	connStr := "postgres://postgres:password@localhost:5432/gopgtest?sslmode=disable"

	db, err := sql.Open("postgres", connStr)

	//延迟关闭
	defer db.Close()

	if err != nil {
		log.Fatal(err)
	}

	// db.Ping : 检测数据库是否连接成功
	if err = db.Ping(); err != nil {
		log.Fatal(err)
	}

	//调用创建表函数
	createProductTable(db)

	//向表中插入数据

	//product := Product{
	//	Name:      "book",
	//	Price:     15.55,
	//	Available: true,
	//}
	//pk := insertProduct(db, product)
	//fmt.Printf("ID = %d\n", pk)

	//数据库查询,返回一行

	//var name string
	//var price float64
	//var available bool
	//
	//query := "SELECT name,available,price FROM product WHERE id = $1"
	//err = db.QueryRow(query, 4).Scan(&name, &available, &price)
	//if err != nil {
	//	if err == sql.ErrNoRows {
	//		log.Fatalf("No rows found with ID %d", 4) //如果错误信息等于sql行错误,则返回: No rows found with ID 4
	//
	//	}
	//	log.Fatal(err)
	//}
	//fmt.Printf("Name: %s\n", name)
	//fmt.Printf("Available: %t\n", available) //%t 打印bool值 true or false
	//fmt.Printf("Price: %f\n", price)

	//数据库查询, 返回多行
	data := []Product{}

	rows, err := db.Query("SELECT name,available,price FROM product")
	if err != nil {
		log.Fatal(err)
	}

	defer rows.Close()
	//to scan DB vals
	var name string
	var available bool
	var price float64
	//循环rows
	for rows.Next() {
		err := rows.Scan(&name, &available, &price)
		if err != nil {
			log.Fatal(err)
		}
		data = append(data, Product{name, price, available})
	}
	fmt.Println("data: ", data)

}

func createProductTable(db *sql.DB) {
	/*Product Table
	- ID
	- Name
	- Price
	- Available
	- Date Created
	*/
	qyery := `CREATE TABLE IF NOT EXISTS product (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
	price NUMERIC(6,2) NOT NULL,
    available BOOLEAN,
    cretaed timestamp DEFAULT NOW()
)`
	//db.Exec 执行后不会返回,执行返回需要使用db.Query
	//只需要接収err来判断SQL语句是否执行成功
	_, err := db.Exec(qyery)
	if err != nil {
		log.Fatal(err)
	}

}

//向表中插入数据

func insertProduct(db *sql.DB, product Product) int {
	query := `INSERT INTO product (name,price,available) 
		VALUES ($1,$2,$3) RETURNING id`

	var pk int
	err := db.QueryRow(query, product.Name, product.Price, product.Available).Scan(&pk)
	if err != nil {
		log.Fatal(err)
	}
	return pk
}