机房重构开始已经一个多星期了,从最开始的理解登录到现在已经成功完成至少一次的“增”、“删”、“改”、“查”的操作,现在在七层的这个大环境下,从最开始的奄奄一息,终于变得生龙活虎起来了。 之前总是听师哥师姐们说,敲完登录一条线了,后面就会很顺利了。可是,从我来说,事实并非如此。然而,磕磕绊绊,四个字足以形容我的这些天。不过,我心态好,我可以忍受一个人花时间调代码的孤独,再说,我也可以找小伙伴、找师父帮助我,我有什么理由不成功。 我们在第一次机房收费系统的时候,就有很深的体会:完成了一次增删改查的操作,后面的路就平坦许多。而在机房重构中,这样的体会依旧出现了,只不过我出现的时间晚些,别人在敲完登录之后就有体会了,而我是在自己一次次摸索之后,完成了一些其他的功能,才有所体会的。 下面就开始进入正题,和大家一起来看看,在七层中的那些事。 首先说说,“增”、“删”、“改”、“查”。这四个对数据库的操作,思路都是一样的。总结来说,就是以下四条: 1.增、删、改(有参数的)——把数据从U层传入D层,数据库做相应修改,返回给U层一个修改提示,即成功与否; 2.增、删、该(无参数的)——根据U层操作,对数据库做相应修改,返回给U层一个修改提示,即成功与否; 3.查(无参数的)——把数据从D层传入U层,直接返回数据库中的表信息; 4.查(有参数的)——把数据从U层传入D层,找到相应的数据,返回一个符合查询的虚拟表; 做完这些,自己才体会到在上篇博客中提到的SqlHelper的好处。之前,他们都说这个好,而自己却不能理解,很想弄清楚,深入研究,还是失败告终。这一次,自己没有刻意花时间去琢磨,而是在敲代码的过程中,用着用着就明白了。下面,便是我用到的SQLHelper封装好的代码:
Public Class SqlHelper '定义变量 '获得数据库的连接字符串 Private ReadOnly strConnection As String = ConfigurationManager.AppSettings("ConnStr") '设置连接 Dim conn As SqlConnection = New SqlConnection(strConnection) '定义cmd命令 Dim cmd As New SqlCommand ''' <summary> ''' 执行增删改三个操作,(有参)返回值为Boolean类型,确认是否执行成功 ''' </summary> ''' <param name="cmdText">需要执行语句,一般是Sql语句,也有存储过程</param> ''' <param name="cmdType">判断Sql语句的类型,一般都不是存储过程</param> ''' <param name="paras">参数数组,无法确认有多少参数</param> ''' <returns></returns> ''' <remarks>2015-2-3 10:05:46</remarks> Public Function ExecAddDelUpdate(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal paras As SqlParameter()) As Boolean '将传入的值,分别为cmd的属性赋值 cmd.Parameters.AddRange(paras) '将参数传入 cmd.CommandType = cmdType '设置一个值,解释cmdText cmd.Connection = conn '设置连接,全局变量 cmd.CommandText = cmdText '设置查询的语句 Try conn.Open() '打开连接 Return cmd.ExecuteNonQuery() '执行增删改操作 cmd.Parameters.Clear() '清除参数 Catch ex As Exception Return False '如果出错,返回0 Finally Call CloseConn(conn) Call CloseCmd(cmd) End Try End Function ''' <summary> ''' 执行增删改三个操作,(无参) ''' </summary> ''' <param name="cmdText">需要执行语句,一般是Sql语句,也有存储过程</param> ''' <param name="cmdType">判断Sql语句的类型,一般都不是存储过程</param> ''' <returns>Interger,受影响的行数</returns> ''' <remarks>2015-2-3 10:05:39</remarks> Public Function ExecAddDelUpdateNo(ByVal cmdText As String, ByVal cmdType As CommandType) As Boolean '为要执行的命令cmd赋值 cmd.CommandText = cmdText '先是查询的sql语句 cmd.CommandType = cmdType '设置Sql语句如何解释 cmd.Connection = conn '设置连接 '执行操作 Try conn.Open() Return cmd.ExecuteNonQuery() Catch ex As Exception Return False Finally Call CloseConn(conn) Call CloseCmd(cmd) End Try End Function ''' <summary> ''' 执行查询的操作,(有参),参数不限 ''' </summary> ''' <param name="cmdText">需要执行语句,一般是Sql语句,也有存储过程</param> ''' <param name="cmdType">判断Sql语句的类型,一般都不是存储过程</param> ''' <param name="paras">传入的参数</param> ''' <returns></returns> ''' <remarks>2015-2-3 10:05:32</remarks> Public Function ExecSelect(ByVal cmdText As String, ByVal cmdType As CommandType, ByVal paras As SqlParameter()) As DataTable Dim sqlAdapter As SqlDataAdapter Dim dt As New DataTable Dim ds As New DataSet '还是给cmd赋值 cmd.CommandText = cmdText cmd.CommandType = cmdType cmd.Connection = conn cmd.Parameters.AddRange(paras) '参数添加 sqlAdapter = New SqlDataAdapter(cmd) '实例化adapter Try sqlAdapter.Fill(ds) '用adapter将dataSet填充 dt = ds.Tables(0) 'datatable为dataSet的第一个表 cmd.Parameters.Clear() '清除参数 Catch ex As Exception MsgBox("查询失败", CType(vbOKOnly + MsgBoxStyle.Exclamation, MsgBoxStyle), "警告") Finally '最后一定要销毁cmd Call CloseCmd(cmd) End Try Return dt End Function ''' <summary> ''' 执行查询的操作,(无参) ''' </summary> ''' <param name="cmdText">需要执行语句,一般是Sql语句,也有存储过程</param> ''' <param name="cmdType">判断Sql语句的类型,一般都不是存储过程</param> ''' <returns>dataTable,查询到的表格</returns> ''' <remarks>2015-2-3 10:05:23</remarks> Public Function ExecSelectNo(ByVal cmdText As String, ByVal cmdType As CommandType) As DataTable Dim sqlAdapter As SqlDataAdapter Dim ds As New DataSet '还是给cmd赋值 cmd.CommandText = cmdText cmd.CommandType = cmdType cmd.Connection = conn sqlAdapter = New SqlDataAdapter(cmd) '实例化adapter Try sqlAdapter.Fill(ds) '用adapter将dataSet填充 Return ds.Tables(0) 'datatable为dataSet的第一个表 Catch ex As Exception Return Nothing Finally '最后一定要销毁cmd Call CloseCmd(cmd) End Try End Function ''' <summary> ''' 关闭连接 ''' </summary> ''' <param name="conn">需要关闭的连接</param> ''' <remarks>2015-2-3 10:05:56</remarks> Public Sub CloseConn(ByVal conn As SqlConnection) If (conn.State <> ConnectionState.Closed) Then '如果没有关闭 conn.Close() '关闭连接 conn = Nothing '不指向原对象 End If End Sub ''' <summary> ''' 关闭命令 ''' </summary> ''' <param name="cmd">需要关闭的命令</param> ''' <remarks>2015-2-3 10:06:03</remarks> Public Sub CloseCmd(ByVal cmd As SqlCommand) If Not IsNothing(cmd) Then '如果cmd命令存在 cmd.Dispose() '销毁 cmd = Nothing End If End Sub End Class
敲的代码多了,对七层中的东西也是越来越熟悉了。下面,就从注册这一功能,重新感受一番七层给我的体会。 注册首先明确涉及到一个新的表,所以,第一步就是添加配置文件,
<add key="StrCard" value="CardDAL"/>
第二封装实体,将注册表(也就是卡表)的各个字段都写入实体中,以便之后的各层之间的传参数。
Public Class EntityCard Private CardNo As String Private StudentNo As String Private RegisterDate As String Private RegisterTime As String Private Balance As String Private UserID As String Private IsCheck As String Private Type As String Private CardStatus As String Public Property Card() As String Get Return CardNo End Get Set(value As String) CardNo = value End Set End Property Public Property Student() As String Get Return StudentNo End Get Set(value As String) StudentNo = value End Set End Property Public Property RDate() As String Get Return RegisterDate End Get Set(value As String) RegisterDate = value End Set End Property Public Property RTime() As String Get Return RegisterTime End Get Set(value As String) RegisterTime = value End Set End Property Public Property BL() As String Get Return Balance End Get Set(value As String) Balance = value End Set End Property Public Property ID() As String Get Return UserID End Get Set(value As String) UserID = value End Set End Property Public Property Check() As String Get Return IsCheck End Get Set(value As String) IsCheck = value End Set End Property Public Property CardType() As String Get Return Type End Get Set(value As String) Type = value End Set End Property Public Property Status() As String Get Return CardStatus End Get Set(value As String) CardStatus = value End Set End Property End Class
第三创建接口方法,可根据需要自行创建,比如:添加学生,注册卡号等等。
Public Interface Card ''' <summary> ''' 创建注册的方法 ''' </summary> ''' <param name="card"></param> ''' <returns></returns> ''' <remarks>2015-2-5 10:43:54</remarks> Function RegisterCard(ByVal card As Model.EntityCard) As Boolean ''' <summary> ''' 查询余额的方法 ''' </summary> ''' <param name="card"></param> ''' <returns></returns> ''' <remarks>2015-2-5 23:05:15</remarks> Function QueryBalance(ByVal card As Model.EntityCard) As DataTable End Interface
第四创建抽象工厂+反射,经慕夏师父的一次详细指导后,对这一层的了解也是更深刻了些。它的好处就是可以避免出现大量的case或其他选择语句,因为工厂+反射自己会去查找相对应的数据表。如,下面指向的就是注册表:
''' <summary> ''' 实例化一个DAL中的Card表的类 ''' </summary> ''' <returns></returns> ''' <remarks>2015-2-5 10:17:38</remarks> Public Function CreateCard() As IDAL.Card Return CType(Assembly.Load("DAL").CreateInstance("DAL" & "." & StrCard), IDAL.Card) End Function
第五D层实现接口的方法。这里就会用到之前封装好的Sqlhelper类,根据实际情况,选择对应的某种操作。如注册卡号(属于有参数的增操作):
''' <summary> ''' 注册新卡 ''' </summary> ''' <param name="card"></param> ''' <returns>返回一个Boolean型的值</returns> ''' <remarks>2015-2-5 12:25:04</remarks> Public Function AddCard(ByVal card As Model.EntityCard) As Boolean Implements Card.RegisterCard Dim Sql As String Dim table As Boolean Dim sqlParams As SqlParameter() = {New SqlParameter("@CNO", card.Card), New SqlParameter("@SNO", card.Student), New SqlParameter("@Date", card.RDate), New SqlParameter("@Time", card.RTime), New SqlParameter("@Balance", card.BL), New SqlParameter("@ID", card.ID), New SqlParameter("@Check", card.Check), New SqlParameter("@Type", card.CardType), New SqlParameter("@Status", card.Status)} Sql = "Insert into Card_Info Values(@CNO,@SNO,@Date,@Time,@Balance,@ID,@Check,@Type,@Status)" table = sqlhelper.ExecAddDelUpdate(Sql, CommandType.Text, sqlParams) Return table End Function
这里实现的就是增加,在这一层,不一样的也就仅仅是有无参数或不同情况下的SQL语句写法不同。值得注意的是SQL语句的写法,往往会因为写法不正确而报错。“=”前后分别是数据库中的字段和封装好的实体的名称,两个不能有任何不同。 第六B层方法封装,实现抽象工厂和接口的方法。
''' <summary> ''' 注册卡号 ''' </summary> ''' <param name="card"></param> ''' <returns></returns> ''' <remarks>2015-2-5 21:19:31</remarks> Public Function AddCard(ByVal card As Model.EntityCard) As Boolean Dim factory As New Factory.ChargeSystemFactory() Dim Acard As IDAL.Card Dim flag As Boolean Acard = factory.CreateCard flag = Acard.RegisterCard(card) If flag = True Then MsgBox("注册卡号成功", , "提示") Else MsgBox("未成功注册", , "提示") End If Return flag End Function
第七完成外观层对应方法的封装,以便调用B层方法将U层数据传入B层或返回数据给U层。
''' <summary> ''' 注册卡号 ''' </summary> ''' <param name="card"></param> ''' <returns></returns> ''' <remarks>2015-2-6 10:04:41</remarks> Public Function AddCard(ByVal card As Model.EntityCard) As Boolean Dim add As New BLL.CardBLL() Dim flag As Boolean flag = add.AddCard(card) Return flag End Function
第八U层传值。视情况,将需要传入的参数赋值给实体,从而通过调用外观层的方法,进行传参。
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click Dim CardFacade As New Facade.CardFacade Dim card As New Model.EntityCard '调用卡 card.ID = frmLogin.txtUserName.Text card.BL = txtMoney.Text card.Student = txtStudentNo.Text card.Card = txtCardNo.Text card.CardType = comboType.Text card.RDate = DateTime.Now.ToLongDateString() card.RTime = DateTime.Now.ToLongTimeString() card.Status = txtStatus.Text card.Check = "未结账" Dim flag1 As Boolean flag1 = CardFacade.AddCard(card) End Sub
上面八条就是这些天自己敲完后总结出来的一个思路吧。每次一个新功能的开始,亦或是功能的调错,自己都是按着以上八步一步一步进行的,脑海中有个清晰的思路,才得以保证自己后面的路可以走下去,或者不会因为前方一片迷茫而不敢前行。 学习心得: 机房重构进行的这些天,真是涨了不少知识。不论是遇到的错误还是一个功能的实现,都有一种收获的感觉。现在觉得七层中的这些东西也都是大同小异的了,所以说重复就是力量。刚开始的感觉一定是最不好的,但也是必须要经过的,这就是一个过程。接下来,依旧一步一步往上爬,机房重构,继续奋战~~
时间: 2024-10-03 21:50:40