golang项目CRUD示例

目录

项目结构

数据库的连接

实体类

Repository层(crud)

Service层

接口层

main.go

Router.go


项目结构

复制代码
myproject/
├── cmd/
│   └── server/
│       └── main.go
├── internal/
│   ├── config/
│   │   └── db.go
│   ├── model/
│   │   └── student.go
│   ├── repository/
│   │   └── student_repo.go
│   ├── service/
│   │   └── student_service.go
│   └── handler/
│       └── student_handler.go
├── pkg/
│   └── utils/
│       └── response.go
├── api/
│   └── swagger.md  # 可选
├── scripts/
│   └── run.sh
├── web/            # 可放前端资源
├── go.mod
└── go.sum

数据库的连接

复制代码
package config

import (
	"fmt"
	"log"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

var DB *gorm.DB

func InitDB() {
	user := "root"
	password := "your_password"
	host := "127.0.0.1"
	port := "3306"
	dbname := "students"

	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		user, password, host, port, dbname)

	var err error
	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true, // 使用单数表名
		},
	})
	if err != nil {
		log.Fatalf("数据库连接失败: %v", err)
	}

	log.Println("✅ MySQL 数据库连接成功")
}

实体类

go语言中类名和列名首字母大写才能被外部访问,Student对应数据库库students,可以在数据库连接的时候配置使用单数表名

复制代码
package model

type Student struct {
	Id        uint   `gorm:"primaryKey" json:"id"`
	Name      string `json:"name"`
	Age       int    `json:"age"`
	Major     string `json:"major"`
	ClassRoom string `json:"class_room"`
}

Repository层(crud)

复制代码
package repository

import (
	"go-student-project/internal/config"
	"go-student-project/internal/model"
)

func CreateStudent(student *model.Student) error {
	return config.DB.Create(student).Error
}

func GetAllStudents() ([]model.Student, error) {
	var students []model.Student
	err := config.DB.Find(&students).Error
	return students, err
}

func GetStudentByID(id uint) (model.Student, error) {
	var student model.Student
	err := config.DB.First(&student, id).Error
	return student, err
}

func UpdateStudent(student *model.Student) error {
	return config.DB.Save(student).Error
}

func DeleteStudent(id uint) error {
	return config.DB.Delete(&model.Student{}, id).Error
}

Service层

复制代码
package service

import (
	"go-student-project/internal/model"
	"go-student-project/internal/repository"
)

func CreateStudent(student *model.Student) error {
	return repository.CreateStudent(student)
}

func GetAllStudents() ([]model.Student, error) {
	return repository.GetAllStudents()
}

func GetStudent(id uint) (model.Student, error) {
	return repository.GetStudentByID(id)
}

func UpdateStudent(student *model.Student) error {
	return repository.UpdateStudent(student)
}

func DeleteStudent(id uint) error {
	return repository.DeleteStudent(id)
}

接口层

复制代码
package handler

import (
	"go-student-project/internal/model"
	"go-student-project/internal/service"
	"go-student-project/pkg/utils"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

func AddStudent(c *gin.Context) {
	var student model.Student
	if err := c.ShouldBindJSON(&student); err != nil {
		utils.Error(c, "参数绑定失败", 400)
		return
	}

	if err := service.CreateStudent(&student); err != nil {
		utils.Error(c, "创建失败", 500)
		return
	}

	utils.Success(c, student, "学生创建成功")
}

func ListStudents(c *gin.Context) {
	students, err := service.GetAllStudents()
	if err != nil {
		utils.Error(c, "查询失败", 500)
		return
	}
	utils.Success(c, students, "查询成功")
}

func GetStudent(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	student, err := service.GetStudent(uint(id))
	if err != nil {
		utils.Error(c, "学生不存在", 404)
		return
	}
	utils.Success(c, student, "查询成功")
}

func UpdateStudent(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))

	var input model.Student
	if err := c.ShouldBindJSON(&input); err != nil {
		utils.Error(c, "参数错误", 400)
		return
	}

	student, err := service.GetStudent(uint(id))
	if err != nil {
		utils.Error(c, "学生不存在", 404)
		return
	}

	// 更新允许修改的字段
	student.Name = input.Name
	student.Age = input.Age
	student.Major = input.Major
	student.ClassRoom = input.ClassRoom

	if err := service.UpdateStudent(&student); err != nil {
		utils.Error(c, "更新失败", 500)
		return
	}

	utils.Success(c, student, "更新成功")
}

func DeleteStudent(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	if err := service.DeleteStudent(uint(id)); err != nil {
		utils.Error(c, "删除失败", 500)
		return
	}
	utils.Success(c, nil, "删除成功")
}

统一处理(和Java中自定义Result<T>很像)

复制代码
package utils

import (
	"github.com/gin-gonic/gin"
)

func JsonResponse(c *gin.Context, code int, msg string, data any) {
	c.JSON(200, gin.H{
		"code": code,
		"msg":  msg,
		"data": data,
	})
}

func Success(c *gin.Context, data any, msg string) {
	JsonResponse(c, 200, msg, data)
}

func Error(c *gin.Context, msg string, code int) {
	JsonResponse(c, code, msg, nil)
}

main.go

复制代码
package main

import (
	"go-student-project/internal/config"
	"go-student-project/internal/handler"
	"github.com/gin-gonic/gin"
)

func main() {
	// 初始化数据库
	config.InitDB()
	config.DB.AutoMigrate(&handler.Student{}) // 或 model.Student

	// 初始化路由
	r := gin.Default()

	studentGroup := r.Group("/student")
	{
		studentGroup.POST("/", handler.AddStudent)
		studentGroup.GET("/", handler.ListStudents)
		studentGroup.GET("/:id", handler.GetStudent)
		studentGroup.PUT("/:id", handler.UpdateStudent)
		studentGroup.DELETE("/:id", handler.DeleteStudent)
	}

	r.Run(":8080")
}

Router.go

复制代码
package router

import (
	"student/controller"

	"github.com/gin-gonic/gin"
)

func InitRouter() *gin.Engine {
	engine := gin.Default()

	engine.POST("/student", controller.AddStudent)
	engine.GET("/student", controller.GetStudent)
	engine.PUT("/student/:id", controller.UpdateStudent)
	engine.DELETE("/student/:id", controller.DeleteStudent)
	return engine
}
相关推荐
想搞艺术的程序员2 小时前
Go 优雅关闭实践指南:从原理到框架落地
开发语言·后端·golang
JohnYan2 小时前
Bun技术评估 - 29 Docker集成
javascript·后端·docker
m5655bj2 小时前
Python 查找并高亮显示指定 Excel 数据
开发语言·python·excel
华仔啊2 小时前
MyBatis-Plus 让你开发效率翻倍!新手也能5分钟上手!
java·后端·mybatis
绝无仅有2 小时前
某东互联网大厂的Redis面试知识点分析
后端·面试·架构
洛克希德马丁2 小时前
Qt 配置Webassemble环境
开发语言·qt·webassembly·emscripten·emsdk
武子康2 小时前
Java-167 Neo4j CQL 实战:CREATE/MATCH 与关系建模速通 案例实测
java·开发语言·数据库·python·sql·nosql·neo4j
自由的好好干活2 小时前
C#桌面框架与Qt对比及选型(国产操作系统开发视角)
开发语言·qt·c#
upward_tomato2 小时前
python中模拟浏览器操作之playwright使用说明以及打包浏览器驱动问题
开发语言·python