1-数据库连接采用把连接字符串放到配置文件中
数据库连接相关信息有可能需要更改,如数据库服务器的ip地址,用户名,密码等,为了避免到时候需多次更改数据库连接字符串信息,需要将连接字符串放到配置文件中
与数据库交互的步骤
a 使用sql语句和 数据库连接字符串 利用sqlcommand 创建command对象(){如果sql语句中有参数,使用sqlParameters创建参数数组,cmd的传参方法传入参数 }, b使用sqlConnection建立连接 数据库 。 调用执行cmd配套的三种执行cmd语句的方法
ExecuteScalar 返回得到单一值
ExecuteNonQuery 返回得到数据库受影响的行数
ExecuteReader 返回一条数据流,需要及时接收。
SqlDataAdapter 不需要显式建立连接 ,会自动开启和关闭
2-登录时加载页面
去除了登录页面的边框(会导致无法移动),所以注册了鼠标点击事件,鼠标移动了多少,窗体xy就y移动多少。
此时与数据库交互的是myExecuteScalar() 我封装的一个传入参数和sql语句的一个全局静态函数, 在公共类sqlHelp中(会返回一个object对象,第一行第一列,所以判空就可以判断是否执行成功)
ExecuteScalar()操作后则会返回一个对象,ExecuteScalar()经常使用于当需要返回单一值时的情况。例如当插入一条数据信息时,常常需要马上知道刚才插入的值,则可以使用ExecuteScalar()方法。
验证登录需要及时反馈单一值
3- 新增学生,
采用触发一个窗口类的方式,由于新增窗口会不受限,所以有三种方式。
1-单例模式。如果窗口对象已经存在,就不创建对象 {但是每个窗口都得写一个单例,麻烦}
2- 单例模式的变种,先创建对象(在此处限制数量),然后返回对象。
3-创建窗口对象时 遍历创建过的窗口对象 。 判断是否重名,如果窗口对象重名,则不创建
所以使用方法三
新增学生会加载班级下拉列表(供管理员操作 ,)。 点击确定后 会判空,检测学生是否已经存在,学生的姓名和电话绑定验证是否重复增加,不可能重名还电话相同
增加时使用ExecuteNonQuery 与数据库交互。
判重复使用ExecuteScalar
返回的是创建的学生数 ,大于0 则创建成功。
4-增加班级,
增加班级会 加载年级下拉列表 供管理员操作 , 点击后,判空,根据年级和班级绑定 判断是否是重复添加行为。
其他都和增加学生无差异
增加时使用ExecuteNonQuery 与数据库交互。
判重复使用ExecuteScalar
5-增加年级。
增加年级,不提供下拉菜单。所以我将 年级的增加和修改放到一个窗口的同一输入个框里。
通过按钮触发一个标志位,判断对年级名的修改还是增加。
默认标志位是增加。 同样判空,判重复。
6 -增加用户,会加载权限选择框,若不选择,默认不会分配权限。 同样会进行判空处理。
其他
增加时使用ExecuteNonQuery 与数据库交互。
判重复使用ExecuteScalar
/信息查询功能//
信息查询功能
1-查询学生信息
默认加载班级下拉列表
查询 ,提供 班级年级和姓名绑定查询,姓名模糊查询 ,班级名查询 ,全局查询 。 这些查询依赖
sql语句的参数化和sql语句拼接
默认是全局查询
下拉列表选中项 提供班级年级名参数和班级年级名约束
姓名输入框提供 姓名参数和姓名约束
这两种提供有2的2次方种查询方式
2-班级查询 和学生查询相同。
3-管理员查询
年级不提供查询(标识信息过少,每一年就是一个年级)
加载用户权限列表, 提供了用户名和权限绑定查询 ,用户名模糊查询 ,权限单独查询 ,
权限用户名模糊查询 。。。三种互斥条件有 2的3次方种查询
加载下拉管理名列表和权限下拉列表可以 快速方便查询是否该用户 是否有该项权限
///信息删除功能///
删除的类型是假删除
给学生 班级 年级 用户 都设置一个 存在位(IsDeleted),默认为0 ,当我要删除这个学生时,我使用update 更新这个值为1,表示已被删除。
与数据库交互 选用 myExecuteNonQuery 。 返回值大于0,则删除成功。
当然为了做到 瞒天过海。 在涉及到查询学生表 的有关操作上 ,都要加上 and StudentInfo .Isdelete=0
表示查询的是IsDeleted=0 的记录,也就是没有执行假删除的 这条记录。
删除的 方式有单条记录删除和多条记录删除
单条记录 ,使用鼠标点击单元格内容事件 DataGriView中存在 删除列 。当点击的单元格内容是删除且点击的是对应的DataGridlink控件时 就执行单条删除。
多条记录删除. DataGriView 存在 复选框列, 遍历每行数据的 复选框列,使用List容器
存放那些复选框的value值已经改变的行的标识属性,对应每张表里也就是学号,班级号 。。。用户Id
点击确定删除后 当然首先是判空处理,然后由于是多条记录的一批次删除,所以我们会开启事务
开启事务的具体步骤是
//01.调用SqlConnection对象的BeginTransaction()方法,创建一个SqlTransaction对象,标志事务开始。
//02.将创建的SqlTransaction对象分配给要执行的SqlCommand的Transaction属性。
//03.调用相应的方法执行SqlCommand命令。
//04.调用SqlTransaction的Commit()方法完成事务。或调用Rollback()方法终止事务。
//4.在进行事务操作中的注意点
//01.在调用BeginTransaction()方法开始事务之前,要打开数据库连接,否则出现异常。
02.如果在事务的Commit()方法或RollBack()方法执行前数据库连接断开或关闭,则事务将回滚。
使用 ExecuteNonQuery 与数据库交互 。
如果list .count和 ExecuteNonQuery 返回值的累加相同,则删除学生就可以执行终止事务
表明执行成功。
班级删除
班级删除 需要先执行删除全部学生,然后执行删除全部班级
这是两条sql语句 ,而且两条语句必须一批次执行,要么全执行,要么全都不执行。
设置两种存放类型的 List 容器 ,存放两条command命令的,存放命令批量删除数据的
由于班级删除,班级内的学生一定是全部删除,所以不需要用List容器存放学生的选中Id
直接使用 update 更新班级号为选中班级号的学生表。这样整张学生表的数据都会受影响。
另外一个List是存放选中复选框对应的 ClassId 。
这个classId 将 用于 指定 哪些班级要被删除,和 指定班级Id为ClassId 的所有学生表被删除。
又有一个惯例 ;当一个事务涉及到多个SQL语句时或者涉及到对多个表的操作时就要考虑用存储过程; 尽管这里没有把sql 写成存储过程,;
所以 创建command 对象的处理包含 传参,判断处理过程
就干脆创建一个commandInfo 类, 根据是否需要传参,是否是存储过程 提供三种构造函数 ,
提供对command对象的初始化
将command对象装入List容器中, 作为自定义事务处理函数ExecuteTrans的参数
这个函数中对存储过程特别处理 ,同时执行command语句
如果事务终止,则执行成功。
执行数据库交互可以选则 ExecuteNonQuery
年级删除
年级删除和班级删除相似
应该先全部删除学生,再删除班级,最后删除年级
用户删除
用户删除和学生删除相同
无论哪种删除,删除之后,都需要刷新表。重新绑定表的数据源。
/修改数据。//
修改数据之前需要加载的各种信息
由于我们加载的信息是某一条记录的若干列,也就是让属性作为索引,加载属性对应的数据
我们选择使用 ExecuteReader 进行交互 。返回值是SqlDataReader ,理解成一维数组名
返回值 必须进行判空处理 。目的是让 数据流前进下一条,存在则为true,只向前读取,读一条,丢一条 ,及时接收值
学生信息修改页面,
触发条件和触发单选删除的条件相同
提供加载班级下拉框, 提交修改数据的过程和增加数据的过程相同
班级信息修改页面
提供加载年级下拉框,提交修改数据的过程和增加数据的过程相同
年级信息修改页面
触发修改后,标志位改变,文本控件的文字改为修改, 会将将年级名称加载到文本框, 同时,需要判空,判重复
用户修改页面
提供加载权限列表,提交修改数据的过程和增加数据的过程相同
不支持对权限表的任何操作(代码现有结构的缺陷,因为我将权限控制的功能写死了 … )
/数据显示方面///
表结构数据的加载
1-创建 DataTable对象
2- 通过配置文件的数据库连接串 创建SqlConnection的实例(建立与数据库的连接)
4 使用 SqlDataAdapter cmd语句 实现数据库交互
生成 适配器对象,调用 SelectCommand,就是用cmd对象获取数据库中的数据,保存在SqlDataAdapter
5 适配器对象 填充 数据表Datatable ;并返回数据表对象。
调用者 需要绑定这个数据源。
我将此过程也封装在 SqlHelp中
下拉框的信息加载
和加载表数据相同
1-绑定数据源
2- 设置下拉框显示的成员
3-设置下拉框显示记录的标识属性
数据的恢复
和数据的删除操作类似,(是删除的逆过程)
学生恢复
直接恢复即可
班级恢复 (因为先有班级,后有学生)
先恢复班级
再恢复学生
年级恢复
先恢复年级
再恢复班级
最后恢复学生
恢复的操作 只需要将存在位(IsDeleted)更新为 1即可
我同时也创建了 已删除学生表,已删班级表,已删除年级表
我们也能对已经删除的学生,班级,年级进行搜索(但需要将搜索条件的sql语句增加一个and Student .IsDeleted =1 ),但不提供修改和删除
///权限控制
在每个用户登录时,会将用户名以静态全局变量的形式保留,同时利用ExecuteReader 方法
根据 用户名查询到用户的权限Id.
(权限越大,操作越多)
再 在用户对数据之前的所有操作前 加一道判断,管理员对数据库的指定操作 都必须大于或等于这个权限所指定的 权限Id