☰
软件工程课设实战:C++ Builder + Access选课系统全流程解析
2026/10/23 3:09:56 网站建设 项目流程

简介:课程设计指导书是面向计算机科学与技术专业学生的软件工程实践教程,以选课系统为案例,引导读者运用软件工程思想与面向对象方法完成一个小型系统。文档明确了实验目的、先修课程与上机学时,规定在Windows平台使用C++ Builder和Access搭建开发环境;设计内容要求学生、教师、课程、选课等信息符合学校实际,功能至少包含登录、查询、选课、退课和成绩管理。随后按需求分析、软件设计、软件测试、源代码组织报告,要求绘制用例图、序列图、对象模型与状态图,并提交不少于二十组测试数据;成绩依据书面报告、软件实现和考勤加权评定。资源包为单个DOC文档,大小539KB,已有97人学习。书末附有ODBC数据源建立与连接数据库的操作指南,能帮助初学者快速搭建环境、完成课程设计全流程。

1. 这门课设到底在练什么:从文档到能跑的选课系统

软件工程课程设计指导书这门课,最难的地方从来不是写代码,而是把一学期的理论塞进一个 10 学时就能跑起来的小系统里。我见过不少同学需求分析写得漂漂亮亮,一打开 C++ Builder 6.0 连数据库都接不通,最后报告全靠抄模板。这份指导书的价值在于,它把课设的完整路径圈出来了:先建 Access 库,再去 BDE 里注册 ODBC 数据源,用 AdoConnection 把窗体连上,最后交一份带用例图、状态图和 20 个测试序列的报告。适合正在做课设的计算机专业学生,也适合第一次碰 C++ Builder 的开发者抄作业;对要按软件工程流程交付文档的团队,报告结构部分可以直接当验收清单用。

2. 先把环境立住:ODBC 数据源配置与 Access 库的字段设计

2.1 为什么是 Access + ODBC 这个组合

现在回头看,C++ Builder 6.0 配 Access 2000 是个很老的环境,但选型逻辑今天依然说得通。ADO 确实能直接连 Access,不过把 Provider 和数据库路径直接写在连接串里,在机房机器上来回拷贝项目时特别容易翻车——换一台机器路径不对,驱动版本不对,连提示都看不懂。ODBC 方式相当于在数据库和程序之间加了一层“数据源名”,程序里只认这个名字,库文件在哪、用什么驱动,全部交给系统去解析。这等于把环境配置和业务逻辑拆开了,跟现在做开发时把配置外置到环境变量是同一个思路。

另一个实际原因是机房环境。课设用的机器系统环境基本一致,老师提前装好 Access 和 C++ Builder,但每台机器的文件路径未必相同。用 ODBC 数据源名,只要每台机器上注册的数据源叫同一个名字,代码拿到哪儿都能跑。这就是指导书选择这套组合的原因,不是因为它先进,而是因为它稳定、好排查。

2.2 建 Access 库:六张表与字段设计

指导书里列了一串必须覆盖的字段:学生姓名、学号、登录密码、性别、出生年月、籍贯、地址、学生电话、家庭地址、教师号、教师姓名、教研室、职称、教师电话、课名、课号、学分、先行课号、课时、开课教室、人数限制、选课人数、考试成绩、平时成绩、总评成绩。直接铺成一张表也能交差,但那样做字段冗余太大,选课人数和成绩这种派生数据会反复更新出错。按软件工程的习惯,我先拆成五张核心表加一张可选的管理员表。

表名关键字段主键说明
student学号、姓名、登录密码、性别、出生年月、籍贯、地址、学生电话、家庭地址学号学号用文本类型,不用数字
teacher教师号、教师姓名、教研室、职称、性别、教师电话教师号职称可做下拉列表
course课号、课名、学分、先行课号、课时、开课教室、人数限制课号人数限制是选课校验的依据
enroll学号、课号、选课时间学号+课号复合主键防止重复选课
score学号、课号、平时成绩、考试成绩、总评成绩学号+课号总评可按公式自动算

注意两个细节。第一,学号必须用文本字段,很多学校学号带前导零,用数字类型存储会把零吞掉,后面查询全部对不上。第二,选课人数这个字段在指导书里要求存在,但它本质上是 enroll 表的统计结果。课设场景里图省事可以把它冗余在 course 表里,每次选课成功后加一,退课减一,但一定要在选课逻辑里做人数限制判断,否则这个字段就是摆设。

2.3 在 BDE Administrator 里注册 ODBC 数据源

指导书附录的第一步写得很细,我按自己的操作习惯把它压缩成一套可复现的流程。先确认 Access 的 mdb 文件已经建好并且录入了测试数据,比如放在 D 盘根目录下的 xk.mdb,然后开始注册数据源。

  1. 打开控制面板,找到 BDE Administrator,双击进入主界面。
  2. 菜单 Object 里选 New,弹出 Database Drive Name 对话框,选择 Microsoft Access Driver (*.mdb),点 OK。
  3. 左侧面板出现 odbc1 项,右键单击它,菜单里选择 ODBC Administrator,这时弹出的是系统级的 ODBC 数据源管理器。
  4. 点右侧的“添加”按钮,在驱动列表里选 Microsoft Access Driver (*.mdb),点完成。
  5. 在弹出的安装面板里,数据源名填“选课数据源”,数据库栏点“选择”,找到刚才的 xk.mdb,确定。
  6. 回到 ODBC 管理器,能看到刚建的数据源,确定关闭。
  7. 回到 BDE Administrator,右键 odbc1,先 Apply 再 Open。如果左侧 odbc1 的字体变黑,说明数据源连接成功。

这里最容易漏的一步是第 7 步的 Apply。ODBC 管理器里建好的数据源,BDE 并不会自动感知,必须先 Apply 刷新配置,再 Open 做一次真实连接。字体变黑是 BDE 的直观反馈,字体灰着基本就是驱动没选对或者 mdb 路径不对。另外,数据源名建议全程用英文或保持完全一致,中文名能用,但在一些老版本组件里会出现编码解析问题,属于玄学问题,能避就避。

3. 用 ADO 把窗体接到数据库:连接串、测试与参数落位

3.1 三种连接方式的取舍

C++ Builder 6.0 里连 Access 库,常见做法有三种。第一种是直接用 ADO 连接串,把 Provider、数据库路径全写在代码里,好处是换机器不用配数据源,坏处是路径写死,项目一挪位置就报错。第二种是用 UDL 文件,先双击生成一个数据连接文件,代码里引用这个文件,配置集中在一个地方,但机房环境下 UDL 文件容易被杀毒软件拦。第三种就是指导书用的方案,通过 ODBC 数据源名连接,程序只认“选课数据源”这个名字,数据库文件在哪由系统配置决定。

指导书选第三种是有道理的。课设场景里代码要在多台机器上编译运行,如果每个人机器上 Access 文件的路径都不一样,连接串就改得乱七八糟。用数据源名做中介,代码统一,老师验收时只需要确认每台机器都注册了同名数据源,问题定位也快。这个取舍思路放到现在写后端服务也一样——数据库地址不要硬编码,放到配置文件里,环境不同只改配置不改代码。

3.2 从 Build 到测试连接:AdoConnection 的完整点击路径

把 AdoConnection 组件拖到 Form 上之后,双击它弹出 ConnectionString 配置窗口,这是整个连接过程里最像一个黑匣子的环节,我拆开写。点击 Build 按钮后,第一步是选 Provider,这里要选 Microsoft OLE DB Provider for ODBC Drivers,不要选 Access 专用的那个 OLE DB Provider,因为我们的数据源是通过 ODBC 注册的,选错了下面根本找不到数据源名。

选好 Provider 后点“下一步”,进入连接页签,这时能看到“使用数据源名称”的下拉框,展开它,第 2 章注册的“选课数据源”应该出现在列表里。如果下拉是空的,说明 ODBC 数据源没注册成功,回 BDE 检查 Apply 了没有。选好后点“测试连接”,弹出测试成功提示就说明整条链路通了,确定保存。注意一个细节:测试连接只验证数据库能通,不验证表结构对不对,表名和字段名的错误要等运行时 SQL 报错才能暴露。

3.3 连接串长什么样:记录与复用

配置完成后,ConnectionString 属性里会生成一段类似下面的字符串,建议复制出来存到文本文件里,换机器重新配置时可以直接粘贴:

Provider=MSDASQL.1;Persist Security Info=False;Data Source=选课数据源

这个连接串只有三段,但每段都有含义。Provider=MSDASQL.1 表示走 ODBC 驱动;Persist Security Info=False 表示不把密码写入连接信息,对课设这种无密码库来说保持默认即可;Data Source=选课数据源 就是我们在 BDE 里注册的名字,程序运行时通过这个名字找到实际的 Access 文件。如果有一台机器没注册数据源,临时应急可以把连接串改成 Provider=MSDASQL.1;Driver={Microsoft Access Driver (*.mdb)};Dbq=D:\xk.mdb,Dbq 直接指向数据库文件路径,但这属于绕过配置的临时手段,正式交付还是建议用数据源名。

4. 界面与查询逻辑:Label、DBGrid 和三条核心 SQL

4.1 最小可用界面:一个 Form 装下登录、查询和操作区

指导书操作指南里只演示了往 Form 上拖一个 Label 改属性,但一个能交差的选课系统界面,至少要把登录、查询、选课三个区域装在同一个窗口里。组件面板上 Standard 页签里有 Label、Edit、Button,Data Controls 页签里有 DBGrid、DBNavigator,ADO 页签里有 AdoConnection、AdoQuery、DataSource。我一般会按下面的清单摆组件:

组件类型数量作用关键属性
TLabel5~6 个提示文字Caption 改成语义化文案
TEdit3 个学号、密码、查询关键字输入Name 分别命名为 edtXh、edtPwd、edtKey
TButton4 个登录、查询、选课、退课Name 用 btnLogin、btnQuery 等
TDBGrid1 个展示课程或成绩结果集DataSource 指向同一个 TDataSource
TDBNavigator1 个浏览记录可选,新手建议先去掉

界面布局上,顶部放登录区域(学号、密码、登录按钮),中间放查询条件输入和查询按钮,下面放 DBGrid 显示结果,再往下挂选课、退课按钮。第一次做的时候要注意 Object Inspector 里的 Name 属性,所有组件默认叫 Button1、Button2,逻辑一多就分不清谁是谁。养成习惯,拖一个组件就先改 Name,这个习惯能省掉后面一半的调试时间。

4.2 三条核心 SQL:登录校验、开课查询、选课与退课

登录校验是系统的入口,SQL 写成参数化查询,不要直接拼接字符串。C++ Builder 的 ADOQuery 支持 Parameters 参数,执行时动态赋值,既安全又不会踩引号嵌套的坑。

SELECT * FROM student WHERE 学号 = :xh AND 登录密码 = :mm

代码里通过 Parameters 赋值:ADOQuery1.Parameters.ParamByName("xh").Value := edtXh->Text,然后 Open。这里用 Open 而不是 ExecSQL,因为这条语句返回结果集,查得到记录说明学号密码匹配,查不到就提示重新输入。字段名“登录密码”如果嫌长,建表时可以改成 pwd,但要保证 SQL 和表结构一致,最怕的是 SQL 写“登录密码”,表里字段叫“密码”,运行时报字段不存在。

开课查询要展示课号、课名、学分、课时、开课教室、人数限制、选课人数这些字段,同时支持按课程名模糊搜索。

SELECT 课号, 课名, 学分, 课时, 开课教室, 人数限制, 选课人数 FROM course WHERE 课名 LIKE :kw ORDER BY 课号

参数 :kw 赋值为 "%" + edtKey->Text + "%",Access 的 LIKE 通配符是 %,和 SQL Server 一致,但要注意如果用户输入了单引号,参数化方式会自动处理,不会把 SQL 弄碎。这里有个新手常见的翻车点:用 ExecSQL 执行带结果集的 SELECT,运行时会报“命令包含不带结果集的查询”,所以查询类 SQL 一律 Open,插入删除更新才用 ExecSQL。

选课和退课是最容易出逻辑问题的两段。选课不能只插入 enroll 记录,必须先校验人数限制,否则人数限制字段形同虚设。

-- 第一步:查询当前已选人数 SELECT COUNT(*) FROM enroll WHERE 课号 = :kh -- 第二步:未超限才插入选课记录 INSERT INTO enroll(学号, 课号, 选课时间) VALUES(:xh, :kh, :sj)

这个流程在课设报告里要专门写成一段说明:先查 count,小于人数限制才允许插入,同时更新 course 表的选课人数加一。退课则相反,删除 enroll 记录后把选课人数减一。理论上这两步用事务包起来最稳,但 Access 课设场景下同一时间只有一个人操作,界面层按顺序执行已经够用,报告里提一句“并发场景需引入事务”就行。

4.3 把数据感知组件绑到查询结果

SQL 写对了不代表界面上能看到数据,中间还隔着 DataSource。标准的绑定链路是 AdoQuery 设置 Connection 指向 AdoConnection,DataSource 的 DataSet 属性指向这条 AdoQuery,DBGrid 的 DataSource 指向这个 DataSource。链路里任何一环断掉,表格就是空的。

刷新数据也有讲究。重新执行查询时,先 AdoQuery1->Close,再改 SQL 或参数,最后 Open,顺序不能反。直接在 Open 状态下改 SQL 会报“数据集正在使用中”。还有一种情况是数据改了但界面不刷新,比如选课成功后 DBGrid 还是旧数据,这时调用 AdoQuery1->Requery 或者先 Close 再 Open 都能解决。

5. 避坑与排查:连接变黑、字段保留字与人数超限

5.1 BDE 字体不变黑

现象:按指导书操作,ODBC 数据源已经添加成功,但回到 BDE 后 odbc1 的字体始终是灰色,Open 也没有反应。

原因:ODBC 管理器里添加的数据源没有正确挂到 BDE 的 odbc1 上。常见做法是添加完数据源就急着回 BDE 点 Open,漏了 BDE 右侧的 ODBC DSN 面板选择这一步。

解决:回到 BDE Administrator,看右侧面板找 ODBC DSN 区域,在空白处右键,选择刚注册的数据源名,让 odbc1 真正关联到这个 DSN,然后右键 odbc1 先 Apply 再 Open。字体变黑的判定条件是最直观的,黑不了就说明物理连接没建立。

5.2 换一台机器就报找不到数据源

现象:项目在自己机器上跑得好好的,拷到机房另一台机器编译运行,点开数据库连接直接提示找不到数据源。

原因:ODBC 数据源是系统级的配置,注册在配置表里,不随项目文件迁移。换机器后,新机器上没注册同名 DSN,程序自然找不到。

解决:机房统一使用时,在每台机器上按第 2 章的流程注册一次同名数据源;或者改用连接串直连方式,把 Provider=MSDASQL.1;Driver={Microsoft Access Driver (*.mdb)};Dbq=数据库路径 直接写进代码。从交付角度讲,我倾向于把两种方式都写进报告,说明各自适用条件,老师会认为你考虑到了环境移植问题。

5.3 中文字段名引发保留字冲突

现象:登录 SQL 用 登录密码 字段没问题,换成 密码 字段后查询直接报语法错误,或者查询结果异常。

原因:Access 内部把 Name、Password 这类词作为保留字,字段名直接用 密码 可能触发保留字解析问题,不同版本表现还不一样,属于比较玄学的兼容性坑。

解决:建表的时候就把敏感字段改掉,比如 登录密码 用 pwd、姓名 用 xm、地址 用 addr,SQL 里写的时候保持全部一致。如果已经建好表不想改,SQL 里用方括号把字段名包起来,例如 [密码],APower 能识别但属于绕行方案,治标不治本,报告里不建议展示这种写法。

5.4 选课人数超过限制还能继续选

现象:course 表里一门课人数限制是 30,选课人数已经到 30,再点选课按钮仍然插入成功。

原因:选课按钮的点击事件里只写了 INSERT,没有先做 COUNT 判断,或者判断用的条件写错了,比如拿课号和学号比较而不是和课号比较。

解决:在 INSERT 之前先执行 SELECT COUNT(*) FROM enroll WHERE 课号 = :kh,把结果和 course 表的人数限制做比较,小于才放行。这个逻辑要在代码里写清楚,同时在选课按钮的 Click 事件最前面加一个提示框,如果当前用户已经选过这门课就直接 return,避免重复选课。这些判断加完后,测试序列里才有东西可写。

5.5 mdb 文件放在中文目录下连接失败

现象:数据库文件在 D:\选课数据\xk.mdb 时偶尔连接失败,放到 D:\data\xk.mdb 就一切正常,同一个文件同一台机器。

原因:老版本 ODBC 驱动对中文路径的编码处理不稳定,在部分系统区域设置环境下解析路径失败,属于环境兼容问题。

解决:项目文件夹和数据库文件路径全程使用英文命名,这是最省事的规避方式。如果必须用中文路径,测试连接成功后就不要再移动文件位置,路径一旦变化连接串里的 Dbq 就要重新指向。课设报告里把这个坑写进环境配置说明,能体现你确实踩过并处理过实际问题。

6. 用 20 个测试序列把报告写扎实:对象状态与操作的正交展开

6.1 先懂“对象测试序列”再凑数

指导书要求测试部分至少包含 20 个不同的对象测试序列,很多同学看到这个要求就头疼,不知道“对象测试序列”到底指什么。按我的理解,这里的对象不是 UI 控件,而是系统里的业务实体,比如课程、选课记录、成绩,每个对象在不同状态下执行不同操作,就构成一个测试序列。它的本质是状态转换测试,写的是“某个对象处于什么状态时,执行什么操作,预期变成什么状态”。

比如选课记录这个对象,存在“已选”和“已退”两种状态。已选状态下执行退课操作,预期是记录删除且课程选课人数减一;已退状态下重复退课,预期是提示“未选该课程”。同一个对象有多个状态和多条操作路径,组合起来就是不同的测试序列。理解了这个逻辑,凑 20 个不是问题,问题是怎么组织得让老师一眼看出你是有规划地测,而不是瞎点了二十下。

6.2 一份可以抄的 20 行测试表格

下页表格是我在类似课设项目里用过的模板,按 对象数 × 状态数 × 操作数 展开,5 个对象 × 2 个状态 × 2 种操作就能到 20 条,不需要硬编。每条序列写清前置条件、输入操作、预期结果,报告里直接可用:

序号对象前置状态操作预期结果
1学生未登录输入正确学号和密码,点登录进入主界面
2学生未登录输入错误密码,点登录提示密码错误,停留在登录页
3课程可选状态按课名模糊查询返回匹配课程列表
4课程可选状态课号不存在时精确查询返回空结果,界面不报错
5选课记录未选状态选一门未选课程插入记录,选课人数加一
6选课记录未选状态选同一门课两次第二次被拦截,提示已选
7选课记录已选状态执行退课记录删除,选课人数减一
8选课记录已退状态再次退同一门课提示未选该课程
9课程人数已满继续选课提示人数已达上限,禁止插入
10成绩未录入查询学生成绩显示空记录,不报 NULL 错误

表格后面再补一段结论:测试采用等价类划分和边界值分析方法设计,覆盖了正常流程、异常输入和边界状态。这句话老师很熟悉,能表明你不是随机点的界面,而是按方法设计的。做这套表最好的时间点其实是写代码之前,因为每一条预期结果都会倒逼你补齐代码里的判断分支;边写边测容易被“正常路径能跑通就行”的心态带偏。

从那以后,我每次做课设都强制自己先列测试序列表再动手搭界面,列完表代码里的异常分支也就有了清单。这套方法帮我少改了好几轮返工,也把报告从“凑字数”变成了“真验证”。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询