Skip to content

Commit 5212b55

Browse files
committed
chore: menambahkan materi database sql
`database/sql` adalah interface generic untuk bekerja dengan database yang bersifat relasional di golang. Ini bukan driver database itu sendiri, melainkan sebuah standard interface yang bisa digunakan dengan driver-driver spesifik database. close #21 Signed-off-by: slowy07 <[email protected]>
1 parent 4eefb94 commit 5212b55

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed

utilities/database_sql/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## database/sql
2+
3+
`database/sql` adalah interface generic untuk bekerja dengan database yang bersifat relasional di golang. Ini bukan driver database itu sendiri, melainkan sebuah standard interface yang bisa digunakan dengan driver-driver spesifik database.
4+
5+
## Arsitektur sederhana
6+
7+
```
8+
+-----------------+
9+
| Aplikasi |
10+
| Go App |
11+
+--------+--------+
12+
|
13+
| SQL Query
14+
v
15+
+--------+--------+
16+
| database/sql | <== abstraction layer
17+
+--------+--------+
18+
|
19+
+------------+---------------+
20+
| |
21+
+-------------v----+ +------v-------+
22+
| Driver MySQL | | Driver PG |
23+
+-------------------+ +--------------+
24+
```
25+
- kita tidak perlu lagi menulis ulang logika koneksi, pooling, query.
26+
- kode kita bisa berjalan di berbagai jenis database selama ada drivernya.
27+
- dan manajemen koneksi yang aman efisien.
28+
- serta mendukung prepared statement untuk mencegah terjadinya SQL injection
29+
30+
## Yang harus diperhatikan
31+
32+
Ketika bekerja dengan sql statement dan database, usahakan untuk
33+
- gunakana prepared statement untuk menghindari terjadinya SQL injection.
34+
- jangan lupa `defer baris.Close()` / `defer row.Close()` saat menggunakan query.
35+
- logging error secara rinci untuk debug di environment production
36+
37+
untuk contohnya bisa lihat filenya [disini](databaseSql.go)
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package databasesql
2+
3+
import (
4+
"database/sql"
5+
"fmt"
6+
"log"
7+
)
8+
9+
type User struct {
10+
id int
11+
nama string
12+
email string
13+
}
14+
15+
func buatTabel(db *sql.DB) {
16+
queryDatabaseTabel := `
17+
CREATE TABLE IF NOT EXISTS users (
18+
id INT AUTO_INCREMENT PRIMARY KEY,
19+
nama VARCHAR(50),
20+
email VARCHAR(100)
21+
);
22+
`
23+
24+
_, err := db.Exec(queryDatabaseTabel)
25+
if err != nil {
26+
log.Fatal("error saat membuat tabel, informasi: ", err)
27+
}
28+
29+
fmt.Println("tabel `users` sudah dibuat atau sudah ada")
30+
}
31+
32+
func insertDataUser(db *sql.DB, nama, email string) {
33+
queryData := "INSERT INTO users (nama, email) VALUES (?, ?)"
34+
hasil, err := db.Exec(queryData, nama, email)
35+
if err != nil {
36+
log.Fatal("error pada saat insert data user, informasi: ", err)
37+
}
38+
39+
id, _ := hasil.LastInsertId()
40+
fmt.Printf("insert data dengan id: %d\n", id)
41+
}
42+
43+
func ambilSemuaDataUser(db *sql.DB) []User {
44+
baris, err := db.Query("SELECT id, nama, email FROM users")
45+
if err != nil {
46+
log.Fatal("error fetching data user, informasi: ", err)
47+
}
48+
49+
defer baris.Close()
50+
51+
var userData []User
52+
53+
for baris.Next() {
54+
var u User
55+
err := baris.Scan(&u.id, &u.nama, &u.email)
56+
if err != nil {
57+
log.Fatal("error scanning dari baris, informasi: ", err)
58+
}
59+
userData = append(userData, u)
60+
}
61+
return userData
62+
}
63+
64+
func updateUserEmail(db *sql.DB, id int, emailBaru string) {
65+
queryData := "UPDATE users SET email = ? WHERE id = ?"
66+
_, err := db.Exec(queryData, emailBaru, id)
67+
if err != nil {
68+
log.Fatal("error update user, informasi: ", err)
69+
}
70+
fmt.Printf("update email untuk user id %d\n", id)
71+
}
72+
73+
func deleteUser(db *sql.DB, id int) {
74+
query := "DELETE FROM users WHERE id = ?"
75+
_, err := db.Exec(query, id)
76+
if err != nil {
77+
log.Fatal("error delete data user, informasi: ", err)
78+
}
79+
fmt.Printf("menghapus data user dengan id: %d\n", id)
80+
}
81+
82+
func main() {
83+
// format data source name atau DSN
84+
db, err := sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/testdb")
85+
if err != nil {
86+
log.Fatal("error waktu buka database, informasi: ", err)
87+
}
88+
89+
defer db.Close()
90+
91+
// ping database untuk pastikan koneksi berhasil
92+
err = db.Ping()
93+
if err != nil {
94+
log.Fatal("database ada masalah, informasi: ", err)
95+
}
96+
fmt.Println("koneksi ke database berjalan dengan baik")
97+
98+
// membuat tabel jika tidak ada
99+
buatTabel(db)
100+
insertDataUser(db, "Mamad", "[email protected]")
101+
insertDataUser(db, "hiruzen", "[email protected]")
102+
103+
// ambil semua data user dan tampilin
104+
userData := ambilSemuaDataUser(db)
105+
for _, user := range userData {
106+
fmt.Printf("ID: %d, Nama: %s, Email: %s\n", user.id, user.nama, user.email)
107+
}
108+
109+
// update data user
110+
updateUserEmail(db, 1, "[email protected]")
111+
// delete data user
112+
deleteUser(db, 2)
113+
}

0 commit comments

Comments
 (0)