引言:为什么Go和数据库是完美搭档
\nGo(Golang)是由Google开发的现代编译型语言。其主要优势在于高性能、简洁性以及内置的并发支持。在数据库操作方面,Go为各种数据库管理系统提供了强大的标准库和流行的第三方驱动。
\n本文将详细讲解如何连接并执行两种最流行数据库的基本操作:关系型数据库PostgreSQL和文档型数据库MongoDB。本教程面向已掌握Go基础语法的初学者开发者。
\n\n1. 环境准备与驱动安装
\n在编写代码之前,请确保已安装Go(1.21+版本)。我们需要安装数据库驱动,使用以下命令:
\ngo get github.com/lib/pq // 用于PostgreSQL\ngo get go.mongodb.org/mongo-driver // 用于MongoDB\n同时确保您的机器上已启动相应的数据库服务器(本地或通过Docker)。
\n\n1.1. 项目结构
\n创建文件main.go。为简单起见,所有逻辑将集中在此文件中。在实际项目中,应将代码拆分为不同的包。
2. Go中的PostgreSQL操作
\nPostgreSQL是一款强大的关系型数据库管理系统。在Go中,我们使用database/sql包和lib/pq驱动进行操作。
2.1. 连接数据库
\n创建一个连接函数。连接字符串(DSN)包含主机、端口、用户名和数据库名称。
\npackage main\n\nimport (\n "database/sql"\n "fmt"\n "log"\n\n _ "github.com/lib/pq"\n)\n\nfunc main() {\n connStr := "host=localhost port=5432 user=postgres password=secret dbname=testdb sslmode=disable"\n db, err := sql.Open("postgres", connStr)\n if err != nil {\n log.Fatal("连接错误:", err)\n }\n defer db.Close()\n\n // 检查连接\n err = db.Ping()\n if err != nil {\n log.Fatal("无法建立连接:", err)\n }\n fmt.Println("成功连接到PostgreSQL!")\n}\n重要提示:sql.Open并不创建实际连接,仅创建连接池。实际连接在首次请求或调用Ping()时建立。
2.2. 创建表与插入数据
\n现在创建users表并添加几条记录。
// 创建表\ncreateTable := `\nCREATE TABLE IF NOT EXISTS users (\n id SERIAL PRIMARY KEY,\n name VARCHAR(100) NOT NULL,\n email VARCHAR(100) UNIQUE NOT NULL,\n age INT\n);`\n_, err = db.Exec(createTable)\nif err != nil {\n log.Fatal("创建表错误:", err)\n}\n\n// 插入数据\ninsert := `INSERT INTO users (name, email, age) VALUES ($1, $2, $3)`\n_, err = db.Exec(insert, "伊万·彼得罗夫", "ivan@example.com", 30)\nif err != nil {\n log.Fatal("插入错误:", err)\n}\nfmt.Println("数据已添加")\n注意使用占位符$1、$2——这是防止SQL注入的有效方式。
2.3. 读取与更新数据
\n执行查询并更新用户年龄。
\n// 读取数据\nrows, err := db.Query("SELECT id, name, email, age FROM users")\nif err != nil {\n log.Fatal(err)\n}\ndefer rows.Close()\n\nfor rows.Next() {\n var id int\n var name, email string\n var age int\n err := rows.Scan(&id, &name, &email, &age)\n if err != nil {\n log.Fatal(err)\n }\n fmt.Printf("ID: %d, 姓名: %s, 邮箱: %s, 年龄: %d\\n", id, name, email, age)\n}\n\n// 更新\n_, err = db.Exec("UPDATE users SET age = $1 WHERE name = $2", 31, "伊万·彼得罗夫")\nif err != nil {\n log.Fatal(err)\n}\nfmt.Println("年龄已更新")\n\n