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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 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

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
8月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
625 4
|
8月前
|
开发框架 前端开发 Go
【GoGin】(0)基于Go的WEB开发框架,GO Gin是什么?怎么启动?本文给你答案
Gin:Go语言编写的Web框架,以更好的性能实现类似Martini框架的APInet/http、Beego:开源的高性能Go语言Web框架、Iris:最快的Go语言Web框架,完备的MVC支持。
674 1
|
11月前
|
监控 Java 编译器
限流、控并发、减GC!一文搞懂Go项目资源优化的正确姿势
本章介绍Go语言项目在构建与部署阶段的性能调优和资源控制策略,涵盖编译优化、程序性能提升、并发与系统资源管理、容器化部署及自动化测试等内容,助力开发者打造高效稳定的生产级应用。
|
11月前
|
测试技术 Go 开发工具
Go语言项目工程化 — 常见开发工具与 CI/CD 支持
Go语言项目工程化实践中的开发工具与CI/CD支持,涵盖格式化、静态检查、依赖管理、构建打包、自动化测试及部署策略。内容包括常用工具如gofmt、go vet、golangci-lint、Docker、GitHub Actions等,并提供实战建议与总结,提升团队协作效率与项目质量。
|
11月前
|
NoSQL 中间件 Go
Go语言项目工程化 — 项目结构与模块划分
本章讲解Go语言项目工程化中的结构设计与模块划分,涵盖单体及分层架构方案,指导如何按功能组织代码,提升项目的可维护性、扩展性,适用于不同规模的开发场景。
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
11月前
|
JSON 安全 Go
Go语言项目工程化 —— 日志、配置、错误处理规范
本章详解Go语言项目工程化核心规范,涵盖日志、配置与错误处理三大关键领域。在日志方面,强调其在问题排查、性能优化和安全审计中的作用,推荐使用高性能结构化日志库zap,并介绍日志级别与结构化输出的最佳实践。配置管理部分讨论了配置分离的必要性,对比多种配置格式如JSON、YAML及环境变量,并提供viper库实现多环境配置的示例。错误处理部分阐述Go语言显式返回error的设计哲学,讲解标准处理方式、自定义错误类型、错误封装与堆栈追踪技巧,并提出按调用层级进行错误处理的建议。最后,总结各模块的工程化最佳实践,助力构建可维护、可观测且健壮的Go应用。
|
开发框架 JSON 中间件
Go语言Web开发框架实践:使用 Gin 快速构建 Web 服务
Gin 是一个高效、轻量级的 Go 语言 Web 框架,支持中间件机制,非常适合开发 RESTful API。本文从安装到进阶技巧全面解析 Gin 的使用:快速入门示例(Hello Gin)、定义 RESTful 用户服务(增删改查接口实现),以及推荐实践如参数校验、中间件和路由分组等。通过对比标准库 `net/http`,Gin 提供更简洁灵活的开发体验。此外,还推荐了 GORM、Viper、Zap 等配合使用的工具库,助力高效开发。
|
JSON 前端开发 API
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
1030 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
584 20

推荐镜像

更多