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. WPF数据模板样式选择器

    在使用数据模板样式选择器时,不能设置ItemContainerStyle的属性值,如果设置了该值,那么数据模板样式选择器会失去作用. 在使用数据模板样式选择器时,首先要创建数据模板样式选择器对象,此对 ...

  2. android-support-v7使用

    前言:android-support-v7与v4相对,还是有很大不同的,首先v7中分为的3个JAR包,其次v7中提供的一些布局资源,所以在使用的时候,需要将v7的源码项目导入,作为lib项目来添加到你 ...

  3. 绝对定位position: absolute;

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 回溯法——最大团问题(Maximum Clique Problem, MCP)

    概述: 最大团问题(Maximum Clique Problem, MCP)是图论中一个经典的组合优化问题,也是一类NP完全问题.最大团问题又称为最大独立集问题(Maximum Independent ...

  5. T-SQL Table-valued Function使用分隔符将字符串转换为表

    )=' ') RETURNS @Strings TABLE ( ITEM_VALUE VARCHAR(MAX) ) AS BEGIN DECLARE @index INT ) BEGIN SET @i ...

  6. 《从零开始学Swift》学习笔记(Day 49)——扩展声明

    原创文章,欢迎转载.转载请注明:关东升的博客 声明扩展的语法格式如下: extension 类型名 { //添加新功能 } 声明扩展的关键字是extension,“类型名”是Swift中已有的类型,包 ...

  7. Exponentiation(高精度大数)

    Exponentiation Description Problems involving the computation of exact values of very large magnitud ...

  8. coursera 《现代操作系统》 -- 第五周 同步机制(2)

    分清紧急等待队列与条件等待队列(c 链) 条件等待队列:但是进入管程的这个进程可能由于对资源的操作的过程中发现条件不成熟, 那么它就不能够继续对资源进行相应的操作. 我们以生产者. 消费者为例. 如果 ...

  9. 原文来自 url get

    w http://www.tuicool.com/articles/BvYbEvR http://36kr.com/p/5069371.html?utm_source=tuicool&utm_ ...

  10. <2013 08 12> Andrew:C语言的一点心得

    C语言的特点在于,这是少见的中级语言(介于机器汇编和高级语言之间),因此它极其紧密地与特定机器架构.编译器.操作系统.库等基本概念相连.在底层,人们可以少量的甚至不使用汇编,但是不能不使用C.它以一种 ...