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 configimport ("fmt""log""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/schema"
)var DB *gorm.DBfunc 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 errorDB, 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 modeltype 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 repositoryimport ("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.Studenterr := config.DB.Find(&students).Errorreturn students, err
}func GetStudentByID(id uint) (model.Student, error) {var student model.Studenterr := config.DB.First(&student, id).Errorreturn 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 serviceimport ("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 handlerimport ("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.Studentif 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.Studentif 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.Namestudent.Age = input.Agestudent.Major = input.Majorstudent.ClassRoom = input.ClassRoomif 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 utilsimport ("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 mainimport ("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 routerimport ("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
}