go项目实现mysql接入以及web api

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: go项目实现mysql接入以及web api

本文为博主原创,转载请注明出处:

  创建go项目,并在go项目中接入mysql,将mysql的配置项单独整理放到一个胚子和文件中,支持项目启动时,通过加载配置文件中的值,然后创建数据库连接。

  之后使用net/http相关的库,创建路由,并在路由中通过不同的http方法,实现mysql连接的test数据库中users表的增删改查 的 web api

1.在idea中创建go项目

  其目录文件结构如下

                                    

2.创建配置文件,并初始化数据库

  在项目的根目录下创建数据库的配置文件:config.json

{
    "host": "192.168.118.46",
    "port": 3306,
    "user": "root",
    "password": "root",
    "dbname": "terra_no"
}

  创建数据库以及表,并插入数据

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(12) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `age` int(12) DEFAULT '18',
  PRIMARY KEY (`id`)
); 
insert into users value (1,"aa",12);
insert into users value (2,"bb",22);

3.创建加载mysql,并创建数据库连接的类

  在项目的根目录下创建database目录,之后创建 mysql.go 文件

package database
import (
    "database/sql"
    "encoding/json"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "io/ioutil"
    "log"
)
type MySQLConfig struct {
    Host     string `json:"host"`
    Port     int    `json:"port"`
    User     string `json:"user"`
    Password string `json:"password"`
    DBName   string `json:"dbname"`
}
func NewMySQLDB() (*sql.DB, error) {
    log.Println("coming NewMySQLDB ...")
    config, err := loadMySQLConfig()
    log.Println("coming NewMySQLDB config...", config.User, config.Password)
    if err != nil {
        log.Fatal(err)
        return nil, err
    }
    log.Println("coming NewMySQLDB config...", config)
    dbSource := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", config.User, config.Password, config.Host, config.Port, config.DBName)
    log.Println("coming NewMySQLDB config dbSource is ...", dbSource)
    db, err := sql.Open("mysql", dbSource)
    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 loadMySQLConfig() (*MySQLConfig, error) {
    configFile, err := ioutil.ReadFile("config.json")
    if err != nil {
        log.Fatal("----------error-----------loadMySQLConfig err...", err)
        return nil, err
    }
    var config MySQLConfig
    err = json.Unmarshal(configFile, &config)
    log.Println("loadMySQLConfig Unmarshal err...", err)
    if err != nil {
        log.Fatal("---------error----------------loadMySQLConfig Unmarshal err...", config)
        return nil, err
    }
    return &config, nil
}

 

4.创建数据库实体类 user 以及项目所需实体类 ErrorResponse

  user.go 的文件内容如下:

package models
type User struct {
    ID   uint   `json:"id"`
    Name string `json:"name"`
    Age  int    `json:"age"`
}

ErrorResponse.go 中的文件内容如下:

package models
type ErrorResponse struct {
    Message string `json:"message"`
}

5.编写user表中数据库交互的逻辑

package repositories
import (
    "database/sql"
    "go_test/models"
)
type UserRepository struct {
    DB *sql.DB
}
func (ur *UserRepository) CreateUser(user *models.User) error {
    query := "INSERT INTO users (name, age) VALUES (?, ?)"
    _, err := ur.DB.Exec(query, user.Name, user.Age)
    if err != nil {
        return err
    }
    return nil
}
func (ur *UserRepository) GetUserByID(id uint) (*models.User, error) {
    query := "SELECT id, name, age FROM users WHERE id = ?"
    row := ur.DB.QueryRow(query, id)
    user := new(models.User)
    err := row.Scan(&user.ID, &user.Name, &user.Age)
    if err != nil {
        if err == sql.ErrNoRows {
            return nil, nil // 用户不存在
        }
        return nil, err
    }
    return user, nil
}
func (ur *UserRepository) GetUsers() ([]*models.User, error) {
    query := "SELECT id, name, age FROM "
    rows, err := ur.DB.Query(query)
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    users := []*models.User{}
    for rows.Next() {
        user := new(models.User)
        err := rows.Scan(&user.ID, &user.Name, &user.Age)
        if err != nil {
            return nil, err
        }
        users = append(users, user)
    }
    return users, nil
}
func (ur *UserRepository) UpdateUser(user *models.User) error {
    query := "UPDATE users SET name = ?, age = ? WHERE id = ?"
    _, err := ur.DB.Exec(query, user.Name, user.Age, user.ID)
    if err != nil {
        return err
    }
    return nil
}
func (ur *UserRepository) DeleteUser(id uint) error {
    query := "DELETE FROM users WHERE id = ?"
    _, err := ur.DB.Exec(query, id)
    if err != nil {
        return err
    }
    return nil
}

6.编写处理业务层的service

package services
import (
    "errors"
    "go_test/models"
    "go_test/repositories"
)
type UserService struct {
    UserRepository *repositories.UserRepository
}
func (us *UserService) CreateUser(user *models.User) error {
    if user.Name == "" {
        return errors.New("Name is required")
    }
    if user.Age <= 0 {
        return errors.New("Age should be greater than 0")
    }
    // ... 其他基础业务校验
    return us.UserRepository.CreateUser(user)
}
func (us *UserService) GetUserByID(id uint) (*models.User, error) {
    return us.UserRepository.GetUserByID(id)
}
func (us *UserService) GetUsers() ([]*models.User, error) {
    return us.UserRepository.GetUsers()
}
func (us *UserService) UpdateUser(user *models.User) error {
    if user.Name == "" {
        return errors.New("Name is required")
    }
    if user.Age <= 0 {
        return errors.New("Age should be greater than 0")
    }
    // ... 其他基础业务校验
    return us.UserRepository.UpdateUser(user)
}
func (us *UserService) DeleteUser(id uint) error {
    return us.UserRepository.DeleteUser(id)
}

7.编写两个项目常用的util

  error_handler.go

package utils
import (
    "encoding/json"
    "go_test/models"
    _ "log"
    "net/http"
)
//
//type ErrorResponse struct {
//    Message string `json:"message"`
//}
func HandleError(w http.ResponseWriter, statusCode int, message string) {
    errResponse := models.ErrorResponse{Message: message}
    response, _ := json.Marshal(errResponse)
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(statusCode)
    w.Write(response)
}
func ErrorHandlerString(w http.ResponseWriter, message string) {
    errResponse := models.ErrorResponse{Message: message}
    response, _ := json.Marshal(errResponse)
    w.Header().Set("Content-Type", "application/json")
    //w.WriteHeader(statusCode)
    w.Write(response)
}
func ErrorHandler(w http.ResponseWriter, err error) {
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        response := models.ErrorResponse{
            Message: err.Error(),
        }
        json.NewEncoder(w).Encode(response)
        return
    }
}

 

  json_utils.go

package utils
import (
    "encoding/json"
    "net/http"
)
func RespondJSON(w http.ResponseWriter, data interface{}, statusCode int) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(statusCode)
    json.NewEncoder(w).Encode(data)
}

 

8.编写核心类:main.go

package main
import (
    _ "database/sql"
    "encoding/json"
    "go_test/models"
    "go_test/utils"
    "log"
    "net/http"
    "go_test/database"
    "go_test/repositories"
    "go_test/services"
)
func main() {
    log.Println("coming main method ...")
    db, err := database.NewMySQLDB()
    if err != nil {
        log.Fatal(err)
    }
    userRepository := &repositories.UserRepository{
        DB: db,
    }
    userService := &services.UserService{
        UserRepository: userRepository,
    }
    http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
        switch r.Method {
        case http.MethodGet:
            users, err := userService.GetUsers()
            if err != nil {
                utils.ErrorHandler(w, err)
                return
            }
            utils.RespondJSON(w, users, http.StatusOK)
        case http.MethodPost:
            var user models.User
            err := json.NewDecoder(r.Body).Decode(&user)
            if err != nil {
                utils.ErrorHandler(w, err)
                return
            }
            err = userService.CreateUser(&user)
            if err != nil {
                utils.ErrorHandler(w, err)
                return
            }
            utils.RespondJSON(w, user, http.StatusCreated)
        default:
            w.WriteHeader(http.StatusMethodNotAllowed)
            response := models.ErrorResponse{
                Message: "Method not allowed",
            }
            json.NewEncoder(w).Encode(response)
        }
    })
    log.Println("Server is running on port 8000")
    log.Fatal(http.ListenAndServe(":8000", nil))
}

 

9.在服务器上部署和验证

  linux上传代码并进行编译项目

           

  linux上启动项目

  调用api:

 

 

 

 


标签: GO

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
58 4
|
2月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
159 3
|
10天前
|
Kubernetes 安全 Devops
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
36 10
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
|
1月前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
51 4
|
1月前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
52 1
|
1月前
|
JSON API 数据格式
如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架
本文介绍了如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架,适合小型项目和微服务。文章从环境准备、创建基本Flask应用、定义资源和路由、请求和响应处理、错误处理等方面进行了详细说明,并提供了示例代码。通过这些步骤,读者可以快速上手构建自己的RESTful API。
63 2
|
2月前
|
监控 负载均衡 API
Web、RESTful API 在微服务中有哪些作用?
在微服务架构中,Web 和 RESTful API 扮演着至关重要的角色。它们帮助实现服务之间的通信、数据交换和系统的可扩展性。
54 2
|
2月前
|
中间件 Go API
使用Go语言构建高性能RESTful API
在现代软件开发中,RESTful API因其简洁和高效而成为构建网络服务的首选。Go语言以其并发处理能力和高性能著称,是开发RESTful API的理想选择。本文将介绍如何使用Go语言构建RESTful API,包括基础的路由设置、中间件的使用、数据验证、错误处理以及性能优化。通过实际代码示例,我们将展示Go语言在API开发中的强大功能和灵活性。
|
2月前
|
前端开发 JavaScript API
惊呆了!学会AJAX与Fetch API,你的Python Web项目瞬间高大上!
在Web开发领域,AJAX与Fetch API是提升交互体验的关键技术。AJAX(Asynchronous JavaScript and XML)作为异步通信的先驱,通过XMLHttpRequest对象实现了局部页面更新,提升了应用流畅度。Fetch API则以更现代、简洁的方式处理HTTP请求,基于Promises提供了丰富的功能。当与Python Web框架(如Django、Flask)结合时,这两者能显著增强应用的响应速度和用户体验,使项目更加高效、高大上。
54 2
|
2月前
|
前端开发 API 开发者
从零到精通,AJAX与Fetch API让你的Python Web前后端交互无所不能!
从零到精通,AJAX与Fetch API让你的Python Web前后端交互无所不能!
46 3
下一篇
DataWorks