go: Model,Interface,DAL ,Factory,BLL using mysql

mysql:

sql 复制代码
drop table IF EXISTS School; #刪除表
create table School  #創建表
(
    `SchoolId` int(11) NOT NULL AUTO_INCREMENT comment'學校Id', #設計為自增長
    `SchoolNo` char(5) NOT NULL comment'主鍵primary key,學校編號',  #採取手工輸入,也可以設計為自動添加自增長 為5位元,數位,字元,或數位和字元組合,在文本保存資料時,用程式碼進行限制
    `SchoolName` nvarchar(500) NOT NULL DEFAULT '' comment' 學校名稱',
    `SchoolTelNo`  varchar(8)  NULL DEFAULT '' comment'電話號碼',      
    PRIMARY KEY (SchoolId),  #主鍵
    UNIQUE KEY (SchoolNo)
)COMMENT='學校表 School Table' DEFAULT CHARSET=utf8;
  
drop table IF EXISTS Teacher; #刪除表
create table Teacher  #創建表
(
    `TeacherId` int(11) NOT NULL AUTO_INCREMENT comment'老师編號', #設計為自增長
    `TeacherNo` char(5) NOT NULL comment'主鍵primary key,老师編號',
    `TeacherFirstName` nvarchar(100) NOT NULL DEFAULT '' comment' 名',
    `TeacherLastName` nvarchar(20) NOT NULL DEFAULT '' comment' 姓',
    `TeacherGender` char(2) NOT NULL DEFAULT '' comment'性別',
    `TeacherTelNo`  varchar(8)  NULL DEFAULT '' comment'電話號碼',
     `TeacherSchoolId` int NOT NULL  comment'外鍵 foreign key 學校ID',    
     PRIMARY KEY (TeacherId),   #主鍵
     UNIQUE KEY (TeacherNo),
     FOREIGN KEY(TeacherSchoolId) REFERENCES School(SchoolId)  #外鍵
)COMMENT='老師表Teacher Table' DEFAULT CHARSET=utf8;
 
drop table IF EXISTS Student; #刪除表
create table Student  #創建表
(
    `StudentId` int(11) NOT NULL AUTO_INCREMENT comment'學生ID', #設計為自增長
    `StudentNO` char(5) NOT NULL comment'主鍵primary key,學生編號',
    `StudentFirstName` nvarchar(120) NOT NULL DEFAULT '' comment' 名',
    `StudentLastName` nvarchar(120) NOT NULL DEFAULT '' comment' 姓',
    `Gender` char(2) NOT NULL DEFAULT '' comment'性別',
    `StudentTelNo`  varchar(8)  NULL DEFAULT '' comment'電話號碼',    
    `StudentTeacherId`  int not NULL comment'外鍵foreign key,老師編號', 
  PRIMARY KEY (`StudentId`),   #主鍵
  UNIQUE KEY (StudentNO),
  FOREIGN KEY(StudentTeacherId) REFERENCES Teacher(TeacherId)  #外鍵
)COMMENT='學生表 Student Table' DEFAULT CHARSET=utf8;

项目结构:

Model:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:22
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : school.go
*/
package model
 
// 学校表 定义数据模型结构
type School struct {
    SchoolId   int       `gorm:"column:SchoolId;primaryKey;autoIncrement" json:"school_id"`     // 自增主键
    SchoolNo   string    `gorm:"column:SchoolNo;type:char(5);not null;unique" json:"school_no"` // 学校编号5位
    SchoolName string    `gorm:"column:SchoolName;type:varchar(500);not null" json:"school_name"`
    SchoolTel  string    `gorm:"column:SchoolTelNo;type:varchar(8)" json:"school_tel"`
    Teachers   []Teacher `gorm:"foreignKey:TeacherSchoolId;references:SchoolId"` // 老师关联 SchoolId
}
 
// TableName 指定表名为 School,强制 GORM 使用这个名称而不是默认的 schools
func (School) TableName() string {
    return "school"
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:23
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : teacher.go
*/
package model
 
// 教师表 定义数据模型结构
type Teacher struct {
    TeacherId        int    `gorm:"column:TeacherId;primaryKey;autoIncrement" json:"teacher_id"`
    TeacherNo        string `gorm:"column:TeacherNo;type:char(5);not null" json:"teacher_no"`
    TeacherFirstName string `gorm:"column:TeacherFirstName;type:varchar(100);not null" json:"first_name"`
    TeacherLastName  string `gorm:"column:TeacherLastName;type:varchar(20);not null" json:"last_name"`
    TeacherGender    string `gorm:"column:TeacherGender;type:char(2);not null" json:"gender"`
    TeacherTelNo     string `gorm:"column:TeacherTelNo;type:varchar(8)" json:"tel"`
    TeacherSchoolId  int    `gorm:"column:TeacherSchoolId;not null" json:"school_id"` // 外键必须 char(5)
 
    School   School    `gorm:"foreignKey:TeacherSchoolId;references:SchoolId"`
    Students []Student `gorm:"foreignKey:StudentTeacherId;references:TeacherId"`
}
 
func (Teacher) TableName() string {
    return "teacher"
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:23
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : student.go
*/
package model
 
// 学生表 定义数据模型结构
type Student struct {
    StudentId        int    `gorm:"column:StudentId;primaryKey;autoIncrement" json:"student_id"`
    StudentNo        string `gorm:"column:StudentNo;type:char(5);not null" json:"student_no"`
    StudentFirstName string `gorm:"column:StudentFirstName;type:varchar(120);not null" json:"first_name"`
    StudentLastName  string `gorm:"column:StudentLastName;type:varchar(120);not null" json:"last_name"`
    Gender           string `gorm:"column:Gender;type:char(2);not null" json:"gender"`
    StudentTel       string `gorm:"column:StudentTelNo;type:varchar(8)" json:"tel"`
    StudentTeacherId int    `gorm:"column:StudentTeacherId;not null" json:"teacher_id"`
 
    Teacher Teacher `gorm:"foreignKey:StudentTeacherId;references:TeacherId"`
}
 
func (Student) TableName() string {
    return "student"
}
 
// 分页统一返回结构体
type PageResult struct {
    Total int64       `json:"total"`
    List  interface{} `json:"list"`
}

Interface:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:27
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : school_interface.go
*/
package _interface
 
import "mysqldemol/model"
 
// 学校接口 定义抽象接口,实现解耦
type ISchool interface {
    Add(school *model.School) error
    Update(school *model.School) error
    Delete(id int) error
    GetById(id int) (*model.School, error)
    GetPageList(page, pageSize int) (*model.PageResult, error)
    // 模糊查询
    SearchSchools(page, pageSize int, keyword string) (*model.PageResult, error)
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:38
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : teacher_interface.go
*/
package _interface
 
import "mysqldemol/model"
 
// 老师接口  定义抽象接口,实现解耦
type ITeacher interface {
    Add(teacher *model.Teacher) error
    Update(teacher *model.Teacher) error
    Delete(id int) error
    GetById(id int) (*model.Teacher, error)
    GetPageList(page, pageSize int) (*model.PageResult, error)
    // 模糊查询
    SearchTeachers(page, pageSize int, keyword string) (*model.PageResult, error)
    GetListBySchoolId(schoolId int) ([]model.Teacher, error)
    GetTeacherWithSchool(teacherId int) (*model.Teacher, error)
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:38
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : student_interface.go
*/
package _interface
 
import "mysqldemol/model"
 
// 学生接口(含分页+关联查询)定义抽象接口,实现解耦
type IStudent interface {
    Add(student *model.Student) error
    Update(student *model.Student) error
    Delete(id int) error
    GetById(id int) (*model.Student, error)
    GetPageList(page, pageSize int) (*model.PageResult, error)
    SearchStudents(page, pageSize int, keyword string) (*model.PageResult, error)
    GetStudentWithTeacherSchool(studentId int) (*model.Student, error)
 
    GetStudentsPaginated(page int, size int, keyword string) (*model.PageResults, error)
}

DAL :

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:33
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : school_dal.go
*/
package dal
 
import (
    "mysqldemol/interface"
    "mysqldemol/model"
)
 
// 据访问层实现
type SchoolDAL struct{}
 
func NewSchoolDAL() _interface.ISchool {
    return &SchoolDAL{}
}
 
func (d *SchoolDAL) Add(m *model.School) error {
    return DB.Create(m).Error
}
 
func (d *SchoolDAL) Update(m *model.School) error {
    return DB.Model(m).Where("SchoolId=?", m.SchoolId).Updates(m).Error
}
 
func (d *SchoolDAL) Delete(id int) error {
    return DB.Delete(&model.School{}, id).Error
}
 
func (d *SchoolDAL) GetById(id int) (*model.School, error) {
    var m model.School
    err := DB.First(&m, id).Error
    return &m, err
}
 
func (d *SchoolDAL) GetPageList(page, pageSize int) (*model.PageResult, error) {
    var list []model.School
    var total int64
 
    DB.Model(&model.School{}).Count(&total)
    err := DB.Offset((page - 1) * pageSize).Limit(pageSize).Find(&list).Error
 
    return &model.PageResult{Total: total, List: list}, err
}
 
// 学校模糊查询:编号、名称
func (d *SchoolDAL) SearchSchools(page, pageSize int, keyword string) (*model.PageResult, error) {
    var list []model.School
    var total int64
 
    db := DB.Model(&model.School{})
    if keyword != "" {
        db = db.Where("SchoolNo LIKE ? OR SchoolName LIKE ?",
            "%"+keyword+"%", "%"+keyword+"%")
    }
 
    db.Count(&total)
    err := db.Offset((page - 1) * pageSize).Limit(pageSize).Find(&list).Error
 
    return &model.PageResult{Total: total, List: list}, err
}
 
 
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:33
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : teacher_dal.go
*/
package dal
 
import (
    "mysqldemol/interface"
    "mysqldemol/model"
)
 
// TeacherDAL 教师数据访问层实现 数据访问层
type TeacherDAL struct{}
 
func NewTeacherDAL() _interface.ITeacher {
    return &TeacherDAL{}
}
 
func (d *TeacherDAL) Add(m *model.Teacher) error {
    return DB.Create(m).Error
}
 
func (d *TeacherDAL) Update(m *model.Teacher) error {
    return DB.Model(m).Where("TeacherId=?", m.TeacherId).Updates(m).Error
}
 
func (d *TeacherDAL) Delete(id int) error {
    return DB.Delete(&model.Teacher{}, id).Error
}
 
func (d *TeacherDAL) GetById(id int) (*model.Teacher, error) {
    var m model.Teacher
    err := DB.First(&m, id).Error
    return &m, err
}
 
func (d *TeacherDAL) GetPageList(page, pageSize int) (*model.PageResult, error) {
    var list []model.Teacher
    var total int64
 
    DB.Model(&model.Teacher{}).Count(&total)
    err := DB.Offset((page - 1) * pageSize).Limit(pageSize).Find(&list).Error
 
    return &model.PageResult{Total: total, List: list}, err
}
 
// 老师模糊查询:编号、姓名
func (d *TeacherDAL) SearchTeachers(page, pageSize int, keyword string) (*model.PageResult, error) {
    var list []model.Teacher
    var total int64
 
    db := DB.Model(&model.Teacher{})
    if keyword != "" {
        db = db.Where("TeacherNo LIKE ? OR TeacherFirstName LIKE ? OR TeacherLastName LIKE ?",
            "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%")
    }
 
    db.Count(&total)
    err := db.Offset((page - 1) * pageSize).Limit(pageSize).Find(&list).Error
 
    return &model.PageResult{Total: total, List: list}, err
}
 
func (d *TeacherDAL) GetListBySchoolId(schoolId int) ([]model.Teacher, error) {
    var list []model.Teacher
    err := DB.Where("SchoolId=?", schoolId).Find(&list).Error
    return list, err
}
 
func (d *TeacherDAL) GetTeacherWithSchool(id int) (*model.Teacher, error) {
    var m model.Teacher
    err := DB.Preload("School").First(&m, id).Error
    return &m, err
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:31
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : student_dal.go
*/
package dal
 
import (
    "mysqldemol/interface"
    "mysqldemol/model"
)
 
// 学生DAL实现 据访问层实现
type StudentDAL struct{}
 
func NewStudentDAL() _interface.IStudent {
    return &StudentDAL{}
}
 
func (d *StudentDAL) Add(m *model.Student) error {
    return DB.Create(m).Error
}
 
func (d *StudentDAL) Update(m *model.Student) error {
    return DB.Model(m).Where("StudentId=?", m.StudentId).Updates(m).Error
}
 
func (d *StudentDAL) Delete(id int) error {
    return DB.Delete(&model.Student{}, id).Error
}
 
func (d *StudentDAL) GetById(id int) (*model.Student, error) {
    var m model.Student
    err := DB.First(&m, id).Error
    return &m, err
}
 
func (d *StudentDAL) GetPageList(page, pageSize int) (*model.PageResult, error) {
    var list []model.Student
    var total int64
 
    DB.Model(&model.Student{}).Count(&total)
    err := DB.Offset((page - 1) * pageSize).Limit(pageSize).Find(&list).Error
 
    return &model.PageResult{Total: total, List: list}, err
}
 
// 学生模糊查询:学号、姓名
func (d *StudentDAL) SearchStudents(page, pageSize int, keyword string) (*model.PageResult, error) {
    var list []model.Student
    var total int64
 
    db := DB.Model(&model.Student{})
    if keyword != "" {
        db = db.Where("StudentNo LIKE ? OR StudentFirstName LIKE ? OR StudentLastName LIKE ?",
            "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%")
    }
 
    db.Count(&total)
    err := db.Offset((page - 1) * pageSize).Limit(pageSize).Find(&list).Error
 
    return &model.PageResult{Total: total, List: list}, err
}
 
func (d *StudentDAL) GetStudentWithTeacherSchool(id int) (*model.Student, error) {
    var m model.Student
    err := DB.Preload("Teacher").Preload("Teacher.School").First(&m, id).Error
    return &m, err
}
 
// GetSchoolsPaginated 分页查询学校列表
// @param db
// @Param page
// @param size
// @param keyword
func (d *StudentDAL) GetStudentsPaginated(page int, size int, keyword string) (*model.PageResults, error) {
 
    var students []model.Student
    var total int64
 
    query := DB.Model(&model.Student{})
 
    // 如果有关键词搜索,则模糊匹配学校名称
    if keyword != "" {
        query = query.Where("StudentFirstName LIKE ?", "%"+keyword+"%")
    }
 
    // 获取总数
    if err := query.Count(&total).Error; err != nil {
        return nil, err
    }
 
    // 计算偏移量
    offset := (page - 1) * size
 
    // 执行分页查询
    if err := query.Offset(offset).Limit(size).Find(&students).Error; err != nil {
        return nil, err
    }
 
    // 计算总页数
    totalPages := total / int64(size)
    if total%int64(size) > 0 {
        totalPages++
    }
 
    pageResults := &model.PageResults{
        Data:       students,
        Page:       page,
        Size:       size,
        Total:      total,
        TotalPages: totalPages,
    }
 
    return pageResults, nil
}
  

Factory:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:33
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : factory.go
*/
package factory
 
import (
    "mysqldemol/dal"
    "mysqldemol/interface"
)
 
// 工厂:统一创建数据访问实例
type DALFactory struct{}
 
// 创建学校DAL
func (f *DALFactory) CreateSchoolDAL() _interface.ISchool {
    return dal.NewSchoolDAL()
}
 
// 创建教师DAL
func (f *DALFactory) CreateTeacherDAL() _interface.ITeacher {
    return dal.NewTeacherDAL()
}
 
// 创建学生DAL
func (f *DALFactory) CreateStudentDAL() _interface.IStudent {
    return dal.NewStudentDAL()
}

BLL:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:46
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : school_bll.go
*/
package bll
 
import (
    "errors"
    "mysqldemol/factory"
    "mysqldemol/interface"
    "mysqldemol/model"
)
 
// SchoolBLL 学校业务逻辑层
type SchoolBLL struct {
    dal _interface.ISchool
}
 
func NewSchoolBLL() *SchoolBLL {
    f := &factory.DALFactory{}
    return &SchoolBLL{dal: f.CreateSchoolDAL()}
}
 
// 添加
func (b *SchoolBLL) AddSchool(m *model.School) error {
    if len(m.SchoolNo) != 5 {
        return errors.New("学校编号必须5位")
    }
    if m.SchoolName == "" {
        return errors.New("学校名称不能为空")
    }
    return b.dal.Add(m)
}
 
// 更新
func (b *SchoolBLL) UpdateSchool(m *model.School) error {
    return b.dal.Update(m)
}
 
// 删除
func (b *SchoolBLL) DeleteSchool(id int) error {
    return b.dal.Delete(id)
}
 
// 通过ID查询一条
func (b *SchoolBLL) GetSchoolById(id int) (*model.School, error) {
    return b.dal.GetById(id)
}
 
// 分页查询
func (b *SchoolBLL) GetSchoolPage(page, pageSize int) (*model.PageResult, error) {
    if page < 1 {
        page = 1
    }
    if pageSize < 1 || pageSize > 100 {
        pageSize = 10
    }
    return b.dal.GetPageList(page, pageSize)
}
 
// 学校模糊查询
func (b *SchoolBLL) SearchSchools(page, pageSize int, keyword string) (*model.PageResult, error) {
    if page < 1 {
        page = 1
    }
    if pageSize < 1 || pageSize > 100 {
        pageSize = 10
    }
    return b.dal.SearchSchools(page, pageSize, keyword)
}
 
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:47
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : teacher_bll.go
*/
package bll
 
import (
    "errors"
    "mysqldemol/factory"
    "mysqldemol/interface"
    "mysqldemol/model"
)
 
// TeacherBLL 教师业务逻辑层
type TeacherBLL struct {
    dal _interface.ITeacher
}
 
func NewTeacherBLL() *TeacherBLL {
    f := &factory.DALFactory{}
    return &TeacherBLL{dal: f.CreateTeacherDAL()}
}
 
// 添加
func (b *TeacherBLL) AddTeacher(m *model.Teacher) error {
    if len(m.TeacherNo) != 5 {
        return errors.New("教师编号必须5位")
    }
    if m.TeacherFirstName == "" || m.TeacherLastName == "" {
        return errors.New("姓名不能为空")
    }
    if m.TeacherSchoolId <= 0 {
        return errors.New("必须选择学校")
    }
    return b.dal.Add(m)
}
 
// 更新
func (b *TeacherBLL) UpdateTeacher(m *model.Teacher) error {
    return b.dal.Update(m)
}
 
// 删除
func (b *TeacherBLL) DeleteTeacher(id int) error {
    return b.dal.Delete(id)
}
 
// 通过ID查询一条
func (b *TeacherBLL) GetTeacherById(id int) (*model.Teacher, error) {
    return b.dal.GetById(id)
}
 
// 分页查询
func (b *TeacherBLL) GetTeacherPage(page, pageSize int) (*model.PageResult, error) {
    if page < 1 {
        page = 1
    }
    if pageSize < 1 || pageSize > 100 {
        pageSize = 10
    }
    return b.dal.GetPageList(page, pageSize)
}
 
// 老师模糊查询
func (b *TeacherBLL) SearchTeachers(page, pageSize int, keyword string) (*model.PageResult, error) {
    if page < 1 {
        page = 1
    }
    if pageSize < 1 || pageSize > 100 {
        pageSize = 10
    }
    return b.dal.SearchTeachers(page, pageSize, keyword)
}
 
func (b *TeacherBLL) GetTeachersBySchoolId(schoolId int) ([]model.Teacher, error) {
    return b.dal.GetListBySchoolId(schoolId)
}
 
func (b *TeacherBLL) GetTeacherInfo(id int) (*model.Teacher, error) {
    return b.dal.GetTeacherWithSchool(id)
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:  Model → Interface → DAL → Factory → BLL
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/14 20:41
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : student_bll.go
*/
package bll
 
import (
    "errors"
    "mysqldemol/factory"
    "mysqldemol/interface"
    "mysqldemol/model"
)
 
// StudentBLL 学生业务逻辑
type StudentBLL struct {
    dal _interface.IStudent
}
 
func NewStudentBLL() *StudentBLL {
    f := &factory.DALFactory{}
    return &StudentBLL{dal: f.CreateStudentDAL()}
}
 
// 添加
func (b *StudentBLL) AddStudent(m *model.Student) error {
    if len(m.StudentNo) != 5 {
        return errors.New("学号必须5位")
    }
    if m.StudentTeacherId <= 0 {
        return errors.New("必须选择老师")
    }
    return b.dal.Add(m)
}
 
// 更新
func (b *StudentBLL) UpdateStudent(m *model.Student) error {
    return b.dal.Update(m)
}
 
// 删除
func (b *StudentBLL) DeleteStudent(id int) error {
    return b.dal.Delete(id)
}
 
// 通过ID查询一条
func (b *StudentBLL) GetStudentById(id int) (*model.Student, error) {
    return b.dal.GetById(id)
}
 
// 分页查询
func (b *StudentBLL) GetStudentPage(page, pageSize int) (*model.PageResult, error) {
    if page < 1 {
        page = 1
    }
    if pageSize < 1 || pageSize > 100 {
        pageSize = 10
    }
    return b.dal.GetPageList(page, pageSize)
}
 
// 模糊查询
func (b *StudentBLL) SearchStudents(page, pageSize int, keyword string) (*model.PageResult, error) {
    if page < 1 {
        page = 1
    }
    if pageSize < 1 || pageSize > 100 {
        pageSize = 10
    }
    return b.dal.SearchStudents(page, pageSize, keyword)
}
 
// GetSchoolsPaginated 分页查询学校列表
// @param db
// @Param page
// @param size
// @param keyword
func (b *StudentBLL) GetStudentsPaginated(page int, pageSize int, keyword string) (*model.PageResults, error) {
    if page < 1 {
        page = 1
    }
    if pageSize < 1 || pageSize > 100 {
        pageSize = 10
    }
    return b.dal.GetStudentsPaginated(page, pageSize, keyword)
}
 
// 查询
func (b *StudentBLL) GetStudentInfo(id int) (*model.Student, error) {
    return b.dal.GetStudentWithTeacherSchool(id)
}

调用

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/4/13 22:19
# User      :  geovindu
# Product   : GoLand
# Project   : mysqldemol
# File      : main.go
*/
 
package main
 
import (
    "fmt"
    "log"
    "mysqldemol/bll"
    "mysqldemol/dal"
)
 
//TIP <p>To run your code, right-click the code and select <b>Run</b>.</p> <p>Alternatively, click
// the <icon src="AllIcons.Actions.Execute"/> icon in the gutter and select the <b>Run</b> menu item from here.</p>
 
func main() {
 
    //dal.InitDB()
    // 从 JSON 初始化 DB
    //err := dal.InitAutoDB()
    //if err != nil {
    //log.Fatal(err)
    //}
    // 2. 初始化业务层
    err := dal.InitDB()
    if err != nil {
        log.Fatal("数据库连接失败:", err)
    }
    fmt.Println("✅ 数据库连接成功")
 
    schoolBll := bll.NewSchoolBLL()
    teacherBll := bll.NewTeacherBLL()
    studentBll := bll.NewStudentBLL()
 
    /*
        // ==========================================
        // 第一步:添加学校
        // ==========================================
        school := &model.School{
            SchoolNo:   "SCH02",
            SchoolName: "广州市第二中学",
            SchoolTel:  "88889666",
        }
        err = schoolBll.AddSchool(school)
        if err != nil {
            log.Fatal("添加学校失败:", err)
        }
        fmt.Println("✅ 学校添加成功")
 
        // ==========================================
        // 第二步:添加老师
        // ==========================================
        teacher := &model.Teacher{
            TeacherNo:        "T0001",
            TeacherFirstName: "李",
            TeacherLastName:  "华",
            TeacherGender:    "男",
            TeacherTelNo:     "13800138",
            TeacherSchoolId:  1,
        }
        err = teacherBll.AddTeacher(teacher)
        if err != nil {
            log.Fatal("添加老师失败:", err)
        }
        fmt.Println("✅ 老师添加成功")
 
        // ==========================================
        // 第三步:添加学生
        // ==========================================
        student := &model.Student{
            StudentNo:        "S0001",
            StudentFirstName: "小明",
            StudentLastName:  "张",
            Gender:           "男",
            StudentTel:       "28883434",
            StudentTeacherId: 1,
        }
        err = studentBll.AddStudent(student)
        if err != nil {
            log.Fatal("添加学生失败:", err)
        }
        fmt.Println("✅ 学生添加成功")
    */
    // ==========================================
    // 第四步:模糊查询 + 分页(用户自定义)
    // ==========================================
    // ========== 学生查询 ==========
    page := 1 // 第一次定义 := Model → Interface → DAL → Factory → BLL
    pageSize := 15
    keyword := ""
 
    res, err := studentBll.SearchStudents(page, pageSize, keyword)
    if err != nil {
        log.Fatal("搜索失败:", err)
    }
    fmt.Println("\n🔍 学生模糊查询结果:")
    fmt.Println("总条数:", res.Total)
    fmt.Println("列表:", res.List)
 
    // ========== 学校查询(不用 :=,直接用 =)==========
    page = 1      // 不再用 :=
    pageSize = 15 // 不再用 :=
    keyword = "University"
 
    // res 前面也不要 :=,只需要 =
    res, err = schoolBll.SearchSchools(page, pageSize, keyword)
    if err != nil {
        log.Fatal("搜索失败:", err)
    }
    fmt.Println("\n🔍 学校模糊查询结果:")
    fmt.Println("总条数:", res.Total)
    fmt.Println("列表:", res.List)
 
    // ========== 老师查询(同样用 =)==========
    page = 1
    pageSize = 15
    keyword = "Nanping"
 
    res, err = teacherBll.SearchTeachers(page, pageSize, keyword)
    if err != nil {
        log.Fatal("搜索失败:", err)
    }
    fmt.Println("\n🔍 老师模糊查询结果:")
    fmt.Println("总条数:", res.Total)
    fmt.Println("列表:", res.List)
 
} 

输出:

安装包:

bash 复制代码
go get gorm.io/gorm
go get gorm.io/driver/mysql
go get gorm.io/driver/sqlserver
go get gorm.io/driver/sqlite
go get gorm.io/driver/postgres
相关推荐
XiYang-DING2 小时前
【Java】反射
java·开发语言
意法半导体STM322 小时前
【官方原创】STM32 USBx Host HID standardalone移植示例 LAT1449
开发语言·前端·stm32·单片机·嵌入式硬件
若阳安好2 小时前
【java】任务流批处理平台
java·开发语言
梦想与想象-广州大智汇2 小时前
MySQL 同步数据到 ClickHouse 方案对比分析
数据库·mysql·clickhouse
yuezhilangniao2 小时前
centos7安装mysql57- 2026整理 mysql5.7.44
mysql
chimooing2 小时前
Hermes与OpenClaw的技术碰撞:从JavaScript引擎优化到企业级数据采集的深度解析
开发语言·javascript·ecmascript
guojb8242 小时前
当 Vue 3 遇上桥接模式:手把手教你优雅剥离虚拟滚动的业务大泥球
vue.js·设计模式
XiYang-DING2 小时前
【Java】Lambda表达式
java·开发语言·python
来自远方的老作者2 小时前
第9章 函数-9.7 函数嵌套
开发语言·python·函数·函数嵌套