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接入以及web api的更多相关文章
- 【WEB API项目实战干货系列】- WEB API入门(一)
这篇做为这个系列的第一篇,做基本的介绍,有经验的人可以直接跳到第二部分创建 ProductController. 创建 Web API 项目 在这里我们使用VS2013, .NET 4.5.1创建 ...
- 【WEB API项目实战干货系列】- 导航篇(十足干货分享)
在今天移动互联网的时代,作为攻城师的我们,谁不想着只写一套API就可以让我们的Web, Android APP, IOS APP, iPad APP, Hybired APP, H5 Web共用共同的 ...
- 【WEB API项目实战干货系列】- 接口文档与在线测试(二)
上一篇: [WEB API项目实战干货系列]- Web API 2入门(一) 这一篇我们主要介绍如何做API帮助文档,给API的调用人员介绍各个 API的功能, 输入参数,输出参数, 以及在线测试 A ...
- Web API(三):创建Web API项目
在本篇文章中将讲解如何使用Visual Studio创建一个新的ASP.NET Web API项目. 在Visual Studio中有两种方式用于创建Web API项目: 1.创建带MVC的Web A ...
- Web API应用架构在Winform混合框架中的应用(4)--利用代码生成工具快速开发整套应用
前面几篇介绍了Web API的基础信息,以及如何基于混合框架的方式在WInform界面里面整合了Web API的接入方式,虽然我们看似调用过程比较复杂,但是基于整个框架的支持和考虑,我们提供了代码生成 ...
- Entity Framework 6 Recipes 2nd Edition(9-4)译->Web API 的客户端实现修改跟踪
9-4. Web API 的客户端实现修改跟踪 问题 我们想通过客户端更新实体类,调用基于REST的Web API 服务实现把一个对象图的插入.删除和修改等数据库操作.此外, 我们想通过EF6的Cod ...
- Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务
前言 很久没更新了,之前有很多事情,所以拖了很久,非常抱歉.好了,废话不多说,下面开始正题.本篇仍然使用上一季的的项目背景(系列地址http://www.cnblogs.com/fzrain/p/34 ...
- ASP.NET Web API 接口执行时间监控
软件产品常常会出现这样的情况:产品性能因某些无法预料的瓶颈而受到干扰,导致程序的处理效率降低,性能得不到充分的发挥.如何快速有效地找到软件产品的性能瓶颈,则是我们感兴趣的内容之一. 在本文中,我将解释 ...
- 2.4使用属性在 ASP.NET Web API 2 路由创建一个 REST API
Web API 2 支持一种新型的路由,称为属性路由.属性路由的一般概述,请参阅属性路由 Web API 2 中.在本教程中,您将使用属性路由创建一个 REST API 集合的书.API 将支持以下操 ...
- ASP.NET Web API实现POST报文的构造与推送
毕设和OAuth协议相关,而要理解OAuth协议就必须理解HTTP GET/POST方法.因此研究了一下如何使用Web API或MVC构造POST报文并实现客户端与服务器端的交互. 我使用的工具是Vi ...
随机推荐
- Go windows 环境搭建
下载地址 官网下载地址:https://golang.google.cn/dl/ 1.下载完之后 双击msi进行安装 路径可以不用改, 继续next 安装完之后就需要配置环境变量, 找到环境变量 GO ...
- 2023-04-14:n对情侣坐在连续排列的 2n 个座位上,想要牵到对方的手, 人和座位由一个整数数组 row 表示,其中 row[i] 是坐在第 i 个座位上的人的ID, 情侣们按顺序编号,第一对
2023-04-14:n对情侣坐在连续排列的 2n 个座位上,想要牵到对方的手, 人和座位由一个整数数组 row 表示,其中 row[i] 是坐在第 i 个座位上的人的ID, 情侣们按顺序编号,第一对 ...
- 2023-01-11:体育馆的人流量。编写一个 SQL 查询以找出每行的人数大于或等于 100 且 id 连续的三行或更多行记录。返回按 visit_date 升序排列 的结果表。 DROP TAB
2023-01-11:体育馆的人流量.编写一个 SQL 查询以找出每行的人数大于或等于 100 且 id 连续的三行或更多行记录.返回按 visit_date 升序排列 的结果表. DROP TABL ...
- Django自定义视图类及实现请求参数和返回参数加解密
django rest_framework中GenericAPIView配合拓展类mixin或者视图集viewset可以复用其代码,减少自己编写的代码量.下面我要实现自己的视图类,以减少代码量新建一个 ...
- Springboot+actuator+prometheus+Grafana集成
本次示例以Windows示例 推荐到官网去下载:Windows版的应用程序 下载最新版 prometheus-2.37.8.windows-amd64 压缩包:解压就行 下载最新版 grafana-9 ...
- THM红队基础
Red Team Fundamentals Learn the core components of a red team engagement, from threat intelligence t ...
- 绘图;OSPF 虚连接
绘图;OSPF 虚连接 原图如下 绘图 实验拓扑 实验需求 按照图示分区域配置OSPF 配置虚连接认证 实验步骤 配置相应接口IP地址及loopback 环回口地址 按照图示分区域配置OSPF AR1 ...
- Hyperledger Fabric系统链码介绍
在Hyperledger Fabric中,LSCC(Lifecycle System Chaincode).CSCC(Chaincode System Chaincode).QSCC(Query Sy ...
- App性能测试之SoloPi
SoloPi简介 SoloPi是蚂蚁金服开发的一款无线化.非侵入.免Root的Android专项测试工具.直接操控安卓系统的手机或智能设备,即可完成自动化的功能.性能.兼容性.以及稳定性测试等工作,降 ...
- ProtocolBuffers的国际化和本地化支持
目录 1. 引言 2. 技术原理及概念 3. 实现步骤与流程 4. 应用示例与代码实现讲解 5. 优化与改进 34.< Protocol Buffers 的国际化和本地化支持> 本文将介绍 ...