大家好,又见面了,我是你们的朋友全栈君。
原创作品,出自 “晓风残月xj” 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj)。
由于各种原因,可能存在诸多不足,欢迎斧正!
1需求分析
生活在21世纪,我们每个人的日常生活免不了跟银行打交道。安全、规范、操作简单、功能齐全的银行管理系统能使业务得以顺利流畅的办理,使人们获得极好的用户体验。基于这样的背景,我的选题是银行管理系统。
日常生活中的银行管理系统很复杂,对安全性和完整性要求都很高。在此我运用数据库课上所学知识,结合自己平时的银行业务体验,认为一个合格的银行管理系统至少应该具备以下几点要素:
1.安全性,不会泄露相关信息,造成损失;
2.功能齐全,各种业务可以高效办理;
3.操作简单,可以快速上手。
为了兼备以上的要素,我认为银行管理系统至少需要4类用户的参与,他们依权限可以分为银行注册师、银行营业员(以下简称营业员)、存款用户、贷款用户。
银行注册师负责登记银行信息,主要包括银行名、所在城市、总资产等。
营业员负责开户、销户,即处理客户信息,包括用户名、所在城市、所住街道,并根据客户需求是存款还是贷款分配密码和授予权限;此外,银行员工可能因为工作需要要完成各类查询、删除等工作。银行员工是整个数据库中权限较大的用户,他能看到整个银行系统客户信息以及相关的交易记录。
贷款用户属于整个数据库的底层用户,他只能在开户后根据权限登录到相应的窗口界面完成查询与贷款。在查询工程中,为了整个数据库的安全性,他只能看到自己的信息。
存款用户也属于整个数据库的底层用户,它只能在开户后根据权限登录到相应的窗口界面完成查询与存款。在查询工程中,为了整个数据库的安全性,他也只能看到自己的信息。
2数据库(DB)设计
为了完成整个数据库银行管理系统的开发,首先要设计数据库:按用户的观点对数据和信息建模,从现实世界中抽象出概念模型。整个银行管理系统可以首先预定义几个用户,如银行注册师、营业员,因为我的整个系统主要是服务广大的客户,包括存款用户与贷款用户。整个数据库有5个在现实世界中区别于其他对象的“事物”或“物体”,称之为实体(Entity)。5个实体分别为银行(Branch)、客户(Customer)、贷款(Loan)、存款(Account)、用户(User),他们共同构成了整个银行管理系统的实体集(Entity Set)。以下是各种实体所包含的所有信息,它们描述了实体集中所有成员的特征,我们称之为实体的属性(Attribute):
Branch(Branch_Name、Branch_City、Assets);
Customer(Customer_Name,Customer_City,Customer_Street);
User(User_Name,User_Pswd,User_Type);
Loan(Loan_Number,Branch_Name,Amount);
Account(Account_Number,Branch_Name,Balance);
上面的实体彼此之间并不是孤立的,他们之间有一定的约束关系,称之为联系(Relationship)。整个数据库中的联系很多,他们中有的是一一对应的关系如一个客户只能开一个户,而开过户的登陆口令和密码只能被一个客户持有,即一个User对应一个Customer;有的是一对多,如一个客户可以办理多笔代贷款,即一个Customer对应多个Loan;有的是多对一,如多个贷款号同时被一个银行拥有,即多个Loan_Number对应一个Branch;还有的是多对多的关系,如一个客户办理多笔存款,一笔存款被多个客户拥有。上面四种联系是在银行管理系统中经常用到的,他们共同构成了整个银行管理系统的联系集(Relationship Set)。
有了实体集和联系集,就可以将整个现实世界中的银行管理系统进行2级抽象,得到机器世界即DBMS支持的数据模型(Data Model),用于数据库银行管理系统的实现。
我的整个数据库的设计是基于实体–联系模型(Entity-Relation Model)的,处理该类问题的关键是设计正确全面的E-R图。
说明:为了防止过于混乱,上述E-R省去了部分一一对应关系。
在整个数据库中,完整性是很重要的。数据库的完整性是指数据的正确性和相容性。主码的各个属性不能为空和主码值唯一;当更新、删除、插入一个表中的数据时,通过参照引用相互关联的另一个表中的数据,来检查对表的数据操作是否正确。完整性包括3个部分:实体完整性、参照完整性、用户定义完整性。以上有的表中属性是两外一个表的主码,我们称为外码参照(Reference relation)。正确的外码参照关系是整个数据库系统正确性、安全性的保证。我的银行管理系统有着规范、正确的外码参照关系。以下是我的银行系统模式图。
3.数据库实现
有了E-R图,剩下的工作就是将对应的E-R图正确的翻译为表,从而被计算机中数据库管理系统处理。上述E-R图中我已将可以合在另一张表中的联系集合并了,剩下不能合并的都是多对多关系,这类联系集是不能被合并到任何一张表中的。E-R图中一个实体集或联系集对应数据库中的一张表,实体集或联系集上的属性对应表中的列。
有了表的大致框架,我们要做的就是在计算机中存储信息。要存储,就要涉及数据结构,即每张表中每个属性分配什么样的存储单元。既要毫无遗漏的存储所有信息,又要做到尽可能的节约存储空间。在我们平时开发的应用程序中,就是要考虑要一些较为高级的数据结构,如字典树、线段树、哈希表等等。但由于存储过程是交由数据库管理系统(DBMS)来实现的,即我在开发银行管理系统时不用关心具体物理存储甚至是逻辑存储过程。表中的数据类型都是在实际需求与节省存储空间二者之间权衡的折中方案。
我们只需编写正确高效的应用程序,来适应不同类型用户的查询与办理相关业务的需求。
说明:在数据库中,我的整个银行管理系统的各种约束关系、一致性原则等都是通过自己编程来实现的。这个在下面的具体设计会详细解释。
1.银行注册师
这个用户是事先存在User表中的,他的权限是注册银行相关的工作。包括添加、删除、修改、查询。其中添加、查询只涉及一张表,即Branch表;但修改、删除就涉及多张表了,而且要保证修改、删除的银行信息元祖是客观存在的,即级联删除、级联修改。要保证修改或删除的元祖是存在的,可以在修改删除一直查询一下该元素是否存在。若不存在,输出相应的提示信息,并撤销相应的操作;如果存在,则根据外码参照关系来处理。在本系统中,所有的修改操作都能修改主码,这符合时下的一些数据库设计潮流。
2.营业员
对于营业员,他的工作就是开户、销户,修改客户个人信息以及按类型查询相应的信息,包括用户信息和银行信息。开户时首先得查询该用户是否开过户,若没开过就给他开户,否则输出相应的提示信息。销户由于设计的表比较多,我精心设计了一下。撤销一个用户,首先查询他是否存在,在这样的用户客观存在的情况下然后执行删除相应表中该客户的信息。由于涉及多张表(Customer表,User表,Loan表,Account表、Depositor表、Borrower表,共6张),且它们中存在一对多关系,如Customer—Depositor,Customer—Borrower;同时存在多对多关系,如Customer—Account,Customer—Loan。要删除一个客户,就得删除他的存款与贷款方面的信息。修改时也存在相应的完整性约束。
这本来在SQL Serve中注意一下删除顺序,做几个笛卡尔积就可以的。但由于用VC编程,一张表关联一个类,给编程带来一定的困难。对于多张表的笛卡尔积,我有4种想法。
解决方案1:
直接在数据库中表与应用程序中类一一对应的基本上,寻找有效的可行方案。即直接写带笛卡尔积的查询语句,然后单张表查询。事实证明该方案是不可行的。虽说一下打开了整个数据(m_database.Open(_T(“BANKDB”))),但是一张表有且只关联一个类,返回值为该类型。例如Customer表中关联CCustomerSet类,不能试图通过它直接获取其他任何表中的信息。该方案是不可行的。
解决方案2:
在知道一张表有且只关联一个类的基础上,结合C++中类的继承关系,我试图自定义一个类,继承要做笛卡尔积的所有表。如我要求一个用户的所有贷款信息,涉及3张表,Loan表、Borrower表、Customer表,其中Customer表提供用户名Customer_Name,然后就是剩下的Loan表、Borrower表做笛卡尔积,可以尝试自定义一个BorrowerLoan类,如下:
Class BorrowerLoanSet
{
LoanSet m_LoanSet;
BorrowerSet m_BorrowerSet;
};
这样做就得具体看看Open(CRecordset::snapshot,Cstring strSQL),由于对VC底层和数据库打交道的具体机制不熟,导致产生自定义一个涉及多张表的类,事实证明这个方案也是不可取的。
解决方案3:
要处理多张表,可以先尝试把其中一张标的作为另一张表的主键的信息存起来,开个数组或调用C++中容器。然后再根据第一张表中得到的并存储起来的信息在第二张表中查询…知道处理完所有的表为止。这个方案是完全可行的。
还是解决方案2中的问题,Loan表、Borrower表做笛卡尔积,可以理解为先对Borrower表进行查询,记录中间过程结果,然后根据中间结果查询Loan表。对应伪代码为:
For(Borrower表中的所有记录)
{
If(该记录的Customer_Name就是我们所需的)
存到容器Vector中;
}
For(Loan表中的所有记录)
{
If(该记录的Loan_Number在Vector容器中)
该记录就是我们所需的;
}
上述判断Loan表中的Loan_Number是否在Vector中可以用哈希表的思想,将Loan_Number映射到一个map中,实现时间复杂度O(1)判断每条Loan表中的记录是否在Vector容器中。此方案是可行的。
解决方案4:
这个方案的基本思想就是多重循环。要做笛卡尔积,不能直接在VC中写SQL语句但可以通过编程模拟笛卡尔积的过程。猜想在数据库内部笛卡尔积就是通过高效的多重循环来实现的。Loan表、Borrower表做笛卡尔积,选取Borrower表中Loan_Number和Loan表中Loan_Number相等的,组合起来的信息就是我们要查的。模拟笛卡尔积的过程如下:
For(Borrower表中的每个元祖)
{
If(元祖b的Customer_Name是要查的)
{
For(Loan表中的每个元祖)
{
If(Loan中的元祖l,使得l.Loan_Number=b.Loan_Number)
{
Borrower表和Loan表中对应元祖的组合信息就是我们所要的
}
}
}
}
我实现Loan表和Borrower表做笛卡尔积(在两者Loan_Number相等的情况下)的代码见附件1
3.存款者
对于存款者,他可以选择办理存款业务,办理成功给出“业务办理成功”提示。若选择办理业务的银行不存在,则给出提示,防止在底层数据库中出错。具体的实现是先查询一次看看办理业务的银行是否存在,若不存在则给出提示。提前给出提示比在数据库中违反外码参照关系导致错误要健壮、鲁棒得多。同时根据现实需求,该客户是可以查询自己的交易记录的,处于安全性考虑,他仅能看到自己的交易记录,别人的交易记录他是没有权限访问的。同时,他也可以查询银行信息,做到对比分析,得到对自己最有利的存款方案。其中涉及多张表的处理用的方案同上面解决方案4,在此不再不说。
4.贷款者
对于贷款者,他的权限很大程度上和存款者一样。他可以办理贷款业务。查询自己的交易记录和银行相关信息。功能与具体编程实现同上面的存款者,区别在于存款者操作的是Account表和Depositor表,而贷款者操作的是Loan表和Borrower表。当然二者的界面是不一样的。为了避免重复,在此就不再赘言了。
为了尽可能的符合现实生活中的银行管理系统,我的程序写得比较大。下面是一些具体数据:
为了方便开发,我的变量、函数、类、资源等都用相应的英文表示,做到了见名知意。
以下是我程序中的类视图:
关于各个类的功能说明,见附件2.
4.我的特色
1.尽可能避免数据冗余
首先,作为一个数据库系统,我的银行管理系统尽可能避免了数据冗余。数据库编程时开发者并不需要关心具体的存储过程,即我们并不关心数据是怎么存储的,这些数据库系统已经帮我们做了。但我们应该组织好数据的存储,即决定存储那些数据,存在那张表中。这些都是大有学问的。结合数据库中范式的知识,我对书上的银行管理系统进行加工并加入了自己的表User,但是整个系统并没有出现严重的数据冗余。
2.外码参照关系
我的银行管理系统模式图中关系是很密集的。为了回避直接在数据库中建立关系图带来操作上的困难,我的外码参照关系都是自己编程实现的。例如某个客户带了笔款,马上将相关信息插入Account表和Depositor表中。又如要撤销某个客户,需要级联删除,为了保证完整性约束,需编程实现删除与该客户相关的所有交易记录,包括Account表和Depositor表、Loan表和Borrower表、Customer表、User表等等。先插主键,后插外键;先删外键,后删主键。
3.笛卡尔积的处理
可能具体所来不应该叫笛卡尔积或不全叫笛卡尔积,有时是自然连接等等。我想到了4中解决方案,最后用到了其中最为高效的利用多重循环模拟笛卡尔积的过程。具体实现在上面展开过,在此就不再重复。
4.程序功能齐全
模拟现实生活中的银行管理系统,功能较为齐全,安全性也有保证。具体说来解决了以下几个主要问题:
(1)、首先营业的银行得到注册师那里登记。只用登记了的银行才能接受办理各类业务。
(2)、营业员可以完成开户、销户工作,并看到和查询所有的交易记录、银行信息。
(3)、客户只有通过营业员开户后才能登陆系统并办理相关业务;销户之后就不能登陆了。
(4)、每个客户可以办理存款、贷款业务,同时查询所有银行信息和自己的交易记录。当且只能看到自己的交易记录是符合安全性的。
(5)、一个客户可以办理多笔业务,一笔业务可以被多个客户持有。
(6)、插入、删除、修改时的正确性、一致性得到保证。
5.调试分析与解决方案
总结编程过程中遇到的问题,回顾解决方案是件很有意义的事。在用VC对数据库编程的过程中,我遇到了很多问题。有数据库方面的,也有MFC方面的等等。这些问题可以归结为两类:语言方面的、逻辑方面的。下面我选取一些典型的加以分析。
问题1
数据库编程编译链接无错误,运行时崩溃。根据编程经验,我知道这可能是数据库方面出错了。经过一段时间的查找,发现是在打开一个对话框窗口并显示所有记录时忘记事先打开数据库。在对话框的OnInitDialog()中添加一条m_database.Open(_T(“BANKDB”))语句就可以解决。
问题2
在进行主对话框(我都是用的模态对话框)向子对话框传参时出问题。我打算在打开一个子对话框时通过主对话框向其传递一个参数,尝试定义对话框对象实例,其包含需要传递的参数变量,在DoModal()函数前对其赋值。如下例子:
DepositorAccountDlg dlg;
dlg.m_Customer_Name=m_CUserName;
dlg.DoModal();
但在子对话框中用该变量时出错。后来通过查找资料,知道在对话框未被调用DoModal()创建之前其内存单元是不存在的。对一个为分配内存单元的实例变量赋值必然导致错误的产生。但可以通过指针来解决上述问题。首先给子对话框实例分配内存单元,然后对其成员变量赋值,最后调用DoModal()创建子对话框就可实现对话框之间的参数传递。上例正确解决方案如下:
DepositorAccountDlg *dlg=new DepositorAccountDlg;
dlg->m_Customer_Name=m_CUserName;
dlg->DoModal();
问题3
在对窗口添加背景图片时未能如愿显示图片。在上网百度之后发现是没有添加相应的详细响应机制即添加WM_PAINT消息。虽然添加了相应的响应函数,但并没有关联上相应的消息响应机制WM_PAINT消息,即系统不会自动调用添加的响应函数,只有在收到相应消息后才能对其进行处理。这点完全体现了Windows编程的消息响应、事件驱动特点。
问题4
当对控件关联的变量类型进行修改时只修改了类中的定义部分,未对相应的构造函数进行修改,导致报错。造成错误的原因是平时windows编程体验太少,对其中的基本机制不熟。
问题5
涉及多张表的处理,笛卡尔积或自然连接等等。开始时直接用在SQL Serve中的语句在VC中进行编程,导致报错。查找原因的同时,我明白ODBC方式连接数据库时数据库中的一张表当且仅关联VC中的一个类。这就说明涉及多张表示不可能直接套用SQL Serve中的语句,而应该开发者自己编程实现。我想到了上面所讨论的4中初步解决方案,最终选择了哟管多重循环来模拟笛卡尔积。至此问题迎刃而解。
问题6
依照实际需求建立外码参照关系,即在数据库中画好关系图,然后进行插入有外码参照关系的元祖时数据库系统报错。当时我也遵循了先插主键后插外键的指导思想。由于平时SQL Serve中编程体验不多,最终没能正面解决。于是我删除了数据库中的关系图,转而自己编程来控制插入等涉及多张表的操作。比如插入时,先判断外键是否在被参照关系表中客观存在;如果存在才进行插入操作;否则程序给出提示信息,避免数据库系统直接在运行时崩溃。具体做法是对照我的银行管理系统模式图,结合程序的实现功能,一一对应的编程完成外码参照关系。
问题7
为了优化程序同时保留程序的基本功能,我试图代码重用,具体说来大到对话框类重用,小到某些功能相近的函数重用。我建立了一个基本对话框类,其他类都以他为基类继承其部分功能,然后派生出自己特有的功能,用到了虚函数、同名覆盖等。但最终没有达到所有的目的。主要原因是我的不同对话框即使是平行对话框在功能上也有相当大的区别,控件不同,文本及背景要表现的主题也大相径庭。如果一味追求代码的重用,得不偿失。所以我最终放弃了最初的想法,转而在一些功能相近的函数上实现重载、嵌套调用等来减少代码的文本量。我知道在上述优化之后,代码量是减少了,但程序的效率,包括时间复杂度、空间复杂度并没有得到本质上的提高。
6.数据库课设心得体会
在本次数据库课程设计之前,通过几次上机实习,我基本掌握在SQL Serve中创建表,完成简单的插入、删除、修改、查询等操作。但对整个数据库管理系统的运行机制缺乏必要的、正确的理解,而且本次课设老师要求在VC环境下编程,完成可视化。可以说,这次课程设计,我收获颇丰。总结来看,可以分为两方面,技术层面与学习能力层面。
首先说说技术层面。在本次课设之前,我对数据库的了解非常肤浅,极不系统。本次数据库课设,我选择了银行管理系统,确定选题后,就要进行需求分析,从现实世界中提取信息,加以抽象概括,从用户需角度对数据和信息建模,建立一个信息世界的概念模型,建立正确完备的E-R图是十分必要的。由于这个管理系统最终是由计算机来支撑运行的,所有光有银行管理系统的概念模型是远远不够的。开发者需要从计算机角度对存储并处理数据,最终建立一个机器支持的数据模型,具体到我的选题就是有E-R图定义的实体集与联系集创建必要高效的表。只有这样,数据才能高效的被计算机存储并处理。一个好的数据库,没有上面的工作是不行的;只完成上面的工作是远远不够的。在数据库的设计中,要尽可能的避免数据冗余,完全避免插入、删除、更新异常。因此,要结合具体选题选择合适的范式,将复杂的关系分解成等效的、相对简单的若干个关系。完成范式分解后,我们应该注重各种完整性约束。完整性约束包括算个方面的内容:用户自定义完整性、实体完整性、参照完整性。这里我重点谈谈我对参照完整性的理解。银行管理系统中有的表的主码存在于另一张表中,称前者为被参照关系,后者为参照关系。先插主键,后插外键;先删外键,后删主键。但在VC中,这样的参照完整性给初次接触数据库编程的我带来很大挑战。最终我选择通过自己编程来体现外码参照关系,回避了具体数据库对关系图的要求。首先分析清楚外码参照关系,然后设计插入删除的先后顺序以及各种约束条件,达到最终目的。关于多张表的处理也是一件比较棘手的事。主要原因是数据库中一张表通过ODBC方式只能与VC中的一个类相关联,而要进行的插入、删除、更行等操作在逻辑上涉及多张表,比如笛卡尔积、自然连接等,最终我的解决方案是通过多重循环来模拟笛卡尔积(或自然链接)的过程,循环与循环之间是通过属性相等关系来沟通的。还有,由于老师根据学长的经验要求用VC做,在本次数据库课程设计中,我也学到了很多MFC相关知识,加之期间一直在看孙鑫老师的视频,开始了解了windows编程的基本原理,消息响应,事件驱动等等,并掌握了一些窗口、对话框的开发技能。
比起技能的提升,我觉得本次课程设计更重要的是锻炼了我的学习能力。由于之前完全没有VC编程的经验,当突然被要求做MFC可视化时感到压力很大。通过对着课件边看边实验,遇到问题查找相关资料,如百度、书籍、课件、网络视频等,很快模仿了出来。然后就是着手自己的银行管理系统开发了。由于生活经验不足,不清楚各种用户的权限,通过与同学交流、到图书馆查阅相关文献等方式,我对银行管理系统有了初步的认识。然后在敲代码的过程中也遇到了对MFC不熟等问题,但最终都逐一解决了。常听人说,程序员必须具备自主学习能力。很多时候遇到的问题都是陌生的,只有善于利用各种资源学习相关知识的程序员才能脱颖而出。
7.运行截图
8.附件
附件1
/***********************************************
*功能:按查询项查询贷款客户信息
*
************************************************/
BOOL CustomerRecord::ListWANT(CString strSQL)
{
m_Customer_Reocrd_List.DeleteAllItems();
CLoanSet m_CLoanSet;
Try
{
if(m_CLoanSet.IsOpen())
m_CLoanSet.Close();
if(!m_CLoanSet.Open(CRecordset::snapshot,strSQL))
{
MessageBox("打开数据库失败!","数据库错误",MB_OK);
return false;
}
}
catch(CDBException *e)
{
e->ReportError();
}
int nIndex=0;
if(m_CLoanSet.IsEOF())
{
MessageBox("无该记录!","温馨小提示!");
return false;
}
m_CLoanSet.MoveFirst();
while(!m_CLoanSet.IsEOF())
{
CString strsql;
strsql.Format("select * from Borrower where Loan_Number='%s' and Customer_Name='%s'",
m_CLoanSet.m_Loan_Number,CustomerName);
{
CBorrowerSet m_BorrowerSet;
Try
{
if(m_BorrowerSet.IsOpen())
m_BorrowerSet.Close();
if(!m_BorrowerSet.Open(CRecordset::snapshot,strsql))
{
MessageBox("打开数据库失败!","数据库错误",MB_OK);
return false;
}
}
catch(CDBException *e)
{
e->ReportError();
}
if(m_BorrowerSet.IsEOF())
{
m_CLoanSet.MoveNext();
continue;
}
m_BorrowerSet.MoveFirst();
while(!m_BorrowerSet.IsEOF())
{
LV_ITEM lvItem;
LvItem.mask=LVIF_TEXT;
lvItem.iItem=nIndex;
lvItem.iSubItem=0;
lvItem.pszText="";
m_Customer_Reocrd_List.InsertItem(&lvItem);
m_Customer_Reocrd_List.SetItemText(nIndex,0,m_BorrowerSet.m_Customer_Name);
m_Customer_Reocrd_List.SetItemText(nIndex,1,m_BorrowerSet.m_Loan_Number);
m_Customer_Reocrd_List.SetItemText(nIndex,2,m_CLoanSet.m_Branch_Name);
m_Customer_Reocrd_List.SetItemText(nIndex,3,m_CLoanSet.m_Amount);
m_BorrowerSet.MoveNext();
nIndex++;
}
m_BorrowerSet.Close();
}
m_CLoanSet.MoveNext();
}
m_CLoanSet.Close();
return true;
}
附件2
BranchDlg:表示银行注册师对话框类
BranchRecordDlg:表示存款者查询银行信息的话框类
CAboutDlg:建立对话框的系统类
CAccountSet:表示Account表关联类
CBANKDBMFCApp:建立BANKDBMFC工程系统分配的类
CBANKDBMFCDlg:建立BANKDBMFC工程系统分配的对话框主类
CBorrowerSet:表示Borrower表关联类
CBranchSet:表示Branch表关联类
CCustomerSet;表示Customer表关联类
CDepositorSet:表示Depositor表关联类
CDepositorFindBranchDlg:表示存款者查询银行信息的对话框类
CDepositorFindCustomerDlg:表示存款者查询自己交易记录的对话框类
CLoanSet:表示Loan表关联类
CLoginDlg:表是登陆主界面的对话框类
CCUserSet:表示Use表关联类
CCustomerDlg:表示营业员登陆主窗口的对话框类
CCustomerRecordDlg:表示存款者查询自己交易记录的对话框类
DepositorAccountDlg:表示存款者主对话框类的对话框类
LoanBorrowerDlg:表示贷款者主对话框类的对话框类
ShowAllTradeDlg:表示营业员查询客户交易记录的对话框类
附件3
void CLoginDlg::OnOK()
{
UpdateData();
if(m_CUserName=="")
{
MessageBox("请输入用户名","错误提示",MB_OK);
return ;
}
if(m_CUserPassWord=="")
{
MessageBox("请输入密码","错误提示",MB_OK);
GetDlgItem(IDC_PASSWORD)->SetFocus() ;
return;
}
CUserSet m_CUserSet;
CString strSQL;
strSQL.Format("select * from [BANKDB].[dbo].[User] where [User_Name]='%s' and [User_Pswd]='%s' ", m_CUserName,m_CUserPassWord);
m_CUserSet.Open(AFX_DB_USE_DEFAULT_TYPE,strSQL);
if(!m_CUserSet.IsEOF())
{
CDialog::OnOK();
if(3==m_CUserSet.m_User_Type)//管理员
{
BranchDlg dlg;
dlg.DoModal();
CLoginDlg Dlg;
Dlg.DoModal();
}
else if(2==m_CUserSet.m_User_Type)//银行职工
{
CustomerDlg dlg;
dlg.DoModal();
CLoginDlg Dlg;
Dlg.DoModal();
}
else if(1==m_CUserSet.m_User_Type)//取款人
{
DepositorAccountDlg *dlg=new DepositorAccountDlg;
dlg->m_Customer_Name=m_CUserName;
dlg->DoModal();
CLoginDlg Dlg;
Dlg.DoModal();
}
else if(0==m_CUserSet.m_User_Type)//贷款人
{
LoanBorrowerDlg *dlg=new LoanBorrowerDlg;
dlg->m_Customer_Name=m_CUserName;
dlg->DoModal();
CLoginDlg Dlg;
Dlg.DoModal();
}
}
else
{
MessageBox("用户信息不正确,无法登录!","错误提示",MB_OK);
return ;
}
CDialog::OnOK();
}
以上是我最近课程设计报告,有很多不足之处,欢迎大家指出,我定及时改正!谢谢!欢迎交流!
相关代码下载见源码地址 ,在此说明,由于上传容量限制问题,上传的代码去掉了resource文件,所以可能不能运行,如要完整运行,请下方留下方式。
当然,如果大家觉得写博客着实不易,或者代码对你有所帮助,资助几毛钱也是可以的,在此表示感谢。下面是支付宝二维码:
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/144540.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...