Connecting to Databases and Writing Queries in Go
Connecting to Databases and Writing Queries in Go
Go (or Golang) is a powerful, statically typed language widely used for building scalable applications. In this tutorial, we’ll cover how to connect to three popular databases—PostgreSQL, SQLite, and MySQL—using Go, along with examples of basic queries.
1. Setting Up Your Go Project
Before working with databases, ensure you have Go installed. You can create a new project with the following commands:
mkdir go-database-tutorialcd go-database-tutorialgo mod init go-database-tutorial
To interact with databases, we’ll use the database/sql
package along with specific drivers for each database:
- PostgreSQL:
github.com/lib/pq
- SQLite:
modernc.org/sqlite
- MySQL:
github.com/go-sql-driver/mysql
Install the relevant drivers for your database:
go get github.com/lib/pq# For SQLitego get modernc.org/sqlite# For MySQLgo get github.com/go-sql-driver/mysql
2. Connecting to Databases
PostgreSQL Connection
package main
import ( "database/sql" "fmt" "log" _ "github.com/lib/pq")
func main() { connStr := "user=username password=yourpassword dbname=yourdb sslmode=disable" db, err := sql.Open("postgres", connStr) if err != nil { log.Fatal(err) } defer db.Close()
fmt.Println("Connected to PostgreSQL successfully!")}
SQLite Connection
package main
import ( "database/sql" "fmt" "log" _ "modernc.org/sqlite")
func main() { db, err := sql.Open("sqlite", "file:test.db?cache=shared&mode=rwc") if err != nil { log.Fatal(err) } defer db.Close()
fmt.Println("Connected to SQLite successfully!")}
MySQL Connection
package main
import ( "database/sql" "fmt" "log" _ "github.com/go-sql-driver/mysql")
func main() { connStr := "username:password@tcp(127.0.0.1:3306)/yourdb" db, err := sql.Open("mysql", connStr) if err != nil { log.Fatal(err) } defer db.Close()
fmt.Println("Connected to MySQL successfully!")}
3. Writing Basic Queries
Creating a Table
For all databases, we can use the Exec
method to execute SQL statements such as creating tables.
Example (for PostgreSQL, SQLite, or MySQL):
query := `CREATE TABLE IF NOT EXISTS posts ( id SERIAL PRIMARY KEY, title VARCHAR(255), content TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)`
_, err := db.Exec(query)if err != nil { log.Fatalf("Error creating table: %v", err)}fmt.Println("Table created successfully!")
Inserting Data
query := `INSERT INTO posts (title, content) VALUES ($1, $2)`// Use ? instead of $1, $2 for MySQL and SQLite_, err := db.Exec(query, "My First Post", "This is the content of my first post.")if err != nil { log.Fatalf("Error inserting data: %v", err)}fmt.Println("Data inserted successfully!")
Fetching Data
rows, err := db.Query("SELECT id, title, content FROM posts")if err != nil { log.Fatalf("Error fetching data: %v", err)}defer rows.Close()
for rows.Next() { var id int var title, content string if err := rows.Scan(&id, &title, &content); err != nil { log.Fatalf("Error scanning row: %v", err) } fmt.Printf("ID: %d, Title: %s, Content: %s\n", id, title, content)}
Updating Data
query := `UPDATE posts SET content = $1 WHERE id = $2`// Use ? for MySQL and SQLite_, err := db.Exec(query, "Updated content", 1)if err != nil { log.Fatalf("Error updating data: %v", err)}fmt.Println("Data updated successfully!")
Deleting Data
query := `DELETE FROM posts WHERE id = $1`// Use ? for MySQL and SQLite_, err := db.Exec(query, 1)if err != nil { log.Fatalf("Error deleting data: %v", err)}fmt.Println("Data deleted successfully!")
converting data to slice
you can fetch data and convert it to slice and send it or work with the data
type Note struct{ Id string Title string Text string}getNotes:=func (w http.ResponseWriter, r *http.Request) {row,_ := db.Query("SELECT id, title, text FROM notes")defer row.Close()
var notes []Note // we make a slice of Notes and each note is a structfor row.Next() { // we can use the next function to itrate over all the rows inside the qurey var note Note row.Scan(¬e.Id,¬e.Title, ¬e.Text) // with the scan function we add all the data to each note inside the slice notes = append(notes, note) // we append each note to the note slice}html, _ := template.ParseFiles("index.html")html.Execute(w,notes)
}
4. Wrapping Up
You’ve now learned how to connect to PostgreSQL, SQLite, and MySQL databases and execute basic SQL queries using Go. To make your applications production-ready, consider the following best practices:
- Use connection pooling libraries like
github.com/jmoiron/sqlx
orgithub.com/golang-migrate/migrate
for advanced database management. - Sanitize inputs to prevent SQL injection.
- Use environment variables or a configuration file to manage database credentials.
With these fundamentals, you can start building Go applications that interact with databases efficiently!