模型规则
type BaseModel struct {
// 自增主键
ID int `gorm:"column:id;AUTO_INCREMENT;PRIMARY_KEY"`
// 创建时间(由gorm框架自动创建)
CreatedAt time.Time `gorm:"column:created_at;type:datetime"`
// 更新时间(由gorm框架自动更新)
UpdatedAt time.Time `gorm:"column:updated_at;type:datetime"`
}
type StudentModel struct {
BaseModel
Name string `gorm:"column:name"`
Age int `gorm:"column:age"`
Birth *time.Time `gorm:"column:birth"`
}
DbSource
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"time"
)
var DB *gorm.DB
func Init() {
var err error
DB, err = gorm.Open('mysql', 'root:root@tcp(127.0.0.1:3306)/test?charset=utf8∥seTime=True&loc=Local')
if err != nil {
fmt.Printf("mysql connect error %v", err)
// 若连接失败,则延时10秒重新连接
time.Sleep(10 * time.Second)
DB, err = gorm.Open('mysql', 'root:root@tcp(127.0.0.1:3306)/test?charset=utf8∥seTime=True&loc=Local')
if err != nil {
panic(err.Error())
}
}
if DB.Error != nil {
fmt.Printf("database error %v", DB.Error)
}
// 打印SQL
DB.LogMode(true)
DB.SingularTable(true)
DB.DB().SetMaxIdleConns(10)
DB.DB().SetMaxOpenConns(100)
}
Dao
type StudentDao struct {
Student resources.StudentModel
}
// 表字段名称
const StudentModelResultMap = "id,created_at,updated_at,name,age,birth"
// Create
func (d *StudentDao) Insert() StudentModel {
table := models.DB.Table("student")
table.Create(&d.Student)
return d.Student
}
// Delete
func (d *StudentDao) Delete() {
models.DB.Table("student").Delete(&d.Student)
}
// Modify
func (d *StudentDao) Update(data map[string]interface{}) map[string]interface{} {
models.DB.Table("student").Model(StudentModel{}).Where("id = ?", data["Id"]).Updates(data)
return data
}
// Query
func (d *StudentDao) SelectOne() StudentModel {
models.DB.Table("student").Select(StudentModelResultMap).Where("id = ?", d.Student.ID).First(&d.Student)
return d.Student
}
func (d *StudentDao) SelectAll(pageNum int, pageSize int, condition map[string]interface{}) []StudentModel {
var students []StudentModel
table := models.DB.Table("student").Select(StudentModelResultMap)
if condition != nil {
if condition["Name"] != nil && condition["Name"] != "" {
table = table.Where("name like ?", "%"+condition["Name"].(string)+"%")
}
}
table = table.Offset((pageNum - 1) * pageSize).Limit(pageSize)
table.Find(&students)
return students
}
func (d *StudentDao) CountAll(condition map[string]interface{}) interface{} {
var total int
table := models.DB.Table("student").Select(StudentModelResultMap)
if condition != nil {
if condition["Name"] != nil && condition["Name"] != "" {
table = table.Where("name like ?", "%"+condition["Name"].(string)+"%")
}
}
table.Count(&total)
return total
}
func (d *StudentDao) CountByCondition(condition map[string]interface{}) int {
var total int
table := models.DB.Table("student").Select(StudentModelResultMap)
if condition != nil {
if condition["Name"] != nil && condition["Name"] != "" {
table = table.Where("name = ?", condition["Name"].(string))
}
}
table.Count(&total)
return total
}
Service
type StudentService struct {
}
func MakeJson(data map[string]interface{}) []byte {
bytes, _ := json.Marshal(data)
return bytes
}
// 拷贝非nil参数
func CopyParams(val []string, data map[string]interface{}) map[string]interface{} {
params := make(map[string]interface{})
for _, v := range val {
if data[v] != nil {
_, isStr := data[v].(string)
if isStr && data[v] != "" {
params[v] = data[v]
} else {
params[v] = data[v]
}
}
}
return params
}
func (s *StudentService) Add(data map[string]interface{}) StudentModel {
studentDao := new(dao.StudentDao)
params := CopyParams([]string{"Name", "Age", "Birth"}, data)
// 将json解析到对应的结构体
_ = json.Unmarshal(MakeJson(params), &studentDao.Student)
return studentDao.Insert()
}
func (s *StudentService) GetInfo(id int) StudentModel {
studentDao := new(dao.StudentDao)
studentDao.Student.ID = id
return studentDao.SelectOne()
}
func (s *StudentService) Update(data map[string]interface{}) map[string]interface{} {
studentDao := new(dao.StudentDao)
params := CopyParams([]string{"Id", "Name", "Age", "Birth"}, data)
// 无论有没有备注都更新
// params["Remark"] = data["Remark"]
return studentDao.Update(params)
}
func (s *StudentService) Delete(id int) {
studentDao := new(dao.StudentDao)
studentDao.Student.ID = id
studentDao.Delete()
}
func (s *StudentService) GetList(pageNum int, pageSize int, data map[string]interface{}) interface{} {
studentDao := new(dao.StudentDao)
return studentDao.SelectAll(pageNum, pageSize, data)
}
func (s *StudentService) CountAll(condition map[string]interface{}) interface{} {
studentDao := new(dao.StudentDao)
return studentDao.CountAll(condition)
}
func (s *StudentService) CountByCondition(condition map[string]interface{}) int {
studentDao := new(dao.StudentDao)
return studentDao.CountByCondition(condition)
}
Controller
import (
"github.com/gin-gonic/gin"
"strconv"
"strings"
"time"
"unicode/utf8"
"net/http"
)
type HttpResponse struct {
Status int `json:"status"` // HTTP 状态
Code int `json:"code"` // 错误码
Message string `json:"message"` // 错误信息
}
// 分页属性
type Pagination struct {
PageSize int `form:"limit" json:"limit"`
PageNo int `form:"page" json:"page"`
}
// 增改Form:学生Handler
type StudentHandler struct {
// 姓名
Name string `form:"Name" json:"Name" binding:"required"`
// 年龄
Age int `form:"Age" json:"Age" binding:"required"`
// 生日
Birth *time.Time `form:"Birth" json:"Birth" binding:"required"`
}
// 分页查询Form:学生Handler
type StudentQueryHandler struct {
Pagination
// 姓名
Name string `form:"Name" json:"Name"`
}
// 获取有效分页参数
func GetPageParams(handler interface{}) (int, int) {
pageNo := reflect.ValueOf(handler).FieldByName("PageNo").Int()
pageSize := reflect.ValueOf(handler).FieldByName("PageSize").Int()
if pageNo <= 0 {
pageNo = 1
}
if pageSize <= 0 || pageSize > 100 {
pageSize = 10
}
return int(pageNo), int(pageSize)
}
func (*StudentHandler) Save(c *gin.Context) {
handler := StudentHandler{}
// 绑定且判断字段是否存在,required不会判断内容为""
if err := c.ShouldBindJSON(&handler); err != nil {
c.JSON(http.StatusBadRequest.Status, gin.H{
"code": http.StatusBadRequest.Code,
"msg": "请求参数有误",
"data": nil,
})
return
}
// 去除空格
name := strings.TrimSpace(handler.Name)
// 必填判断
if name == "" {
c.JSON(http.StatusBadRequest.Status, gin.H{
"code": http.StatusBadRequest.Code,
"msg": "姓名必填",
"data": nil,
})
return
}
if utf8.RuneCountInString(name) < 2 {
c.JSON(http.StatusBadRequest.Status, gin.H{
"code": http.StatusBadRequest.Code,
"msg": "姓名不得少于2个汉字",
"data": nil,
})
return
}
// 赋值
data := map[string]interface{}{
"Name": handler.Name,
"Age": handler.Age,
"Birth": handler.Birth,
}
// 入库
student := new(StudentService).Add(data)
c.JSON(http.StatusOK.Status, gin.H{
"code": http.StatusOK.Code,
"msg": http.StatusOK.Message,
"data": student,
})
return
}
func (*StudentHandler) DeleteById(c *gin.Context) {
uid, _ := strconv.Atoi(c.Param("id").(string))
// 判断ID是否有效
if uid == 0 {
c.JSON(http.StatusBadRequest.Status, gin.H{
"code": http.StatusBadRequest.Code,
"msg": "主键ID有误",
"data": nil,
})
return
}
studentService := StudentService{}
studentService.Delete(uid)
c.JSON(http.StatusOK.Status, gin.H{
"code": http.StatusOK.Code,
"msg": http.StatusOK.Message,
"data": nil,
})
return
}
func (*StudentHandler) UpdateById(c *gin.Context) {
uid, err := strconv.Atoi(c.Param("id"))
// 判断ID是否有效
if err != nil {
c.JSON(http.StatusBadRequest.Status, gin.H{
"code": http.StatusBadRequest.Code,
"msg": "主键ID有误",
"data": nil,
})
return
}
handler := StudentHandler{}
if err := c.ShouldBindJSON(&handler); err != nil {
c.JSON(http.StatusBadRequest.Status, gin.H{
"code": http.StatusBadRequest.Code,
"msg": "请求参数有误",
"data": nil,
})
return
}
// 绑定值
data := map[string]interface{}{
"Id": uid,
"Name": handler.Name,
"Age": handler.Age,
"Birth": handler.Birth,
}
studentService := SudentService{}
student := studentService.Update(data)
c.JSON(http.StatusOK.Status, gin.H{
"code": http.StatusOK.Code,
"msg": http.StatusOK.Message,
"data": student,
})
return
}
func (*StudentQueryHandler) SelectByPage(c *gin.Context) {
handler := StudentQueryHandler{}
// 校验查询参数
if err := c.ShouldBindQuery(&handler); err != nil {
c.JSON(http.StatusBadRequest.Status, gin.H{
"code": http.StatusBadRequest.Code,
"msg": "请求参数有误",
"data": nil,
})
return
}
handler.PageNo, handler.PageSize = GetPageParams(handler)
condition := map[string]interface{}{
"name": handler.Name,
}
studentService := StudentService{}
studentList := studentService.GetList(handler.PageNo, handler.PageSize, condition)
studentCount := studentService.CountAll(condition)
c.JSON(http.StatusOK.Status, gin.H{
"code": http.StatusOK.Code,
"msg": http.StatusOK.Message,
"data": map[string]interface{}{
"data": studentList,
"total": studentCount,
},
})
return
}