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