Go·链接PostGresSQL 操作增删查改
共性:sql语句使用反斜杠 “包裹 里面语句即可使用双引号来查询,实现PgSQL字段的大小区分
报错无效地址或无效指针:解决方式 在可能报错的 结构体属性字段 使用(*)星号指针
例如:
type User struct { //用户结构体
Id *int `json:"id"` // 用户id
Name *string `json:"name"` // 用户名称
Img string `json:"img"` // 用户头像图片
}Golang·链接PostGresSQL 操作数据库
0】项目下确保存在 go.mod 和 go.sum 文件没有则运行 go mod init test 生成(test为项目文件夹名)
1】项目下终端载入数据库连接驱动 go get github.com/lib/pq
2】项目里引入驱动
import (
"database/sql"
_ "github.com/lib/pq"
)3】链接数据库 例子
var DB *sql.DB
func DbOpen() { //数据库链接
var err error
sqlinfo := "host=127.0.0.1 port=5432 user=数据库名称 password=数据库密码 dbname=数据表名 sslmode=disable"
// sqlinfo数据库信息 host=数据库iP地址 port=端口号 user=数据库用户名 password=数据库密码 dbname=数据库表名 sslmode=安全模式disable (disable/verify-full/verify-ca)
// 以上配置 PgSQL数据库 表 必须在 默认模式的 public中,github.com/lib/pq 驱动无指定模式,解决办法是在sql语句中使用 schemaName.tableName 来指定要访问的模式
// 模式访问如: SELECT id, name, text FROM xx数据库名.xx模式名称.xx表名 或 SELECT id, name, text FROM xx模式名称.xx表名
DB, err = sql.Open("postgres", sqlinfo)
if err != nil {
log.Panicln("PgSQL链接失败")
panic(err)
} else {
fmt.Println("链接成功")
}
defer DB.Close() //延伸关闭数据库 必须关闭Db.Close关闭数据库 否则并发连接池过大,请求超50次会导致数据库宕机404或502
///查询 多条
rows, err := DB.Query("SELECT id, blok, name, text FROM weixin.life_menu ") // SQL语句:查询 id blok name text 在weixin模式的life_menu表
if err != nil { //异常打印
panic(err)
}
var ArrMenu []Life_Menu
for rows.Next() { //循环存储列表
var menu Life_Menu
err := rows.Scan(&menu.Id, &menu.Blok, &menu.Name, &menu.Text)
if err != nil { //异常处理
fmt.Println("异常处理:", err.Error())
}
fmt.Println(menu) //打印结果
ArrMenu = append(ArrMenu, menu) //存入数组
}
}
type Life_Menu struct { //菜单结构
Id int
Type string //类型
Name string //名称
Text string //提示内容
}封装数据库接口方法涵
// 封装数据库接口方法涵 //引用方式:var DB = DBsql()
func DBsql() *sql.DB {
sqlinfo := "host=127.0.0.1 port=5432 user=数据库名称 password=数据库密码 dbname=数据表名 sslmode=disable"
DB, err := sql.Open("postgres", sqlinfo)
if err != nil {
log.Panicln("PgSQL链接失败")
panic(err)
}
//引用方式:var DB = DBsql() rows := DB.QueryRow(sql语句)
return DB
}4】查询多条
func QueryMenu() string { //查询数据
sql := "SELECT id, name, text FROM weixin.life_menu" //SELECT * FROM 模式名.表名
var DB = DBsql()
rows, err := DB.Query(sql) // SQL语句:查询 id name text 在weixin模式的life_menu表
if err != nil { //异常打印
panic(err)
}
defer DB.Close() //关闭数据库
/* */
var ArrMenu []Life_Menu
for rows.Next() { //循环存储列表
var menu Life_Menu
err := rows.Scan(&menu.Id, &menu.Blok, &menu.Name, &menu.Text)
if err != nil { //异常处理
log.Println("异常处理:", err.Error())
}
fmt.Println(menu) //打印结果
ArrMenu = append(ArrMenu, menu) //存入数组
}
rows.Close() //关闭
return "ArrMenu"
}5】查询单条
var menu Life_Menu
err := DB.QueryRow("SELECT id,name, text FROM weixin.life_menu WHERE id='1' ").Scan(&menu.Id, &menu.Name, &menu.Text) // SQL语句
if err != nil { //异常打印
panic(err)
}
//Scan 存储结果, 非常重要:确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放
fmt.Println(menu) //打印结果6】更新数据
rows, err := DB.Exec("UPDATE weixin.life_menu SET blok= '111', name= '222', text= '333' WHERE id='1' ") // SQL语句:查询 id blok name text 在weixin模式的life_menu表
if err != nil { //异常打印 //异常打印
panic(err)
}
fmt.Println("执行结果:", rows) //打印结果7】插入数据
//rows, err := DB.Exec("INSERT INTO weixin.life_menu (blok,name,text)VALUES('box','name11','text1') ") // SQL语句:查询 id blok name text 在weixin模式的life_menu表
//方式二
var id string
err = DB.QueryRow("INSERT INTO weixin.life_menu (blok,name,text)VALUES('box11','name11','text11') RETURNING id ").Scan(&id) // SQL语句 Scan 接收返回id
if err != nil { //异常打印
panic(err)
}
fmt.Println("执行结果:", id) //打印返回id结果
8】删除数据
rows, err := DB.Exec("DELETE FROM weixin.life_menu WHERE id=21 ") // SQL语句说明:weixin模式的life_menu表
if err != nil { //异常打印
panic(err)
}
fmt.Println("执行结果:", rows) //打印结果最后 多个地方调用 需要自行封装成方法涵
无法做夸 DB *sql.DB 模式 只能封装成方法涵
//引用方式:var DB = DBsql()
//rows := DB.QueryRow(sql语句)