ORM功能简介

一、简单对象和单表映射

DBHelper2是一个轻量级的ORM框架,提供了简单但实用的对象-关系映射功能。

  • 仅限于简单对象,即对象的属性是由简单数据类型组成的。
  • 一个简单类映射数据库的一张表,类的属性映射到表的字段。

在类及属性的定义中,可以加上attribute(特性),向编译器提供有关ORM的信息。attribute是不影响类的定义的,所以对源代码不构成侵害。同时,也不像NHibernate那样需要额外使用配置文件来定义ORM,所有的ORM配置信息都在源代码之内,程序之外不可见。

不熟悉.NET中的Attribute编程的同学可以参考:https://docs.microsoft.com/zh-cn/dotnet/standard/attributes/index

 

二、在类中定义映射

这里定义了一个类Person,它与数据库中Person.Person表对应,它的属性与表的字段对应。

Imports JiangNong.DBHelper2
 
'''<summary>
'''定义映射到数据库的类
'''</summary>
<TableMapping(Table:="Person.Person")> Public Class Person
     Inherits BusinessEntity
     <ColumnMapping(PrimaryKey:=True, Identity:=False)> Public Overloads Property BusinessEntityID As Integer
     Public Property PersonType As String
     Public Property NameStyle As Boolean
     Public Property Title As String
     Public Property FirstName As String
     Public Property MiddleName As String
     Public Property LastName As String
     Public Property Suffix As String
     Public Property EmailPromotion As Integer
     Public Property  AdditionalContactInfo As String
     Public Property Demographics As String
EndClass

1、在类定义前加入特性TableMapping,有参数:Table:="Person.Person",表示映射的表名称。如果此项省略,默认为与类同名的表。

2、只有Public(公共)类型的Property(属性)参与映射,普通字段不参与映射。

3、有一个属性加了ColumnMapping特性,参数有:PrimaryKey:=True,表示这个字段在数据库中是一个主键。同时还有Identity:=True,表示这个这段是一个自增类型的字段。自增字段在插入时不需要指定值,它会自动产生一个不断递增的唯一的值。

4、简单类中定义的属性的数据类型必须与数据库对应的字段类型兼容,否则在映射操作时无法实现类型转换而抛错。

5、ColumnMapping的另外几个参数定义

  • Column 如果属性名称与字段名称不同,可以由Column:="映射的字段名"来指定。默认为属性名称。
  • Mapping 指定在读写操作时是否参与映射:None读写都不映射,Read只在读操作时映射,Write只在写操作时映射,Both读写都映射。默认为Both。

 

三、简单类的数据库操作

1、Load

'创建DBHelper实例
Using db As DBHelper = DBFactory.CreateDBHelper
     '创建一个数据对象,赋给一个主键值
     Dim p As New Person With  {.BusinessEntityID = 10}
     '使用Load方法,默认按照主键值从数据库装载记录
     If  db.Load(p) Then
         appendText(p)
     Else
         appendText("Person not found.")
     End If
End Using

由于Person类已经定义了映射所需要的信息,在Load过程中,首先根据对象p所映射的表名、主键值、字段名等构成了一条SELECT语句,从DBHelper所关联的数据库中读取,读取的值一一赋给了p的映射属性。

Load操作的几个关键点:

  • 必须NEW一个实例,并赋给主键值
  • 如果Load成功(有记录),返回True,否则返回False
  • Load成功以后对象中即含有主键对应的记录的值

 

2、Save

         '创建DBHelper实例
         Using db As DBHelper = DBFactory.CreateDBHelper
            '由于需要保存两个对象,需要将两个Save方法放在一个事务中
            db.BeginTransaction()
            Try
                '创建主表对象,它含有一个自增字段(Identity)
                Dim b As New BusinessEntity
                '保存主表对象,自动生成的Insert语句中不包含自增字段
                db.Save(b)
                '从数据库获取自增字段的值
                Dim BusinessEntityID As Integer = getBusinessEntityID(db)
                '构建附表对象,它的主键值必须与主表对象一致
                Dim p As New Person With {
                    .BusinessEntityID =  BusinessEntityID,
                    .PersonType = "SC",
                    .FirstName = "Cougar",
                    .LastName = "Jiang"}
                '保存附表对象
                db.Save(p)
                '提交事务
                db.CommitTransaction()
                appendText("Save Record OK.")
            Catch ex As Exception
                '如果发生错误回滚事务
                db.RollbackTransaction()
                appendText("Save Record Error: " &  ex.Message)
            End Try
         End Using
 
   ''' <summary>
   '''SQLSERVER中获取自增字段的方法
   ''' </summary>
   ''' <param name="db">Insert语句关联的DBHelper对象</param>
   ''' <returns></returns>
   Private Function getBusinessEntityID(db As DBHelper) As Integer
       Return db.ReadInt(db.ExecuteScalar("select @@IDENTITY"))
    End Function

此例中Person表与BusinessEntity表有继承关系,它们使用同一个主键值:BusinessEntityID,因此在保存Person对象前,需要先保存一个BusinessEntity对象,产生一个键值,将此键值赋给Person对象。

由于要保存两个对象,所以需要将它们放在一个事务中执行,如果执行失败,必须回滚事务。

Save操作分两种情况:根据主键值判断,如果数据库中存在记录,Save相当于Update,否则相当于Insert。

 

3、Remove

         '创建DBHelper实例
         Using db As DBHelper = DBFactory.CreateDBHelper
            '创建一个对象,并赋值给非主键字段
            Dim p As New Person With {.FirstName = "Cougar", .LastName = "Jiang"}
            '指定有值的字段为查询关键字,查询记录
            If db.Load(p, {"FirstName", "LastName"}) Then
                appendText("No record to be removed.")
                Exit Sub
            End If
            '获得了主键值,按照主键来操作
            Dim b As New BusinessEntity With {.BusinessEntityID = p.BusinessEntityID}
            '开启事务
            db.BeginTransaction()
            Try
                '删除附表对象
                db.Remove(p)
                '删除主表对象
                db.Remove(b)
                '提交事务
                db.CommitTransaction()
                appendText("Record are removed.")
            Catch ex As Exception
                '回滚事务
                db.RollbackTransaction()
                appendText("Remove Error: " &  ex.Message)
            End Try
         End Using
 

在Load, Save, Remove操作中,都是根据主键值来识别对象的。主键字段是在类定义时指定的,但是也可以临时改变。上例中需要删除FirstName="Cougar",LastName="Jiang"的记录,就临时改变了主键字段:db.Load(p,{"FirstName","LastName"})

 

4、ReadEntity

         '创建DBHelper实例
         Using db As DBHelper = DBFactory.CreateDBHelper
            '将SQL的查询结果直接转换为对象
            Dim p As Person = db.ReadEntity(Of Person)("select *  from person.person where lastname=@lastname and firstname=@firstname",
 {"@lastname", "@firstname"},
 {"Jiang", "Cougar"})
            If p IsNot Nothing Then
                appendText(p)
            Else
                appendText("Entity is not found.")
            End If
         End Using

ReadEntity是使用原生SQL读取数据库记录,并自动转换为所对应的对象。它是一个泛型方法,可以返回指定类型的对象,提供的参数是SQL语句及其参数。

 

5、ReadList

         '创建DBHelper实例
         Using db As DBHelper = DBFactory.CreateDBHelper
            '将SQL的查询结果直接转换为列表
            Dim l As List(Of Person) = db.ReadList(Of Person)("select top  10 * from person.person")
            If l IsNot Nothing AndAlso l.Count > 0 Then
                For Each p As PersonIn l
                    appendText(p)
                Next
            Else
                appendText("List is empty.")
            End If
         End Using

和ReadEntity类似的,ReadList是使用原生SQL读取一组记录,并转换成简单对象列表。

 

6、SaveList

         '创建DBHelper实例
         Using db As DBHelper = DBFactory.CreateDBHelper
            '生成一个列表对象,并加入10个ErrorLog元素
            Dim l As New List(Of ErrorLog)
            For i As Integer = 8990 To 8999
                Dim r As New ErrorLog With {
                .ErrorMessage = "Test Error Message for Save List, " & i,
                .ErrorNumber = i,
                .UserName = "SaveList"}
                l.Add(r)
            Next
            '开启一个事务
            db.BeginTransaction()
            Try
                '保存10个元素的ErrorLog列表
                Dim Result As Integer = db.SaveList(Of ErrorLog)(l)
                '提交一个事务
                db.CommitTransaction()
                appendText(String.Format("List has been saved, Record count: {0}", Result))
            Catch ex As Exception
                '如果出错,回滚事务
                db.RollbackTransaction()
                appendText("Save List Error: " &  ex.Message)
            End Try
         End Using
 

SaveList是将简单对象列表中的一系列对象值保存到数据库中。

源代码:https://github.com/alibary/DBHelper2.git 

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐