您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > 基于三层架构的学生选课系统
面向对象程序设计项目教程模块四基于3层架构的学生选课管理系统模块概述在前一个模块中,实现了基于3层的课程管理,巩固了面向对象的设计理念,引入了三层架构的设计思路和实现技巧。在本模块中,应用三层架构实现完整的学生选课管理系统,包括管理员和学生的登录功能,学生的选课退选功能,管理员除了课程管理功能外的学生管理和选课浏览等功能。在此过程中,进一步理解和应用三层架构原理,理解面向对象的理念。本模块工作任务任务4-1:用户登录任务4-2:学生选课退选任务4-3:管理员的其余功能实现本模块学习目标1、熟悉三层架构的原理和应用2、理解各功能的业务流程,并在三层中设计类,逐层实现功能3、巩固OOP的基本概念和OOP的编程思路---------------------------------------------------------------------------------------------------------------------------------任务4-2:学生选课退选效果与描述学生用户登录成功后,就会将这类用户的使用界面展示出来。如下图4.1所示:图3.1学生选课退选界面在此界面中,学生用户可以看到所有课程的列表,表示可以选的课程,在此表的最后一列是选课链接,按下链接,可以进行选课;选课要符合此学生尚未选此课程、学生选课总学分小于等于8、每门课程的选课人数小于等于30的前提。若选课成功,此学生的已选课程列表、已选总学分会更新,在已选课程的最后一列是退选链接,按下链接,可以退选;退选没有条件;若退选成功,此学生的已选课程列表亦更新。已选课程列表框中的已选总学分亦随之更新。选课的业务流程:模块四基于3层架构的学生选课管理系统按下选课链接此学生已选过此课否是返回否此学生总选课学分+此课程学分超过8是否选此课程人数超过30是否添加选课记录到选课表更新选课列表和已选总学分图4.2选课的业务流程退选的业务流程:按下退选链接在选课表删除相关选课记录更新选课列表和已选总学分图4.3退选的业务流程本任务的总体业务流程:窗体展示时同时展示已选课程列表、已选总学分和可选课程列表学生选课,若不成功,及时提示;成功后,更新已选信息学生退选,成功后,更新已选信息图4.4本任务总体业务流程面向对象程序设计项目教程然后,根据业务需求,从底到高来设计每层。依据业务流程的需要,针对选课表的数据访问层类的方法有:1、当前可选课程是课程表的所有课程,其记录集合的取得在课程表的数据访问类;2、当前已选课程,要根据此学生的学号,在选课表中查询此学生所选课程,这个记录集合的获取方法,也放在选课表的数据访问层类;3、判断某学生是否选某课,既判断选课表中是否有这条记录的方法;4、由于在选课过程中需要判断此学生的已选总学分和此课程的已选人数,所以,这2个方法也需放在这个类中。5、选课的记录添加方法;6、退选的记录删除方法;依据业务流程和界面层的需要,针对选课的业务逻辑层类的方法有:1、选课方法:根据以上选课业务流程,调用数据访问层的方法,实现选课;2、退选方法:根据以上退选业务流程,调用数据访问层的方法,实现退选;3、已选课程列表方法:将数据访问层取得的记录集合,向上传递;4、根据界面层需求,还需要一个返回此学生的已选总学分的方法,将数据访问层取得的统计值,向上传递;选课退选的界面层,依据业务逻辑层的方法,设计相关控件事件中的代码,实现设计功能。1、在选课时,根据用户当前所选课程,生成选课实体类对象,传入业务逻辑层的方法作为实参。2、退选时,根据用户所选退选课程,生成退选必须的条件,传入业务逻辑层的方法作为实参。相关知识与技能4-2-1学号的获取既变量值在窗体间的传递在以上的已选课程浏览、选课、退选流程中,都需要用到此学生的学号。也就是说,如果某学生登录成功,此学生的学号应该从登录窗体传递到后续的选课退选窗体,在选课退选窗体不再需要再次收集学号。这样做,不仅保证了学号的准确性,也使整个系统更加方便的整合在一起。这也是软件系统通用的惯例之一。在Windows窗体应用程序中,如何在窗体间传递某变量的值呢?由于所有窗体都处于UI层的同一个命名空间中。因此:首先将变量定义在需使用它的窗体(选课退选窗体)中,并定义其访问修饰符为internal,此变量即可在命名空间中通用。在登录窗体中,学生用户登录成功后,实例化后选课退选窗体,将登录成功时的学号赋值给变量。此变量的值就从登录窗体传递到了选课退选窗体,在选课退选窗体中就可以应用了。代码如下:在选课退选窗体中的定义:publicpartialclassFormXKTX:Form{internalstringcurrentStuId=string.Empty;…}在登录窗体中,登录成功后的赋值:if(radioButton1.Checked)模块四基于3层架构的学生选课管理系统{StudentBizsb=newStudentBiz();if(sb.StuLogin(userId,userPassword))//登录成功{this.Hide();FormXKTXxs=newFormXKTX();//实例化选课窗体xs.currentStuId=userId;//为此窗体的学号变量赋值xs.Show();//显示此窗体}elseMessageBox.Show(学号或密码错误);}在其他类型的应用程序中,页面之间传递变量值也是常用的技巧,只是实现的方法不同,目标都是一样的。4-2-2数据访问类DBHelper类的重构在选课流程中,需要计算此学生目前选课的总学分,计算当前选此课程的学生人数。这都需要在数据访问层设计方法取得统计值。那么,就需要到数据访问类DBHelper中调用相关方法。来回顾一下,目前的DBHelper类:publicclassDBHelper{//连接字符串字段,从配置文件取值privatestaticreadonlystringconnectionString…//执行INSERT、DELETE、UPDATE等非查询命令的方法publicstaticintExecNonQuery(stringstrSQL)//执行查询命令,取得OleDbDataReader的方法publicstaticOleDbDataReaderGetReader(stringstrSQL)//执行查询命令,取得DataTable的方法publicstaticDataTableGetTable(stringstrSQL)}可见,目前并没有取得统计值的方法。来回顾一下Command对象,实例化时,必须指定的属性是conn连接对象和命令语句strSQL,常用的方法是ExecuteNonQuery()、ExecuteScalar()和ExecuteReader()。到目前为止,ExecuteScalar()方法尚未应用,此时该用了。ExecuteScalar()方法的回顾:在连接上执行Transact-SQL语句,并返回结果集中第一行的第一列。忽略其他列或行。publicstaticintGetScalar(stringstrSql){intresult;OleDbCommandcmd=newOleDbCommand(strSql,Connection);objectobj=cmd.ExecuteScalar();if(obj==DBNull.Value)result=0;elseresult=Convert.ToInt32(obj);面向对象程序设计项目教程returnresult;}此方法用形参strSql和连接Connection,实例化1个命令类对象,执行此对象的ExecuteScalar()方法,判断返回的Object是否为数据库空(DBNull.Value),若是,表示没统计值,返回0;否则将返回的对象转换为整型再返回。所以,在DBHelper类中添加新方法如下:publicstaticintGetScalar(stringstrSQL){using(OleDbConnectionconn=newOleDbConnection(connectionString)){try{conn.Open();OleDbCommandcmd=newOleDbCommand(strSQL,conn);objectobj=cmd.ExecuteScalar();if(obj==DBNull.Value){return0;}else{returnConvert.ToInt32(obj);}}catch(OleDbExceptionex){thrownewException(string.Format(执行{0}失败{1},strSQL,ex.Message));}}}定义了此方法后,在数据访问层的统计方法,就可以调用它,进行相关统计了。4-2-3异常的捕捉在上面的方法GetScalar()中,多了一个语句try..catch语句,是异常处理语句。在应用程序中,语法的错误时很容易就被编译系统检测到的,但有些错误就不会被编译系统发现,但是也会造成严重的运行故障。看下面的代码:intx=2,y=0;Console.WriteLine(x/y);这段代码是可以通过编译的,但运行时异常结束,并显示:模块四基于3层架构的学生选课管理系统像类似的异常很多,大部分是由于开发人员未预料到可能出现的边缘数据(如除数为0,记录集为空等)造成的,这就会造成程序的异常终止。如何使程序可以正常结束,即使在边缘数据不可避免出现的情况下?C#提供了异常捕捉机制来对可能出现的异常进行捕捉和保护。异常捕捉语句:try{需保护的代码段}catch(捕捉异常的类){异常捕捉到后,显示相关信息的语句}表示:如果在被保护的代码段中发生异常,则被catch段中捕捉异常的类捕捉,并显示异常相关信息,程序正常结束。其中,System.Exception类是所有异常类的基类,可捕捉到所有的异常,此类的message描述当前异常的消息。可以把上面除0的代码保护起来:intx=2,y=0;try{Console.WriteLine(x/y);}catch(Exceptione){Console.WriteLine(e.Message);}程序仍通过编译,运行结果如下:此时,虽然有异常,但程序仍正常的而结束,并给出异常信息。读者应理解异常保护的方法和代码书写方法,在今后的学习中,养成给相关代码加异常保护的习惯。在上面的GetScalar()方法中,将命令的执行和统计值的获取和返回代码在try块中保护起来,在catch块中用OleDbException异常类捕捉,以防可能会出现的数据库操作错误。4-2-4数据网格的columns集合面向对象程序设计项目教程在以上章节观察到,数据网格DataGridView可以用来展示数据表、数组或泛型集合中的数据,在默认情况下,数据网格中的列包含表、数组或泛型集合中的所有列。数据网格中的列也可以自定义,在选课退选模块中,就需要自定义列。自定义的列可以是:DataGridViewButtonColumn列、DataGridViewCheckBoxColumn列、DataGridViewComboBoxColumn列、DataGridViewImageColumn列、DataGridViewLinkColumn列、DataGridViewTextBoxColumn列,分别表示按钮列、复选框列、下拉框列、图片列、链接列、文本列。以前用的都是文本列,在选课退选模块中,需要用到文本列和链接列。在数据网格的Columns集合中,选择“添加”按钮,可以添加各种类型的列,如下图所示:1、自定义文本列添加了自定义文本列后,除了列宽和外观的设置外,要注意列所绑定的数据库列。由于在已选课程或可选课程的列表中,都有1列是课程号,其在数据库中的字段名为courseid,所以,此自定义列就要设计其DataPropertyName属性为courseid,进行数据库列的绑定。2、
本文标题:基于三层架构的学生选课系统
链接地址:https://www.777doc.com/doc-5594007 .html