在Web开发中,我们经常需要将数据存储到数据库中以便进行管理和处理。gosqlite3是一个轻量级的sqlite3驱动,它为Golang提供了快速、稳定的sqlite3支持。在本篇文章中,我们将从以下几个方面对gosqlite3进行详细阐述:
1. 安装gosqlite3
2. 基本使用
3. 数据库连接及操作
4. 执行事务
5. 并发使用
一、安装gosqlite3
在进行gosqlite3的使用前,我们需要先进行安装。
步骤1:安装sqlite3
sudo apt-get install sqlite3
步骤2:安装gosqlite3
go get github.com/mattn/go-sqlite3
安装完成后,我们就可以开始使用gosqlite3进行开发了。
二、基本使用
下面是一个简单的例子,演示了如何使用gosqlite3进行数据库的连接和操作:
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
func main() {
db, err := sql.Open("sqlite3", "test.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
sqlStmt := `
create table foo (id integer not null primary key, name text);
delete from foo;
`
_, err = db.Exec(sqlStmt)
if err != nil {
log.Printf("%q: %s\n", err, sqlStmt)
return
}
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
stmt, err := tx.Prepare("insert into foo(id, name) values(?, ?)")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
for i := 0; i < 100; i++ {
_, err = stmt.Exec(i, fmt.Sprintf("こんにちわ世界%03d", i))
if err != nil {
log.Fatal(err)
}
}
tx.Commit()
rows, err := db.Query("select id, name from foo")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
log.Println(id, name)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
这段代码首先创建了一个名为test.db的sqlite3数据库。然后,它创建了一个名为foo的表,插入了100条记录并输出了表中的所以记录。在这个例子中,我们看到了gosqlite3的基本数据类型支持和如何执行SQL语句。
三、数据库连接及操作
对于一个应用程序来说,连接数据库是一个非常关键的步骤。在gosqlite3中,我们可以使用Open方法来连接数据库。数据库连接器会在使用完毕后自动关闭。此外,在进行查询或修改时,还需要使用Transaction。下面的代码演示了如何进行数据库查询和修改:
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
func main() {
db, _ := sql.Open("sqlite3", "./test.db")
defer db.Close()
// 查询数据
rows, _ := db.Query("select id, name from people")
defer rows.Close()
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
fmt.Printf("id=%d, name='%s'\n", id, name)
}
// 插入数据
stmt, _ := db.Prepare("insert into people(name) values(?)")
defer stmt.Close()
res, _ := stmt.Exec("Tom")
id, _ := res.LastInsertId()
fmt.Printf("ID of inserted row is %d\n", id)
// 删除数据
stmt, _ = db.Prepare("delete from people where name=?")
defer stmt.Close()
res, _ = stmt.Exec("Tom")
num, _ := res.RowsAffected()
fmt.Printf("%d row(s) deleted\n", num)
}
四、执行事务
在gosqlite3中执行事务非常简单。通过调用Begin方法,我们可以开启一个事务。在事务中,执行的所有SQL语句都将作为一个整体来进行提交或回滚。下面的代码演示了如何使用事务:
package main
import (
"database/sql"
"log"
_ "github.com/mattn/go-sqlite3"
)
func main() {
db, _ := sql.Open("sqlite3", "./test.db")
defer db.Close()
tx, _ := db.Begin()
stmt, _ := tx.Prepare("insert into people(name) values(?)")
defer stmt.Close()
for i := 0; i < 10; i++ {
_, err := stmt.Exec(fmt.Sprintf("user-%d", i))
if err != nil {
log.Fatal(err)
}
}
tx.Commit()
rows, _ := db.Query("select id, name from people")
defer rows.Close()
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
log.Println(id, name)
}
}
五、并发使用
在Web应用中,我们经常需要在多个Goroutine中同时进行数据库操作。gosqlite3的设计支持并发使用。但是,需要注意的是:不要在多个线程中共享同一个*sql.DB对象,否则会导致不可预期的问题。下面的代码演示了如何在多个Goroutine中同时使用gosqlite3:
package main
import (
"database/sql"
"fmt"
"log"
"sync"
_ "github.com/mattn/go-sqlite3"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done()
db, _ := sql.Open("sqlite3", "./test.db")
tx, _ := db.Begin()
stmt, _ := tx.Prepare("insert into people(name) values(?)")
for i := 0; i < 10; i++ {
stmt.Exec(fmt.Sprintf("user-%d-%d", id, i))
}
stmt.Close()
tx.Commit()
rows, _ := db.Query("select count(*) from people")
defer rows.Close()
var count int
rows.Next()
rows.Scan(&count)
log.Printf("worker%d count=%d", id, count)
db.Close()
}
func main() {
db, _ := sql.Open("sqlite3", "./test.db")
db.Exec("create table if not exists people(id integer primary key, name text)")
var wg sync.WaitGroup
for i := 1; i <= 10; i++ {
wg.Add(1)
go worker(i, &wg)
}
wg.Wait()
}
在这个例子中,我们分别创建了10个Goroutine去并发地插入数据到表people中。在主函数中,我们使用sync.WaitGroup来等待所有的Goroutine执行完毕。最后,我们查询表people中的记录数并输出。