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

mysql:

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; 

 

项目结构:

6ddc5e56-ab38-4992-9992-3ba071941759

 

Model:

/*
# 版权所有  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:

/*
# 版权所有  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 :

/*
# 版权所有  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:

 

/*
# 版权所有  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:

/*
# 版权所有  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)
}

  

调用

/*
# 版权所有  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)

} 

输出:

image

 

 

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

  

 

 

 

 

 

 

 

posted @ 2026-04-14 20:41  ®Geovin Du Dream Park™  阅读(10)  评论(0)    收藏  举报