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. sqoop-1.4.4安装配置

    环境:redhat6.5 hadoop2.4.1 感谢: http://wenku.baidu.com/view/a9083da8dd3383c4bb4cd274.html注释hbase检查 感谢: ...

  2. WCF服务寄宿IIS与Windows服务

      WCF是Windows平台下程序间通讯的应用程序框架.整合和 .net Remoting,WebService,Socket的机制,是用来开发windows平台上分布式开发的最佳选择.wcf程序的 ...

  3. ios--后台返回信息有字符串和数字组成的,如何获取电话号码,让用户能够点击并且进行拨打?

    -(void)callPhone:(NSString*)phoneNumber{ NSString *phoneStr=[NSString stringWithFormat:@"tel:// ...

  4. 解决ios8 webView加载的地图无法定位问题

    本文转载至http://www.cocoachina.com/bbs/read.php?tid-237825.html     1.在文件info.pilist 中导入 NSLocationWhenI ...

  5. jconsole监控JVM

    1.查找catalina.sh,使用tomcat中的catalina.sh 目录地址/opt/apache-tomcat-7.0.82/bin 2.配置JAVA_OPTS JAVA_OPTS=&quo ...

  6. java.lang.VerifyError: Expecting a stack map frame

    https://blog.csdn.net/u013066244/article/details/78434134 对于java7而言,需要添加 -XX:-UseSplitVerifier(已实践). ...

  7. MySQL-库的操作

    05-库的操作   本节重点: 掌握库的增删改查   一.系统数据库 执行如下命令,查看系统库 show databases; nformation_schema: 虚拟库,不占用磁盘空间,存储的是数 ...

  8. EasyNVR智能云终端硬件使用场景分析:如何实现软硬一体的视频上云整体解决方案

    背景分析 在于众多的客户交流中,经常会被客户问到,"EasyNVR到底是软件还是硬件?"."EasyNVR能否出一个硬件的版本,摆脱自建服务器的压力?".&qu ...

  9. 九度OJ 1360:乐透之猜数游戏 (递归)

    时间限制:2 秒 内存限制:32 兆 特殊判题:否 提交:955 解决:261 题目描述: 六一儿童节到了,YZ买了很多丰厚的礼品,准备奖励给JOBDU里辛劳的员工.为了增添一点趣味性,他还准备了一些 ...

  10. Introduction to Mathematical Thinking - Week 9 评论答案2

    根据 rubic 打分. 1. 我认为,如果说明 m, n 是自然数,所以最小值是 1 会更清楚.所以 Clarity 我给了 3 分.其他都是 4 分,所以一共是 23 分. 2.  我给出的分数 ...