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
}