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

  创建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的更多相关文章

  1. 【WEB API项目实战干货系列】- WEB API入门(一)

    这篇做为这个系列的第一篇,做基本的介绍,有经验的人可以直接跳到第二部分创建 ProductController.   创建 Web API 项目 在这里我们使用VS2013, .NET 4.5.1创建 ...

  2. 【WEB API项目实战干货系列】- 导航篇(十足干货分享)

    在今天移动互联网的时代,作为攻城师的我们,谁不想着只写一套API就可以让我们的Web, Android APP, IOS APP, iPad APP, Hybired APP, H5 Web共用共同的 ...

  3. 【WEB API项目实战干货系列】- 接口文档与在线测试(二)

    上一篇: [WEB API项目实战干货系列]- Web API 2入门(一) 这一篇我们主要介绍如何做API帮助文档,给API的调用人员介绍各个 API的功能, 输入参数,输出参数, 以及在线测试 A ...

  4. Web API(三):创建Web API项目

    在本篇文章中将讲解如何使用Visual Studio创建一个新的ASP.NET Web API项目. 在Visual Studio中有两种方式用于创建Web API项目: 1.创建带MVC的Web A ...

  5. Web API应用架构在Winform混合框架中的应用(4)--利用代码生成工具快速开发整套应用

    前面几篇介绍了Web API的基础信息,以及如何基于混合框架的方式在WInform界面里面整合了Web API的接入方式,虽然我们看似调用过程比较复杂,但是基于整个框架的支持和考虑,我们提供了代码生成 ...

  6. Entity Framework 6 Recipes 2nd Edition(9-4)译->Web API 的客户端实现修改跟踪

    9-4. Web API 的客户端实现修改跟踪 问题 我们想通过客户端更新实体类,调用基于REST的Web API 服务实现把一个对象图的插入.删除和修改等数据库操作.此外, 我们想通过EF6的Cod ...

  7. Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务

    前言 很久没更新了,之前有很多事情,所以拖了很久,非常抱歉.好了,废话不多说,下面开始正题.本篇仍然使用上一季的的项目背景(系列地址http://www.cnblogs.com/fzrain/p/34 ...

  8. ASP.NET Web API 接口执行时间监控

    软件产品常常会出现这样的情况:产品性能因某些无法预料的瓶颈而受到干扰,导致程序的处理效率降低,性能得不到充分的发挥.如何快速有效地找到软件产品的性能瓶颈,则是我们感兴趣的内容之一. 在本文中,我将解释 ...

  9. 2.4使用属性在 ASP.NET Web API 2 路由创建一个 REST API

    Web API 2 支持一种新型的路由,称为属性路由.属性路由的一般概述,请参阅属性路由 Web API 2 中.在本教程中,您将使用属性路由创建一个 REST API 集合的书.API 将支持以下操 ...

  10. ASP.NET Web API实现POST报文的构造与推送

    毕设和OAuth协议相关,而要理解OAuth协议就必须理解HTTP GET/POST方法.因此研究了一下如何使用Web API或MVC构造POST报文并实现客户端与服务器端的交互. 我使用的工具是Vi ...

随机推荐

  1. 2021-02-18:给定一个字符串str,给定一个字符串类型的数组arr,出现的字符都是小写英文。arr每一个字符串,代表一张贴纸,你可以把单个字符剪开使用,目的是拼出str来。返回需要至少多少张贴纸可以完成这个任务。例子:str= "babac",arr = {"ba","c","abcd"}。a + ba + c 3 abcd + abcd 2 abcd+ba 2。所以返回2。

    2021-02-18:给定一个字符串str,给定一个字符串类型的数组arr,出现的字符都是小写英文.arr每一个字符串,代表一张贴纸,你可以把单个字符剪开使用,目的是拼出str来.返回需要至少多少张贴 ...

  2. Python忽略NoData计算多张遥感影像的像元平均值:whitebox库

      本文介绍基于Python中whitebox模块,对大量长时间序列栅格遥感影像的每一个像元进行忽略NoData值的多时序平均值求取.   在文章Python ArcPy批量计算多时相遥感影像的各像元 ...

  3. 数据分析缺失值处理(Missing Values)——删除法、填充法、插值法

    缺失值指数据集中某些变量的值有缺少的情况,缺失值也被称为NA(not available)值.在pandas里使用浮点值NaN(Not a Number)表示浮点数和非浮点数中的缺失值,用NaT表示时 ...

  4. 【GiraKoo】C++中static关键字的作用

    C++中static关键字的作用 在程序中良好的使用static,const,private等关键字,对于代码的健壮性有很大的帮助. 本文介绍的就是C++中static关键字的一些常见用法与区别.适合 ...

  5. 从 DevOps 到平台工程:软件开发的新范式

    DevOps 是一种将开发和运营结合起来的方法,在应用规划.开发.交付和运营方面将人员.流程和技术结合起来.DevOps 使以前孤立的角色(如开发.IT运营.质量工程和安全)之间进行协调和合作.一直以 ...

  6. 常见 Linux 提权

    Common Linux Privesc 记录 常见 Linux 提权的 提权方式:水平提权,垂直提权. 水平提权:这是您通过接管与您处于相同权限级别的不同用户来扩大您对受感染系统的影响的地方. 例如 ...

  7. 曾经辛苦造的轮子,现在能否用 ChatGPT 替代呢?

    上一篇文章 我在 vscode 插件里接入了 ChatGPT,解决了代码变量命名的难题 中,展示了如何在 vscode 插件中使用 ChatGPT 解决代码变量命名的问题.vscode 插件市场中有很 ...

  8. 编译器设计与实现:Java编译器并发编程模型实现多核CPU和Web应用程序

    目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3. 实现步骤与流程 3.1 准备工作:环境配置与依赖安装 3.2 核心模块实现 3.3 集成 ...

  9. WPF 入门笔记 - 06 - 命令

    我们把世界看错,反说它欺骗了我们. --飞鸟集 前言 相较而言,命令对我来说是一个新概念,因为在Winform中压根没有所谓的命令这个概念.从文字角度理解,"命令"可以指代一种明确 ...

  10. Maven进阶

    前言 在项目开发的过程中,我们通常要使用到外部依赖的组件,同时也会使用某些插件来帮助我们管理项目.例如,我们访问数据库的时候需要使用到jdbc组件,我们可以下载对应的jar包去加载到我们的应用中.在我 ...