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

  创建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. Django4全栈进阶之路8 createsuperuser创建超级管理员账号

    在 Django 4 中,可以使用 createsuperuser 命令来创建超级管理员账号.超级管理员拥有管理后台的所有权限,包括创建.编辑和删除用户.组.权限等操作. 下面是创建超级管理员账号的步 ...

  2. Vue跨域详解

    碰到这种问题,其实你的接口已经通了,但是在页面上就是访问不通过. 你可以把API请求地址单独拎出来新开个网站打开看请求是否成功,成功,但是你的项目不通. 有那么几个可能吧: 1.请求头设置错误 hea ...

  3. 【GiraKoo】Android Studio调试时,提示port无法打开

    Android Studio调试时,提示port无法打开 现象描述 在Android Studio在进行调试时,无法正常运行.App闪退. IDE提示: Error running 'app': Un ...

  4. 【Java】Java代码拷贝文件的速度

    Java代码拷贝文件的速度究竟有多快? 前言 最近学习Java到了流处理,其中有种流叫FileInputStream和FileOutputStream,简单来说,就是操作文件的,老师给我们示范了一个非 ...

  5. k8s实战案例之部署Nginx+Tomcat+NFS实现动静分离

    1.基于镜像分层构建及自定义镜像运行Nginx及Java服务并基于NFS实现动静分离 1.1.业务镜像设计规划 根据业务的不同,我们可以导入官方基础镜像,在官方基础镜像的基础上自定义需要用的工具和环境 ...

  6. 沉痛悼念 pip search 一路走好

    不知道最近大家有没有发现在使用 pip search 的时候,总是出现一个 XMLRPC 的报错. $ pip search xlrdERROR: XMLRPC request failed [cod ...

  7. Qt+QtWebApp开发笔记(五):http服务器html中使用json触发ajax与后台交互实现数据更新传递

    前言   前面完成了页面的跳转.登录,很多时候不刷新页面就想刷新局部数据,此时ajax就是此种技术,且是异步的.  本篇实现网页内部使用js调用ajax实现异步交互数据.  在js中使用 ajax是通 ...

  8. MySQL8新特性窗口函数详解

    本文博主给大家详细讲解一波 MySQL8 的新特性:窗口函数,相信大伙看完一定能有所收获. 本文提供的 sql 示例都是基于 MySQL8,由博主亲自执行确保可用 博主github地址:http:// ...

  9. 【AGC】云监控日志服务查询不到Logger日志相关问题2

    ​[关键字] AGC.云监控.日志服务 [问题描述] 之前有开发者反馈在使用AGC云监控,填写了Logger日志,但是在云监控的日志服务查不到的问题.具体如下所述: 云函数按要求写了Logger日志, ...

  10. 通过模仿学会Python爬虫(一):零基础上手

    好家伙,爬虫来了 爬虫,这玩意,不会怎么办, 诶,先抄一份作业回来 1.别人的爬虫  Python爬虫史上超详细讲解(零基础入门,老年人都看的懂)_ChenBinBini的博客-CSDN博客 # -* ...