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

go,项目,实现,mysql,接入,以及,web,api · 浏览次数 : 197

小编点评

## 内容生成指南 **1. 工具导入** ```go import ( "encoding/json" "go_test/models" "go_test/utils" "log" "net/http" "go_test/database" "go_test/repositories" "go_test/services" ) ``` **2. 错误处理** ```go func HandleError(w http.ResponseWriter, err error) { if err != nil { w.WriteHeader(http.StatusInternalServerError) response := models.ErrorResponse{ Message: err.Error(), } json.NewEncoder(w).Encode(response) return } } ``` **3. 错误响应** ```go func RespondJSON(w http.ResponseWriter, data interface{}, statusCode int) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(statusCode) json.NewEncoder(w).Encode(data) } ``` **4. 日志记录** ```go log.Println("coming main method ...\") ``` **5. 数据库连接** ```go db, err := database.NewMySQLDB() if err != nil { log.Fatal(err) } ``` **6. 用户仓库** ```go userRepository := &repositories.UserRepository{ DB: db, } ``` **7. 服务接口** ```go userService := &services.UserService{ UserRepository: userRepository, } ``` **8. API路由** ```go http.HandleFunc(\"/users\", func(w http.ResponseWriter, r *http.Request) { // ...其他逻辑 ... } ``` **9. 主类** ```go 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) { // ...其他逻辑 ... } log.Println("Server is running on port 8000\") log.Fatal(http.ListenAndServe(\":8000\", nil))} } ``` **10. 构建项目** ```go go build main.go ``` **11. 部署项目** ```go // ...部署代码 ... ``` **12. 运行项目** ```go // ...运行代码 ... ``` **13. 测试项目** ```go // ...测试代码 ... ```

正文

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

  创建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接入以及web api相似的内容:

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

本文为博主原创,转载请注明出处: 创建go项目,并在go项目中接入mysql,将mysql的配置项单独整理放到一个胚子和文件中,支持项目启动时,通过加载配置文件中的值,然后创建数据库连接。 之后使用net/http相关的库,创建路由,并在路由中通过不同的http方法,实现mysql连接的test数据

go项目实现通过配置文件进行配置项统一管理

转载请注明出处: go项目中实现配置项统一管理,实现逻辑:将 配置项整理为一个json的数据结构,并保存到go.conf文件中,然后在go项目启动main方法中加载 go.conf 文件,读取go.conf 文件的json 数据结构,并进行反序列化为go的数据结构,从而在go项目中可以全局使用 go

Go-Zero从0到1实现微服务项目开发(二)

继续更新GoZero微服务实战系列文章:上一篇被GoZero作者万总点赞了,本文将继续使用 Go-zero 提供的工具和组件,从零开始逐步构建一个基本的微服务项目。手把手带你完成:项目初始化+需求分析+表结构设计+api+rpc+goctl+apifox调试+细节处理。带你实现一个完整微服务的开发。

Go-Zero自定义goctl实战:定制化模板,加速你的微服务开发效率(四)

gozero如何自定义goctl?本文详解和实战,通过本文你将了解goctl的妙用,提高你的开发效率。介绍如何使用goctl工具实现模板定制化,并根据实际项目业务需求进行模板定制化实现。

Go-Zero技能提升:深度探究goctl的妙用,轻松应对微服务开发挑战!(三)

前言 有位同学在群里说:“Go-Zero官方文档太简洁了,对小白有点不友好。好奇你们是怎么学习的?项目是怎么封装的?有什么提高开发效率的技巧吗?”。 来来来,这期内容给你安排上,先教你goctl的妙用! 前两篇文章分享了 Go-Zero微服务快速入门和最佳实践(一) 和 Go-Zero从0到1实现微

分布式注册服务中心etcd在云原生引擎中的实践

作者:王雷 etcd是什么 etcd是云原生架构中重要的基础组件,由CNCF孵化托管。ETCD是用于共享配置和服务发现的分布式,一致性的KV存储系统,是CoreOS公司发起的一个开源项目,授权协议为Apache。etcd 基于Go语言实现,主要用于共享配置,服务发现,集群监控,leader选举,分布

Go-Zero微服务快速入门和最佳实践(一)

前言 并发编程和分布式微服务是我们Gopher升职加薪的关键。 毕竟Go基础很容易搞定,不管你是否有编程经验,都可以比较快速的入门Go语言进行简单项目的开发。 虽说好上手,但是想和别人拉开差距,提高自己的竞争力,搞懂分布式微服务和并发编程还是灰常重要的,这也是我今年更新文章的重点。 更文计划 我会更

Go代码包与引入:如何有效组织您的项目

本文深入探讨了Go语言中的代码包和包引入机制,从基础概念到高级应用一一剖析。文章详细讲解了如何创建、组织和管理代码包,以及包引入的多种使用场景和最佳实践。通过阅读本文,开发者将获得全面而深入的理解,进一步提升Go开发的效率和质量。 关注公众号【TechLeadCloud】,分享互联网架构、云服务技术

彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-登录与图形验证码(captcha)EP06

书接上回,上一回我们按照“低耦合高内聚”的组织架构方针对项目的整体结构进行了优化,本回将会继续编写业务,那就是用户的登录逻辑,将之前用户管理模块中添加的用户账号进行账号和密码的校验,校验通过后留存当前登录用户的信息,过程中使用图形验证码强制进行人机交互,防止账号的密码被暴力破解。 登录逻辑 首先在逻

彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-JWT和中间件(Middleware)的使用EP07

前文再续,上一回我们完成了用户的登录逻辑,将之前用户管理模块中添加的用户账号进行账号和密码的校验,过程中使用图形验证码强制进行人机交互,防止账号的密码被暴力破解。本回我们需要为登录成功的用户生成Token,并且通过Iris的中间件(Middleware)进行鉴权操作。 Iris模板复用 在生成Tok