代码改变世界

NHibernate Begginner Ch4

2011-07-03 22:13  一一九九  阅读(218)  评论(0编辑  收藏  举报

Our next major hurdle in the implementation of NHibernate is database mapping. In the last few chapters, we learned how to create tables to hold our data and how to create classes to hold that data in our application. Now we need to create the glue to bring them together.

Simply put, we need to tell NHibernate about the database that we created and how the fields and tables match up to the properties and classes we created. We need to tell NH how we will be assigning Primary keys, the data types that we will be using to represent data , what variables we will store them in , and so on.

Types of mapping

 there are two basic ways to map data for NHibernate: the traditional XML mapping in an hbm.xml file, or the newer “Fluent NHibernate “ style , which is smilar to the interface pattern introduced with the .net3.5 framework.

todo: 了解 interface pattern : www.martnflower.com/bliki/fluentInterface.html

XML Mapping

     the two biggest complaints about XML mapping is the verbosity of the text and that it is not compiled. We can handler some of the verbosity by limiting the amount of data we put into the document. There are a number of optional parameters that do not absolutely need to mapped, but that provide additional information about the datbase that can be incluede.

without compilation, when the database changes or the classes change, it’s difficult to detect mismatches until the applicaiton is actually executed and nhibernate tries to reconcile the database structure with the mapping classes.

NH通过采用Object的静态编译的方式来避免了之前采用DataSet的形式导致的字段名的不可编译性,不过又把这些信息集中到了hbm.xml文件中,和之前相比,相当于字段匹配都集中在某个单独配置文件中,减少了受影响的范围吧。另外关于hbm.xml文件中配置信息的多少的问题,如果想在hbm.xml中配置数据库相关的信息,那么必然导致hbm.xml的文件的内容增大。在CH1中讨论过时通过NH的tool来生成数据库还是单独创建数据库的问题,这个也会影响后面的hbm.xml文件的包含的信息的多少。

todo: 如果想在hbm.xml中配置数据库相关的信息?在进行定制化的时候是否意味着不能采用工具来生成hbm.xml文件了?之前定制的数据库相关的信息都会被清空和删除?

Tips:Copy the nhiberante-mapping.xsd and nhibernate-configuration.xsd to $(vspath)/common7/packages/schemas/xml

HBM.XML

xml document

<?xml version=”1.0” encoding=”utf-8”?>

hibernate-mapping tag
        <hibernate-mapping xmlns=”urn:nhibernate-mapping-2.2”  namespace=”XXXXX”  assembly=”xxxx”>
         </hibernate-mapping>
         xmlns attribute is the xml namespeace the NHibernate mapping file should be validated against. This is directly related to a versionof NHibernate, as each version has its own XML namespace to cover changes in the mapping language.

Classes
    
<class name=””   table=””>
       </class>
       
class tag is a key tag, it tells Nhibernate two things – the class this mapping document is meat to represent and which table in the database that class should map to.
        tips: while this can be specified in the standard fully-qualified dotted class name, a comma, and then the assembly name , the preferred method is to define the namepace and assembly in the <hibernate-mapping> tag.
        tips: technically, as the table name is the same as our class name, we could leave out the table attribute.

Properties:

     we can map properties from our class to fields in the database using the id tag and the property tag. these tags are for the standard fields in the database, not the foreign key fields.

      <property name=”Address1” type=”string”>
            <column name=”Address1”   length=”255” sql-type=”varchar” not-null=”true”/>
     </property>

ID columns

     <id name=”Id”>
              <generator class=”hilo”/>
       </id>
        This tells NHibernate that we have property in our class named ID which maps to a field in the database called Id and also that we use hilo method to automatically generate a value for this field.
         An optional attribute that I generally use on the id tag is the unsaved-value attribute. This attribute specifies what value should be returned in a new object before it is persisted(saved) to database.

RelationShips

   As this the “many” side of the one-to-many relationship, we need to use a many-to-one type to map it. Things to note here are the name and class attributes. name, again, is the property in our class that this field maps to, and class is the “other end” of the Foreign key relationship or the Contact type in this case .

      <many-to-one name=”BillToContact”class = “Contact”>
           <column name=”BillToContact_ID”/>
      </many-to-one>

   map the “many”side. In the contact mapping file,  we need to create a bag element to hold all of these OrderHeaders. A bag is the NHibernate way to say that it is an unordered collection allowing duplicated items. We have a name element to reference the class property just like all of our other mapping elements and a key child element to tell NHibernate which database column this field is meant to represent.

    <bag name=”BillToOrderHeaders” inverse=”true”cascade=”all-delete-orphan”>
          <key column=”BillToContact_ID”/>
          <one-to-many class=”classname,  assembly”/>

   </bag>

Fluent mapping

    todo: 了解fluent mapping的用法 http://fluentnhibernate.org/