tips-dan-trik

Menghubungkan Golang dengan Database MySQL/PostgreSQL

Golang, atau Go, telah menjadi bahasa pemrograman yang sangat populer karena kemudahan penggunaannya, performa tinggi, dan dukungan kuat dari komunitas. Salah satu aspek penting dalam pengembangan aplikasi adalah kemampuan untuk berinteraksi dengan database. Dalam artikel ini, kita akan membahas cara menghubungkan aplikasi Golang dengan dua database populer, yaitu MySQL dan PostgreSQL. Dengan pemahaman ini, Anda dapat membangun aplikasi yang lebih dinamis dan kaya fitur. Kami juga akan menunjukkan bagaimana melakukan operasi dasar seperti membuat, membaca, memperbarui, dan menghapus (CRUD) data dalam database. Untuk tutorial yang lebih mendetail, Anda dapat merujuk ke tutorial Golang database.

1. Persiapan Lingkungan

Sebelum memulai, pastikan Golang sudah terinstal di sistem Anda. Jika belum, Anda dapat mengunduh dan menginstalnya dari situs resmi Golang. Selain itu, pastikan Anda telah menginstal MySQL dan/atau PostgreSQL di sistem Anda. Jika belum, Anda dapat mengikuti petunjuk instalasi dari situs resmi masing-masing database.

2. Instalasi dan Konfigurasi Library

Untuk menghubungkan Golang dengan MySQL dan PostgreSQL, kita membutuhkan library khusus. Gunakan perintah berikut untuk menginstal library yang diperlukan:

Untuk MySQL:

go get -u github.com/go-sql-driver/mysql

Untuk PostgreSQL:

go get -u github.com/lib/pq

3. Membuat Struktur Proyek

Buat struktur direktori untuk proyek Anda:

database-connection/
├── main.go
├── config/
│   └── config.go
├── models/
│   └── user.go
├── repositories/
│   └── userRepository.go
├── services/
│   └── userService.go

4. Konfigurasi Database

Buat file config/config.go untuk mengatur konfigurasi koneksi database:

package config

import (
    "database/sql"
    "log"

    _ "github.com/go-sql-driver/mysql"
    _ "github.com/lib/pq"
)

func ConnectMySQL() (*sql.DB, error) {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname"
    db, err := sql.Open("mysql", dsn)
    if err != nil {
        log.Fatal(err)
        return nil, err
    }
    if err := db.Ping(); err != nil {
        log.Fatal(err)
        return nil, err
    }
    return db, nil
}

func ConnectPostgreSQL() (*sql.DB, error) {
    dsn := "postgres://user:password@localhost/dbname?sslmode=disable"
    db, err := sql.Open("postgres", dsn)
    if err != nil {
        log.Fatal(err)
        return nil, err
    }
    if err := db.Ping(); err != nil {
        log.Fatal(err)
        return nil, err
    }
    return db, nil
}

5. Membuat Model User

Buat file models/user.go untuk mendefinisikan model data pengguna:

package models

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

6. Membuat Repository User

Repository bertanggung jawab untuk berinteraksi dengan database. Buat file repositories/userRepository.go:

package repositories

import (
    "database/sql"
    "webapp/models"
)

type UserRepository struct {
    DB *sql.DB
}

func NewUserRepository(db *sql.DB) *UserRepository {
    return &UserRepository{DB: db}
}

func (r *UserRepository) CreateUser(user models.User) error {
    _, err := r.DB.Exec("INSERT INTO users (name, email) VALUES (?, ?)", user.Name, user.Email)
    return err
}

func (r *UserRepository) GetAllUsers() ([]models.User, error) {
    rows, err := r.DB.Query("SELECT id, name, email FROM users")
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    users := []models.User{}
    for rows.Next() {
        var user models.User
        err := rows.Scan(&user.ID, &user.Name, &user.Email)
        if err != nil {
            return nil, err
        }
        users = append(users, user)
    }
    return users, nil
}

func (r *UserRepository) GetUserByID(id int) (models.User, error) {
    var user models.User
    err := r.DB.QueryRow("SELECT id, name, email FROM users WHERE id = ?", id).Scan(&user.ID, &user.Name, &user.Email)
    return user, err
}

func (r *UserRepository) UpdateUser(user models.User) error {
    _, err := r.DB.Exec("UPDATE users SET name = ?, email = ? WHERE id = ?", user.Name, user.Email, user.ID)
    return err
}

func (r *UserRepository) DeleteUser(id int) error {
    _, err := r.DB.Exec("DELETE FROM users WHERE id = ?", id)
    return err
}

7. Membuat Service User

Service mengandung logika bisnis aplikasi Anda. Buat file services/userService.go:

package services

import (
    "webapp/models"
    "webapp/repositories"
)

type UserService struct {
    Repo *repositories.UserRepository
}

func NewUserService(repo *repositories.UserRepository) *UserService {
    return &UserService{Repo: repo}
}

func (s *UserService) CreateUser(user models.User) error {
    return s.Repo.CreateUser(user)
}

func (s *UserService) GetAllUsers() ([]models.User, error) {
    return s.Repo.GetAllUsers()
}

func (s *UserService) GetUserByID(id int) (models.User, error) {
    return s.Repo.GetUserByID(id)
}

func (s *UserService) UpdateUser(user models.User) error {
    return s.Repo.UpdateUser(user)
}

func (s *UserService) DeleteUser(id int) error {
    return s.Repo.DeleteUser(id)
}

8. Membuat Fungsi Utama

Terakhir, buat file main.go untuk menjalankan aplikasi:

package main

import (
    "database/sql"
    "log"
    "net/http"
    "webapp/config"
    "webapp/models"
    "webapp/repositories"
    "webapp/services"

    "github.com/gin-gonic/gin"
)

func main() {
    // Pilih koneksi database: MySQL atau PostgreSQL
    db, err := config.ConnectMySQL()
    // db, err := config.ConnectPostgreSQL()
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    userRepo := repositories.NewUserRepository(db)
    userService := services.NewUserService(userRepo)

    router := gin.Default()

    router.POST("/users", func(c *gin.Context) {
        var user models.User
        if err := c.ShouldBindJSON(&user); err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        if err := userService.CreateUser(user); err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
            return
        }
        c.JSON(http.StatusOK, user)
    })

    router.GET("/users", func(c *gin.Context) {
        users, err := userService.GetAllUsers()
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
            return
        }
        c.JSON(http.StatusOK, users)
    })

    router.GET("/users/:id", func(c *gin.Context) {
        id, err := strconv.Atoi(c.Param("id"))
        if err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
            return
        }
        user, err := userService.GetUserByID(id)
        if err != nil {
            c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
            return
        }
        c.JSON(http.StatusOK, user)
    })

    router.PUT("/users/:id", func(c *gin.Context) {
        id, err := strconv.Atoi(c.Param("id"))
        if err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
            return
        }
        var user models.User
        if err := c.ShouldBindJSON(&user); err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        user.ID = id
        if err := userService.UpdateUser(user); err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
            return
        }
        c.JSON(http.StatusOK, user)
    })

    router.DELETE("/users/:id", func(c *gin.Context) {
        id, err := strconv.Atoi(c.Param("id"))
        if err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
            return
        }
       

 if err := userService.DeleteUser(id); err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
            return
        }
        c.JSON(http.StatusOK, gin.H{"message": "User deleted"})
    })

    router.Run(":8080")
}

Kesimpulan

Dalam artikel ini, kita telah membahas cara menghubungkan Golang dengan database MySQL dan PostgreSQL. Dengan mengikuti langkah-langkah di atas, Anda dapat membangun aplikasi yang dapat berinteraksi dengan database untuk melakukan operasi CRUD dasar. Koneksi database yang efisien sangat penting untuk aplikasi yang membutuhkan penyimpanan dan pengambilan data yang cepat. Untuk tutorial yang lebih mendalam, Anda dapat merujuk ke tutorial Golang database untuk mendapatkan pemahaman yang lebih lengkap. Semoga artikel ini membantu Anda dalam mengembangkan aplikasi Golang yang terintegrasi dengan baik dengan database. Selamat mencoba dan selamat berkoding!

comments powered by Disqus