zoukankan      html  css  js  c++  java
  • Nhibernate 3.0 Cookbook学习笔记 利用XML映射类

    本文基于Nhibernate 3.0 Cookbook,下载地址:http://home.cnblogs.com/group/topic/42850.html

    准备工作,下载Nhibernate:http://sourceforge.net/projects/nhibernate/files/NHibernate/3.0.0.GA/

    因为是基于Nhibernate 3.0 Cookbook,所以用的版本也是书上的一致,不是最新的。

    下面我们来说说如何通过配置类的XML文件,最后在数据库中生成相应的表。

    一 创建一个简单的类映射。

     1.新建一个类库项目:Eg.Core,并将解决方命名为:CookbookDemo。

     2.在解决方案目录下,新建一个文件夹:Lib,并将下载的Nhibernate中Required_Bin folder和Required_For_LazyLoading\Castle目录中的文件解压到些文件夹中。

     3.在类库项目:Eg.Core中,新建一个类Entity,代码如下:

    public abstract class Entity
        {
            public virtual Guid Id { get; protected set; }
        }

    4.在新建一个类:Product

     public class Product : Entity 
        {
            public virtual string Name { get; set; }
            public virtual string Description { get; set; }
            public virtual Decimal UnitPrice { get; set; }
        }

    5.在项目Eg.Core中添加一个XML文件,命名为:Product.hbm.xml,右键该XML文件,选择属性,将生成操作改成:嵌入的资源。这个很重要,不然Nhbernate会找不到你所配置的XML文件。

       打开Product.hbm.xml,配置hibernate-mapping如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Eg.Core"
    namespace="Eg.Core">
    <class name="Product">
    <id name="Id">
    <generator class="guid.comb" />
    </id>
    <property name="Name" not-null="true" />
    <property name="Description" />
    <property name="UnitPrice" not-null="true"
    type="Currency" />
    </class>
    </hibernate-mapping>

    PS:为了让配置XML时出现智能提示,在下载的NHibernate中找到configuration.xsd和nhibernate-mapping.xsd两个文件并复制到你的VS安装目录:X:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas目录即可。

     6. 这样,Eg.Core项目就完成了,点击生成,确认没有错误后,我们再新建一个控制台项目:CookBookDemo,在项目中添加对Nhibernate.dll, NHibernate.ByteCode.Castle.dll,Eg.Core.dll的引用。

     7.在CookBookDemo项目中添加配置文件:app.cofig

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
      </configSections>
      <connectionStrings>
        <add name="db" connectionString="Data Source=.;Initial Catalog=NHCookbook;Integrated Security=True"/>
      </connectionStrings>
      <hibernate-configuration
    xmlns="urn:nhibernate-configuration-2.2">
        <session-factory>
          <property name="proxyfactory.factory_class">
            NHibernate.ByteCode.Castle.ProxyFactoryFactory,
            NHibernate.ByteCode.Castle
          </property>
          <property name="dialect">
            NHibernate.Dialect.MsSql2008Dialect,
            NHibernate
          </property>
          <property name="connection.connection_string_name">
            db
          </property>
          <property name="adonet.batch_size">
            100
          </property>
          <mapping assembly="Eg.Core"/>
        </session-factory>
      </hibernate-configuration>
    </configuration>

    8 在program.cs中添加如下代码:

    using System;
    using NHibernate.Cfg;
    using NHibernate.Tool.hbm2ddl;
    
    namespace CookBookDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                var nhConfig = new Configuration().Configure();
                var schemaExport = new SchemaExport(nhConfig);
                schemaExport.Create(false, true);
                Console.WriteLine("NHibernate Configured!");
                Console.ReadKey();
            }
        }
    }

     9 将CookbookDemo设置为启动项目然后调试,控制台上输出:NHibernate Configured后再打开你的数据库,就可以看到生成的Product表了。

     二、创建一个层次结构的映射。

    比如,我们有两个具体的产品:Movie与Book,它们继承Product

    我们先来看看存储在同一张表,即Product中:

     1.在项目Eg.Core中新增两个类:Movie与Book

    public class Movie : Product
    {
    public virtual string Director { get; set; }
    }
    public class Book : Product
    {
    public virtual string ISBN { get; set; }
    public virtual string Author { get; set; }
    }

     2.因为是存在同一张表中,所以为了区别Movie与Book,在Product中增加一个字段用于将它们区分开来,所以,我们要修改Product.hbm.xml

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Eg.Core"
    namespace="Eg.Core">
      <class name="Product">
        <id name="Id">
          <generator class="guid.comb" />
        </id>
        <!--节点discriminator就是区分字段-->
        <discriminator column="ProductType" />
        <natural-id mutable="true">
          <property name="Name" not-null="true" />
        </natural-id>
        <property name="Description" />
        <property name="UnitPrice" not-null="true" />
      </class>
    </hibernate-mapping>

     discriminator 节点中的值就是区分字段,默认情况下它的值就是类的名称,所以在本例中,它的值可能为:Eg.Core.Product, Eg.Core.Book, 与 Eg.Core.Movie。当然你也可以手动的通过在类或子类节点中增加discriminator-value属性来设置该类的鉴别值。如:

    <subclass name="Movie" extends="Product" discriminator-value="Movie">
        <property name="Director" />
      </subclass>

    3.在项目中增加Movie.hbm.xml与Book.hbm.xml,注意要将生成操作改成:嵌入的资源。

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Eg.Core"
    namespace="Eg.Core">
      <subclass name="Movie" extends="Product">
        <property name="Director" />
      </subclass>
    </hibernate-mapping>
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
        assembly="Eg.Core"
        namespace="Eg.Core">
      <!--节点subclass,说明它是一个子类-->
      <subclass name="Book" extends="Product">
        <property name="Author"/>
        <property name="ISBN"/>
      </subclass>
    </hibernate-mapping>

     4.编译并执行项目:CookbookDemo,执行成功后,打开数据库,我们可以看到新生成的Product表结构如下:

     我们也可以将每个类存储在独立的表中,这也分两种情况:子类与父类之间有外键约束与没有外键约束

    有外键约束的情况

     1.Product.hbm.xml中去掉节点:discriminator,因为是存储在独立的表中,所以就不需要这个了。

     2.修改Movie.hbm.xml为:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Eg.Core"
    namespace="Eg.Core">
      <joined-subclass name="Movie" extends="Product">
        <!--key:即子类的主键,会与父类的主键建立外键约束-->
        <key column="Id" />
        <property name="Director" />
      </joined-subclass>
    </hibernate-mapping>

     3.修改Book.hbm.xml为:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
        assembly="Eg.Core"
        namespace="Eg.Core">
      <joined-subclass name="Book" extends="Product">
        <key column="Id" />
        <property name="Author"/>
        <property name="ISBN"/>
      </joined-subclass>
    </hibernate-mapping>

     4.编译并执行项目:CookbookDemo,执行成功后,打开数据库,会看到有三张表:Book,Movie与Product,且三张表的关系如下图:

    我们可以测试,如果尝试在Movie或Book表中插入Product表中不存在的ID是会报错的:

     没有外键约束时,三张表都真的是独立存储,个人感觉这时候Product表就没什么作用了。

     1.修改上面的Movie.hbm.xml为:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Eg.Core"
    namespace="Eg.Core">
      <union-subclass name="Movie" extends="Product">
        <property name="Director" />
      </union-subclass>
    </hibernate-mapping>

    2.修改上面的Book.hbm.xml为:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
        assembly="Eg.Core"
        namespace="Eg.Core">
      <union-subclass name="Book" extends="Product">
        <property name="Author"/>
        <property name="ISBN"/>
      </union-subclass>
    </hibernate-mapping>

     3.编译并执行项目:CookbookDemo.打开数据库,表之间的关系图如一下:

    三 一对多映射

    很多数据都会出现一对多的情况,我们增加一个类ActorRole,它与Movie之间的关系是一对多的。

       public class ActorRole : Entity 
        {
            public virtual string Actor { get; set; }
            public virtual string Role { get; set; }
        }

    再增加该类的XML文件:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
        assembly="Eg.Core"
        namespace="Eg.Core">
      <class name="ActorRole">
        <id name="Id">
          <generator class="guid.comb" />
        </id>
        <property name="Actor" not-null="true" />
        <property name="Role" not-null="true" />
      </class>
    </hibernate-mapping>

    修改Movie类:

     public class Movie : Product 
        {
            public virtual string Director { get; set; }
            public virtual IList<ActorRole> Actors { get; set; }
        }

    修改Movie.hbm.xml文件:

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="Eg.Core"
    namespace="Eg.Core">
      <subclass name="Movie" extends="Product">
        <property name="Director" />
        <list name="Actors" cascade="all-delete-orphan">
          <key column="MovieId" />
          <index column="ActorIndex" />
          <one-to-many class="ActorRole"/>
        </list>
      </subclass>
    </hibernate-mapping>

     all-delete-orphan表明,删除一个Movie时,与该Movie相关联的ActorRole也会被删除。

  • 相关阅读:
    其实吧
    一个很SB的方法,来开始调一个刚启动就SB的程序
    今天真的很SB
    32位程序关闭路径重定向
    WinDbg神断点
    SQLMap用户手册【超详细】

    真有敢干的
    21.递归
    16.数字大小升降排序编写
  • 原文地址:https://www.cnblogs.com/Gyoung/p/2498286.html
Copyright © 2011-2022 走看看