sqlx is a library which provides a set of extensions on go's standard database/sql library.

sqlx support some db:  mysql, postgresql, oracle, sqlite ...

https://github.com/jmoiron/sqlx

示例代码:

该库目前只对查询进行了深度封装,对于更新和插入封装较少。

新建表

package main

import (
"database/sql"
_ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx"
) var schema = `Create table person2(
first_name varchar(),
last_name varchar(),
email varchar());
` var schema2 = `Create table place(
country varchar(),
city varchar() NULL,
telcode int());
` type Person struct {
FirstName string `db:"first_name"`
LastName string `db:"last_name"`
Email string
} type Place struct {
Country string
city sql.NullString
TelCode int
} func main() {
dsn := "root:123456@tcp(172.16.65.200:3306)/golang"
db, err := sqlx.Connect("mysql", dsn)
if err != nil {
panic(err)
} result, err := db.Exec(schema2)
if err != nil {
panic(err)
}
_, err = result.RowsAffected()
if err != nil {
panic(err)
} }

单行查询使用 sqlx.Get(),多行查询使用 sqlx.Select()

package main

import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"fmt"
"log"
"github.com/jmoiron/sqlx"
) type User struct {
Id int `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} // 单行查询,如果查询到多个结果,只返回第一行,查询不到结果就ErrNoRows错误。
func QueryRow(db *sqlx.DB) {
var user User
err := db.Get(&user, "select id, name, age from user where id=?", )
if err == sql.ErrNoRows {
log.Printf("not found data of the id:%d", )
} if err != nil {
panic(err)
} fmt.Printf("user: %#v\n", user)
} // 多行查询, 查询不到任何记录也不会报错。
func Query(db *sqlx.DB) {
var users []*User
err := db.Select(&users, "select id, name, age from user")
if err != nil {
panic(err)
}
if err == sql.ErrNoRows {
log.Printf("not found data")
return
} for _, user := range users {
fmt.Println(user.Id, user.Name)
}
} func main() {
dsn := "root:123456@tcp(172.16.65.200:3306)/golang"
db, err := sqlx.Connect("mysql", dsn)
if err != nil {
panic(err)
} err = db.Ping()
if err != nil {
panic(err)
} fmt.Printf("connect to db success\n") QueryRow(db) Query(db)
}

更新和插入使用sqlx.Exec()

package main

import (
_ "github.com/go-sql-driver/mysql"
"fmt"
"github.com/jmoiron/sqlx"
) func Update(db *sqlx.DB) {
name := "Miles"
age :=
id := result, err := db.Exec("update user set name=?, age=? where id=?", name, age, id)
if err != nil {
panic(err)
} // RowsAffected returns the number of rows affected by an
// update, insert, or delete.
rowsAffected, err := result.RowsAffected()
if err != nil {
panic(err)
} fmt.Printf("update id:%d, affect rows:%d\n", id, rowsAffected) } func Insert(db *sqlx.DB) {
name := "Lucy"
age := result, err := db.Exec("insert into user(name, age) values (?,?)", name, age)
if err != nil {
panic(err)
} id, err := result.LastInsertId()
if err != nil {
panic(err)
} affected, err := result.RowsAffected()
if err != nil {
panic(err)
} fmt.Printf("last insert id:%d affect rows:%d\n", id, affected)
} func main() {
dsn := "root:123456@tcp(172.16.65.200:3306)/golang"
db, err := sqlx.Connect("mysql", dsn)
if err != nil {
panic(err)
} err = db.Ping()
if err != nil {
panic(err)
}
fmt.Println("connect to db success!!!")
Update(db)
Insert(db)
}

预处理,直接使用原生的sql.db,没有进行过任何封装

package main

import (
_ "github.com/go-sql-driver/mysql"
"fmt"
"github.com/jmoiron/sqlx"
) type User2 struct {
Id int `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
} // 预处理是为了提高查询性能;
// 实现的原理是先将查询语句发送给Mysql数据库做预解析;
// 然后再将需要查询的条件数据发送给Mysql数据库进行执行;
// 这种原理类似于GO语言和Python语言执行效率的对比;
// Go语言是需要先编译的,Python是一边执行一边编译。
func PrepareQuery(db *sqlx.DB, id int) {
stmt, err := db.Prepare("select id, name, age from user where id>?")
if err != nil {
panic(err)
} rows, err := stmt.Query(id)
if err != nil {
panic(err)
} defer stmt.Close()
defer rows.Close() for rows.Next(){
var user User2
err := rows.Scan(&user.Id, &user.Name, &user.Age)
if err != nil {
panic(err)
}
fmt.Printf("user: %#v\n", user)
}
} func main() { dsn := "root:123456@tcp(172.16.65.200:3306)/golang"
db, err := sqlx.Connect("mysql", dsn)
if err != nil {
panic(err)
} defer db.Close() PrepareQuery(db, ) }

原则性操作

package main

import (
_ "github.com/go-sql-driver/mysql"
"fmt"
"github.com/jmoiron/sqlx"
) func Transaction(db *sqlx.DB) { // 开启事务
tx, err := db.Begin() if err != nil {
panic(err)
} result, err := tx.Exec("insert into user(name, age)values(?,?)", "Jack", )
if err != nil {
// 失败回滚
tx.Rollback()
panic(err)
} fmt.Println("result", result) exec, err := tx.Exec("update user set name=?, age=? where id=?", "Jack", , )
if err != nil {
// 失败回滚
tx.Rollback()
panic(err)
}
fmt.Println("exec", exec) // 提交事务
err = tx.Commit() if err != nil {
// 失败回滚
tx.Rollback()
panic(err)
}
} func main() { dsn := "root:123456@tcp(172.16.65.200:3306)/golang"
db, err := sqlx.Connect("mysql", dsn)
if err != nil {
panic(err)
} err = db.Ping()
if err != nil {
panic(err)
} Transaction(db)
}

Named

    // Named queries can use structs, so if you have an existing struct (i.e. person := &Person{}) that you have populated, you can pass it in as &person
tx.NamedExec("INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)", &Person{"Jane", "Citizen", "jane.citzen@example.com"})
tx.Commit()

更多用法

package main

import (
"database/sql"
"fmt"
"log" _ "github.com/lib/pq"
"github.com/jmoiron/sqlx"
) var schema = `
CREATE TABLE person (
first_name text,
last_name text,
email text
); CREATE TABLE place (
country text,
city text NULL,
telcode integer
)` type Person struct {
FirstName string `db:"first_name"`
LastName string `db:"last_name"`
Email string
} type Place struct {
Country string
City sql.NullString
TelCode int
} func main() {
// this Pings the database trying to connect, panics on error
// use sqlx.Open() for sql.Open() semantics
db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable")
if err != nil {
log.Fatalln(err)
} // exec the schema or fail; multi-statement Exec behavior varies between
// database drivers; pq will exec them all, sqlite3 won't, ymmv
db.MustExec(schema) tx := db.MustBegin()
tx.MustExec("INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)", "Jason", "Moiron", "jmoiron@jmoiron.net")
tx.MustExec("INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)", "John", "Doe", "johndoeDNE@gmail.net")
tx.MustExec("INSERT INTO place (country, city, telcode) VALUES ($1, $2, $3)", "United States", "New York", "")
tx.MustExec("INSERT INTO place (country, telcode) VALUES ($1, $2)", "Hong Kong", "")
tx.MustExec("INSERT INTO place (country, telcode) VALUES ($1, $2)", "Singapore", "")
// Named queries can use structs, so if you have an existing struct (i.e. person := &Person{}) that you have populated, you can pass it in as &person
tx.NamedExec("INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)", &Person{"Jane", "Citizen", "jane.citzen@example.com"})
tx.Commit() // Query the database, storing results in a []Person (wrapped in []interface{})
people := []Person{}
db.Select(&people, "SELECT * FROM person ORDER BY first_name ASC")
jason, john := people[], people[] fmt.Printf("%#v\n%#v", jason, john)
// Person{FirstName:"Jason", LastName:"Moiron", Email:"jmoiron@jmoiron.net"}
// Person{FirstName:"John", LastName:"Doe", Email:"johndoeDNE@gmail.net"} // You can also get a single result, a la QueryRow
jason = Person{}
err = db.Get(&jason, "SELECT * FROM person WHERE first_name=$1", "Jason")
fmt.Printf("%#v\n", jason)
// Person{FirstName:"Jason", LastName:"Moiron", Email:"jmoiron@jmoiron.net"} // if you have null fields and use SELECT *, you must use sql.Null* in your struct
places := []Place{}
err = db.Select(&places, "SELECT * FROM place ORDER BY telcode ASC")
if err != nil {
fmt.Println(err)
return
}
usa, singsing, honkers := places[], places[], places[] fmt.Printf("%#v\n%#v\n%#v\n", usa, singsing, honkers)
// Place{Country:"United States", City:sql.NullString{String:"New York", Valid:true}, TelCode:1}
// Place{Country:"Singapore", City:sql.NullString{String:"", Valid:false}, TelCode:65}
// Place{Country:"Hong Kong", City:sql.NullString{String:"", Valid:false}, TelCode:852} // Loop through rows using only one struct
place := Place{}
rows, err := db.Queryx("SELECT * FROM place")
for rows.Next() {
err := rows.StructScan(&place)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("%#v\n", place)
}
// Place{Country:"United States", City:sql.NullString{String:"New York", Valid:true}, TelCode:1}
// Place{Country:"Hong Kong", City:sql.NullString{String:"", Valid:false}, TelCode:852}
// Place{Country:"Singapore", City:sql.NullString{String:"", Valid:false}, TelCode:65} // Named queries, using `:name` as the bindvar. Automatic bindvar support
// which takes into account the dbtype based on the driverName on sqlx.Open/Connect
_, err = db.NamedExec(`INSERT INTO person (first_name,last_name,email) VALUES (:first,:last,:email)`,
map[string]interface{}{
"first": "Bin",
"last": "Smuth",
"email": "bensmith@allblacks.nz",
}) // Selects Mr. Smith from the database
rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:fn`, map[string]interface{}{"fn": "Bin"}) // Named queries can also use structs. Their bind names follow the same rules
// as the name -> db mapping, so struct fields are lowercased and the `db` tag
// is taken into consideration.
rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:first_name`, jason)
}

Go sqlx库的更多相关文章

  1. GO学习-(23) Go语言操作MySQL + 强大的sqlx

    Go语言操作MySQL MySQL是业界常用的关系型数据库,本文介绍了Go语言如何操作MySQL数据库. Go操作MySQL 连接 Go语言中的database/sql包提供了保证SQL或类SQL数据 ...

  2. Golang语言系列-15-数据库

    数据库 MySQL 连接数据库 package main import ( "database/sql" "fmt" _ "github.com/go ...

  3. Go语言基础之16--Mysql基本操作

    一.Mysql驱动及数据库连接 1.1 Golang中的Mysql驱动 A. https://github.com/go-sql-driver/mysql B. Go本身不提供具体数据库驱动,只提供驱 ...

  4. Go 操作 Mysql(一)

    关于 Go 的标准库 database/sql 和 sqlx database/sql 是 Go 操作数据库的标准库之一,它提供了一系列接口方法,用于访问数据库(mysql,sqllite,oralc ...

  5. 18 . Go之操作Mysql和sqlx使用

    安装mysql wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm yum -y localinstall ...

  6. sqlx操作MySQL实战及其ORM原理

    sqlx是Golang中的一个知名三方库,其为Go标准库database/sql提供了一组扩展支持.使用它可以方便的在数据行与Golang的结构体.映射和切片之间进行转换,从这个角度可以说它是一个OR ...

  7. 菜鸟Python学习笔记第一天:关于一些函数库的使用

    2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...

  8. TinyWeb v1.0 正式完成第一个Release版本(功能基于 libuv 跨平台库)

    使用方法很简单,很容易融入现有项目,使现有项目拥有Web网站功能和WebSocket,以及Socket直连! 并且包含了一个跨平台(windows/linux)工具集合; 嗯,也挺棒的^,^ 在项目中 ...

  9. 在 Laravel 中使用图片处理库 Integration/Image

    系统需求 PHP >= 5.3 Fileinfo Extension GD Library (>=2.0) … or … Imagick PHP extension (>=6.5.7 ...

随机推荐

  1. SlidingMenu官方实例分析7——SlidingContent和SlidingTitleBar区别

    包含ActionBar:setSlidingActionBarEnabled(true); 效果图: 不包含ActionBar:setSlidingActionBarEnabled(false); 效 ...

  2. ABAP小白的成长日记--------helloblog

    在外企公司培训了3个月,系统的学习了ABAP,希望开通Blog以后和大家一起深入学习交流.印度人的办事效率是出奇的低,赶超国企公务员.虽然内容cover到了几乎所有R/4的内容,但是还有很多知识没有真 ...

  3. LR测试文件上传

    开启fiddler  录制,回放,把上传文件放入脚本根目录中.

  4. MySQL基本操作(+参考手册)

    1.MySQL 5.1参考手册 2.基础教程 3.常用举例入下: 1 连接数据库:mysql -h主机地址 -u用户名-p用户密码 2 数据库的提示符:mysql> 3 退出数据库:exit(回 ...

  5. jquery 模糊查询对象属性

    1.如果你需要查询的对象属性id的值包含这样的值,你可以这样读取所有此条件的对象 $("input[id*='DiscountType']").each(function (i, ...

  6. 爬虫实战【5】送福利!Python获取妹子图上的内容

    [插入图片,妹子图首页] 哈,只敢放到这个地步了. 今天给直男们送点福利,通过今天的代码,可以把你的硬盘装的满满的~ 下面就开始咯! 第一步:如何获取一张图片 假如我们知道某张图片的url,如何获取到 ...

  7. 关于微信小程序的开发步骤

    ~~~~包子最近在研究小程序 首先先讲一下小程序一些基本的步骤: 1.登录微信的公众平台,选择小程序,注册一个账号,期间有碰到什么交300块钱的就不要理他,因为我只是做demo,当然,准备上线的企业啥 ...

  8. 剖析与优化 Go 的 web 应用

    https://mp.weixin.qq.com/s/HDsbZLOK3h8-XjejvPH2sA https://studygolang.com/articles/12685

  9. Distance matrix

    w https://en.wikipedia.org/wiki/Distance_matrix For example, suppose these data are to be analyzed, ...

  10. ubuntu17.04 配置go环境变量

    把官网下载好的tar解压后,go文件夹放到 /usr/local 目录下 在当前用户的 .bashrc 文件末尾添加 这句话 export PATH=$PATH:/usr/local/go/bin 执 ...