Skip to content

MySQL

MySQL 는 현재 가장 인기 있는 오픈소스 관계형 데이터베이스로, 구체적인 sql 지식은 여기서 많이 설명하지 않겠습니다. sql 을 모른다면 먼저 직접 학습하시기 바랍니다. 이 문서에서는 go 를 사용하여 sql 을 조작하는 방법을 간단히 설명합니다. 실제 프로젝트에서는 일반적으로 드라이버를 직접 사용하여 데이터베이스를 조작하지 않고 ORM 프레임워크를 사용합니다. 여기서는 sqlx 라이브러리를 사용하며, 이는 표준 sql 라이브러리를 강화한 것으로 ORM 기능이 그렇게 풍부하지는 않지만 간결하다는 장점이 있습니다. ORM 을 사용하고 싶다면 Gorm, Xorm, Ent 등의 라이브러리를 알아보세요.

의존성

sqlx 라이브러리를 다운로드합니다.

bash
$ go get github.com/jmoiron/sqlx

sqlx 또는 표준 라이브러리 database/sql이 지원하는 데이터베이스는 MySQL 뿐만 아닙니다. driver.Driver 인터페이스를 구현한 모든 유형은 지원됩니다. 예를 들어:

  • PostgreSQL
  • Oracle
  • MariaDB
  • SQLite
  • 기타 관계형 데이터베이스

해당 데이터베이스를 사용하려면 데이터베이스 드라이버를 구현해야 하며, 드라이버는 직접 작성한 것이거나 서드파티 라이브러리일 수 있습니다. 사용하기 전에 sql.Register를 사용하여 드라이버를 등록한 후 사용할 수 있습니다. 하지만 일반적으로 다운로드한 드라이버 라이브러리는 자동으로 드라이버를 등록하므로 수동으로 등록할 필요가 없습니다.

go
func Register(name string, driver driver.Driver)

MySQL 는 인기가 많고 가장 간단하므로 이 문서에서는 MySQL 를 사용하여 설명하며, 다른 관계형 데이터베이스도 조작 방법이 크게 다르지 않습니다. MySQL 드라이버 라이브러리를 다운로드합니다.

bash
$ go get github.com/go-sql-driver/mysql

데이터베이스 연결

sqlx.Open 함수를 통해 데이터베이스 연결을 열 수 있으며, 두 개의 매개변수를 받습니다. 첫 번째는 드라이버 이름이고 두 번째는 데이터 소스 (일반적으로 DSN 이라고 함) 입니다.

go
func Open(driverName, dataSourceName string) (*DB, error)

드라이버 이름은 등록 드라이버 시 사용한 이름과 일치해야 하며, DSN 은 데이터베이스 연결 주소로 각 데이터베이스마다 다를 수 있습니다. MySQL 의 경우 다음과 같습니다.

go
db,err := sqlx.Open("mysql","root:123456@tcp(127.0.0.1:3306)/test")

데이터 준비

sql
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `age` tinyint(0) NULL DEFAULT NULL,
  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('12132', '张三', 35, '北京市');
INSERT INTO `user` VALUES ('16162', '王五', 22, '上海市');

SET FOREIGN_KEY_CHECKS = 1;

조회

조회 후 결과를 구조체에 매핑합니다.

go
var db *sqlx.DB

type Person struct {
   UserId   string `db:"id"`
   Username string `db:"name"`
   Age      int    `db:"age"`
   Address  string `db:"address"`
}

func init() {
    conn, err := sqlx.Open("mysql", "root:wyh246859@tcp(127.0.0.1:3306)/test")
   if err != nil {
      fmt.Println("Open mysql failed", err)
      return
   }

   db = conn
}

func main() {
   query()
   defer db.Close()
}

func query() {
   var person Person
   //하나 조회는 Get, 여러 개 조회는 Select
   err := db.Get(&person, "select * from user where id = ?", "12132")
   if err != nil {
      fmt.Println("query failed:", err)
      return
   }
   fmt.Printf("query succ:%+v", person)
}

func list() {
  var perons []Person
  err := db.Select(&perons, "select * from user")
  if err != nil {
    fmt.Println("list err", err)
    return
  }
  fmt.Printf("list succ,%+v", perons)
}

추가

데이터를 추가합니다.

go
func insert() {
   result, err := db.Exec("insert into user value (?,?,?,?)", "120230", "李四", 12, "广州市")
   if err != nil {
      fmt.Println("insert err:", err)
      return
   }
   id, err := result.LastInsertId()
   if err != nil {
      fmt.Println("insert err:", err)
      return
   }
   fmt.Println("insert succ:", id)
}

업데이트

데이터를 업데이트합니다.

go
func update() {
   res, err := db.Exec("update user set name = ? where id = ?", "赵六", "120230")
   if err != nil {
      fmt.Println("update err:", err)
      return
   }
   eff, err := res.RowsAffected()
   if err != nil || eff == 0 {
      fmt.Println("update err:", err)
      return
   }
   fmt.Println("Update succ")
}

삭제

데이터를 삭제합니다.

go
func delete() {
   res, err := db.Exec("delete from user where id = ?", "120230")
   if err != nil {
      fmt.Println("delete err:", err)
      return
   }
   eff, err := res.RowsAffected()
   if err != nil || eff == 0 {
      fmt.Println("delete err:", err)
      return
   }
   fmt.Println("delete succ")
}

트랜잭션

go
func (db *DB) Begin() (*Tx, error) //트랜잭션 시작
func (tx *Tx) Commit() error //트랜잭션 커밋
func (tx *Tx) Rollback() error //트랜잭션 롤백

트랜잭션을 시작한 후 안전을 위해 일반적으로 defer tx.Rollback()을 추가합니다. 과정 중 오류가 발생하면 롤백되며, 트랜잭션이 성공적으로 커밋되면 이 롤백은 무효가 됩니다.

go
func main() {

  transation, err := db.Begin()
  if err != nil {
    fmt.Println("transation err")
  }
    defer transation.Rollback()

  insert()
  query()
  update()
  query()
  delete()
   transation.Commit()
}

Golang by www.golangdev.cn edit