第一个 go web 应用

Posted 阿拉的梦想

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第一个 go web 应用相关的知识,希望对你有一定的参考价值。

应用简介

学习go web做的第一个应用,主要实现了发送一个http请求到后端,然后路由分发,连接数据库,获取数据,并返回给调用者的过程。

环境信息:

  • win10
  • go:1.16
  • goland:2021.1.1
  • mysql:5.0

应用完整目录:
在这里插入图片描述

各层代码

数据库信息

/*
 Navicat Premium Data Transfer

 Source Server         : 本机
 Source Server Type    : MySQL
 Source Server Version : 50018
 Source Host           : localhost:3306
 Source Schema         : demo

 Target Server Type    : MySQL
 Target Server Version : 50018
 File Encoding         : 65001

 Date: 22/05/2021 16:32:22
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (
  `id` int(11) NOT NULL DEFAULT '' AUTO_INCREMENT,
  `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
  `age` int(11) NOT NULL DEFAULT '' COMMENT '年龄',
  `sex` varchar(5) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '性别',
  PRIMARY KEY USING BTREE (`id`)
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'Tom', 1, '男');
INSERT INTO `t_user` VALUES (2, '张三', 3, '男');

SET FOREIGN_KEY_CHECKS = 1;

main.go

程序的入口,相当于java程序的启动类。
主要做初始化工作和开启web服务监听。

package main

import (
	"demo1/db"
	"demo1/route"
	"fmt"
	"net/http"
)

func main() {
	fmt.Println("开始启动服务...")
	db.InitDB()
	fmt.Println("初始化数据库完毕")
	route.InitAllRoutes()
	err := http.ListenAndServe(":8080", nil)
	fmt.Println("服务启动完毕")
	if err != nil {
		fmt.Printf("启动错误:%v", err)
	}

}

DbUtil.go

负责数据库连接的初始化工作

package db

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql" //必须要有驱动包,虽然没有直接使用,可以在前面加上_表示隐式使用
	"github.com/jmoiron/sqlx"
)

//数据库工具类

//DB 数据库全局变量
var DB *sqlx.DB

//InitDB 初始化数据库连接
func InitDB() (err error) {
	dsn := "root:root@tcp(127.0.0.1:3306)/demo"
	// 也可以使用MustConnect连接不成功就panic
	DB, err = sqlx.Connect("mysql", dsn)
	if err != nil {
		fmt.Printf("connect DB failed, err:%v\\n", err)
		return
	}
	DB.SetMaxOpenConns(20)
	DB.SetMaxIdleConns(10)
	return
}

HTTP路由

负责分发http请求到对应的执行器中,相当于java的controller路由映射

总路由配置AllRoutes.go

一个总的路由初始化接口,里面调用各个模块的路由初始化接口。

package route

import "fmt"

/*
InitAllRoutes 初始化所有路由
*/
func InitAllRoutes() {
	//用户路由
	fmt.Println("开始初始化所有路由...")
	userRoutes()
	fmt.Println("结束初始化所有路由")
}

用户模块的路由配置userRoute.go

用户模块的路由配置

package route

import (
	"demo1/controller"
	"net/http"
)
//userRoutes 初始化用户路由
func userRoutes(){
	http.HandleFunc("/getAllUsers", controller.GetAllUsers)
}

模型

结构体,相当于java的模型类

package user

//需要与数据库字段做映射,大小写要与数据库一致,否则报错query failed, err:non-struct dest type struct with >1 columns (4)

//User 用户类
type User struct {
	Id   int    `db:"id"`
	Name string `db:"name"`
	Age  int    `db:"age"`
	Sex  string `db:"sex"`
}

控制器UserController.go

处理具体的http请求,里面调用service层

package controller

import (
	"demo1/service"
	"encoding/json"
	"fmt"
	"net/http"
)
/*
GetAllUsers 获取所有用户
 */
func GetAllUsers(writer http.ResponseWriter, request *http.Request) {
	fmt.Printf("===进入hello方法,method=%v===\\n",request.Method)
	users := service.GetAllUsers()
	jsonUser,_:=json.Marshal(users)
	res := string(jsonUser)
	fmt.Printf("查询到结果=%v\\n",res)
	fmt.Fprintln(writer,res)
	fmt.Println("===结束hello方法===")
}

业务层UserService.go

处理具体的业务逻辑,里面调用数据库。这里为了简单,就没写dao层

package service

import (
	"demo1/db"
	"demo1/model/user"
	"fmt"
)

/*
GetAllUsers 查询多条数据示例
首字母大写才能被其他包使用
*/
func GetAllUsers() []user.User {
	sqlStr := "select * from t_user"
	var users []user.User
	err := db.DB.Select(&users, sqlStr)
	if err != nil {
		fmt.Printf("query failed, err:%v\\n", err)
		return nil
	}
	// %#v会打印出类型+json格式 users:[]user.User{user.User{Id:1, Name:"Tom", Age:1, Sex:"男"}, user.User{Id:2, Name:"张三", Age:3, Sex:"男"}}
	//fmt.Printf("users:%#v\\n", users)
	//%v 直接打印出值,非json格式 [{1 Tom 1 男} {2 张三 3 男}]
	//fmt.Printf("users:%v\\n", users)
	return users
}

依赖管理

go.mod

module demo1

go 1.16

require (
	github.com/go-sql-driver/mysql v1.5.0
	github.com/jmoiron/sqlx v1.3.4
)

go.sum

github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=
github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=

测试

浏览器调用:http://localhost:8080/getAllUsers
在这里插入图片描述
后台日志:
在这里插入图片描述
完整源码下载:demo1.zip

以上是关于第一个 go web 应用的主要内容,如果未能解决你的问题,请参考以下文章

为什么我坚持用Go语言做Web应用开发框架?

你可能不知道的JavaScript代码片段和技巧(下)

你可能不知道的JavaScript代码片段和技巧(上)

十条jQuery代码片段助力Web开发效率提升

十条jQuery代码片段助力Web开发效率提升

[Go] 通过 17 个简短代码片段,切底弄懂 channel 基础