Why?
为什么要有泛型与Datatable,这个问题看似简单,可是实际上又包含着我们程序的深层含义。我们的程序看似是由很多东西组成的,打但是实际上就是由各种各样的数据组成的,那么如果是数据就一定会有数据类型,所以数据类型就是解决数据的一个组成部分,那么正好泛型与Datatable就是两种不同的数据类型,接下来就和小编一起来学习一下这两种类型。
What?
首先,这两个东西到底是什么呢?为什么要放在一起呢?开始的时候小编也是有这样一连串的问题!
1、泛型:
(1)度娘眼中的泛型:泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。
(2)小编理解的泛型:度娘眼中的泛型在小编看来有些抽象,接下来看看小编理解的泛型。举个栗子:我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int数据,另一个是处理string数据,但是我们没有办法,只能分别写多个方法处理每个数据类型,因为方法的参数类型不同。那么有没有一种方法,在方法中传入通用的数据类型,这样不就可以合并代码了吗?现在就需要使用泛型了!
2、Datatable
(1)度娘眼中的Datatable:是一个临时保存数据的网格虚拟表(表示内存中数据的一个表。)。DataTable是ADO dot net 库中的核心对象。它可以被应用在 VB 和 ASP 上。它无须代码就可以简单的绑定数据库。
(2)小编理解的Datatable:经过机房的实践,理解了虚拟表的概念,但是对于无须代码就可以简单的绑定数据库这一点还是不能很好的理解。
3、泛型和Datatable都可以在一定程度上处理多个类型的数据,但是他们的区别如下:
(1)泛型:
①读取数据时无需了解数据库的结构,直接按下.就可以出来了,如mylist(0).UserName
②符合面向对象的思想
(2)Datatable:
①在一定程度上破坏了封装性,不够面向对象编程,因为我们的东西是一项项取出来的;
②由于是一项项拿出来的,所以比较容易出错
③如果想要一项项拿出来,就要比较了解数据库,这样不够安全
Where?
什么时候使用这个问题对于泛型和Datatable是一样的,两个都是在查询多个数据项的时候使用 ,不同点就是在泛型和Datatable的区别上!
How?
关于怎么使用这个问题就先拿vb.net机房来举个栗子!
机房中的跟数据有关的分为两部分:1、增删改 2、查询
1、增删改:这里在sqlhelper中就会用到一个方法ExecuteNonQuery,关于它的理解如下:执行sql,返回一个整形变量,如果sql是对数据库的记录进行操作,那么返回操作影响的记录条数,所以在增删改这里的数据类型用到的是integer类型。
Datatable:
Imports System.Data.sqlClient
Public Class D_AddTeacher : Implements IDAL.I_AddTeacher
Private sqlHelper As sqlHelper.sqlhelper = New sqlHelper.sqlhelper
Public Function AddTeacher(TeacherInfo As Entity.E_AddTeacher) As Integer Implements IDAL.I_AddTeacher.AddTeacher
'定义
Dim sql As String
Dim int As Integer
Dim sqlParams As sqlParameter() = {New sqlParameter("@teacherNo",TeacherInfo.teacherNo),New sqlParameter("@teacherName",TeacherInfo.teacherName),New sqlParameter("@Password",TeacherInfo.Password),New sqlParameter("@Type",TeacherInfo.Type)}
sql = "insert into teacherInfo (teacherNo,teacherName,Password,Type)values(@teacherNo,@teacherName,@Password,@Type)"
int = sqlHelper.GetDataTableNo(sql,CommandType.Text,sqlParams)
Return int
End Function
End Class
泛型:
Imports System.Data.sqlClient
Imports IDAL
Public Class D_Checkrecord : Implements IDAL.I_Checkrecord
Private sqlHelper As sqlHelper.sqlhelper = New sqlHelper.sqlhelper
Public Function CheckUser(UserInfo As Entity.E_Checkrecord) As List(Of Entity.E_Checkrecord) Implements I_Checkrecord.CheckUser
'定义一个变量接收sql语句
Dim sql As String
'定义一个泛型变量
Dim mylist As New List(Of Entity.E_Checkrecord)
'定义一个DataTable类型的变量
Dim dt As New DataTable
'自定义接收变量
Dim sqlParams As sqlParameter() = {New sqlParameter("@UserID",UserInfo.UserID)}
sql = "select * from LoginUser where UserID=@UserID"
dt = sqlHelper.GetDataTable(sql,sqlParams)
'把dt转化为泛型
mylist = ConvertHelper.ConvertHelper.convertToList(Of Entity.E_Checkrecord)(dt)
Return mylist
End Function
End Class
泛型这里需要注意的一点就是:实体层中定义的变量名和变量类型必须和数据库中相应的数据项一致,否则无法进行!这里比Datatable多定义了一个 Public Class ConvertHelper,如下:
Imports System.Reflection
Module ConvertHelper
''' <summary>
''' 因为sqlhelper中都是datatable类型的,所以需要写一个函数来转换一下
''' </summary>
''' <remarks></remarks>
Public Class ConvertHelper
'将datatable类型转化为泛型集合
Public Shared Function convertToList(Of Turn As {New})(ByVal dt As DataTable) As IList(Of Turn)
'定义最终返回的集合
Dim mylist As New List(Of Turn)
'得到实体类的类型名
Dim myType As Type = GetType(Turn)
'定义行集
Dim dr As DataRow
'定义一个临时变量
Dim tempName As String = String.Empty
'遍历datatable的所有数据行
For Each dr In dt.Rows
Dim myTurn As New Turn
'定义属性集合
Dim propertys() As PropertyInfo = myTurn.GetType().GetProperties()
Dim pr As PropertyInfo
'遍历该对象的所有属性
For Each pr In propertys
'将属性名称赋值给临时变量
tempName = pr.Name
'将此属性与datatable表里的列名比较,查看datatable是否包含此属性
If (dt.Columns.Contains(tempName)) Then
'判断此属性是否有setter
If (pr.CanWrite = False) Then
Continue For
End If
'定义一个对象型的变量来保存列的值
Dim value As Object = dr(tempName)
'如果非空,则赋给对象的属性
If (value.ToString <> DBNull.Value.ToString) Then
'在运行期间,通过反射,动态地访问一个对象的属性
pr.SetValue(myTurn,value,Nothing)
End If
End If
Next
'添加到集合
mylist.Add(myTurn)
Next
'返回实体集合
Return mylist
End Function
End Class
End Module
结语
对于泛型的学习目前也就告一段落,觉得很有意思,理解了很多之前不太理解的地方,在这里多谢美女娜娜的引导了,也知道了自己需要提升的一点:遇到不懂的要多多去查!加油!