Skip to content

Database

GoIgniter menyediakan library database yang ringan dan mudah digunakan. Mendukung SQLite dan MySQL, dengan API yang familiar bagi pengguna CI3.

DriverLibraryCGO Required
SQLitemodernc.org/sqliteTidak (Pure Go)
MySQLgithub.com/go-sql-driver/mysqlTidak

SQLite adalah pilihan paling mudah untuk development karena tidak perlu setup server database.

package main
import (
"log"
"goigniter/system/libraries/database"
_ "goigniter/system/libraries/database/drivers" // Register semua drivers
)
func main() {
// Buka koneksi SQLite
db, err := database.Open("sqlite", "./app.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Set sebagai default (opsional, untuk akses global)
database.SetDefault(db)
}

File app.db akan otomatis dibuat jika belum ada.

Untuk production, MySQL adalah pilihan yang lebih umum.

package main
import (
"log"
"goigniter/system/libraries/database"
_ "goigniter/system/libraries/database/drivers"
)
func main() {
// Format DSN: user:password@tcp(host:port)/database?parseTime=true
dsn := "root:password@tcp(localhost:3306)/myapp?parseTime=true"
db, err := database.Open("mysql", dsn)
if err != nil {
log.Fatal(err)
}
defer db.Close()
database.SetDefault(db)
}

Best practice: jangan hardcode credential database.

import "os"
func main() {
driver := os.Getenv("DB_DRIVER") // "sqlite" atau "mysql"
dsn := os.Getenv("DB_DSN")
if driver == "" {
driver = "sqlite"
dsn = "./app.db"
}
db, err := database.Open(driver, dsn)
if err != nil {
log.Fatal(err)
}
defer db.Close()
}

File .env:

Terminal window
# Development (SQLite)
DB_DRIVER=sqlite
DB_DSN=./app.db
# Production (MySQL)
DB_DRIVER=mysql
DB_DSN=user:password@tcp(localhost:3306)/myapp?parseTime=true

Untuk query SQL langsung, gunakan method Query() dan Exec().

// Query dengan parameter (prepared statement)
var users []User
db.Query("SELECT * FROM users WHERE status = ?", "active").Get(&users)
// Query ke map (tanpa struct)
results, err := db.Query("SELECT * FROM users").GetMap()
for _, row := range results {
fmt.Println(row["name"], row["email"])
}
// Insert
result, err := db.Exec(
"INSERT INTO users (name, email) VALUES (?, ?)",
"John Doe", "[email protected]",
)
if err != nil {
log.Fatal(err)
}
lastId, _ := result.LastInsertId()
fmt.Println("New user ID:", lastId)
// Update
result, err = db.Exec(
"UPDATE users SET status = ? WHERE id = ?",
"inactive", 5,
)
affected, _ := result.RowsAffected()
fmt.Println("Rows updated:", affected)
// Delete
db.Exec("DELETE FROM users WHERE status = ?", "deleted")

Selalu gunakan placeholder ? untuk parameter, jangan concatenate string langsung. Ini mencegah SQL injection.

// BENAR - aman dari SQL injection
db.Query("SELECT * FROM users WHERE email = ?", userInput)
// SALAH - rentan SQL injection!
db.Query("SELECT * FROM users WHERE email = '" + userInput + "'")

Gunakan Exec() untuk DDL (CREATE, ALTER, DROP).

// SQLite
db.Exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
status TEXT DEFAULT 'active',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`)
// MySQL
db.Exec(`
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
status VARCHAR(50) DEFAULT 'active',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`)

Setelah memanggil database.SetDefault(db), kamu bisa akses database dari mana saja:

// Di controller atau file lain
import "goigniter/system/libraries/database"
func ListUsers(c *core.Context) error {
db := database.Default()
var users []User
db.Query("SELECT * FROM users").Get(&users)
return c.JSON(200, users)
}

Untuk cara yang lebih mudah dan type-safe, lihat Query Builder di halaman berikutnya.