NHibernate多对多关联映射的实现

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
简介: 上次用EF演示了数据库多对多关系的操作,这次我们还是引用上次的案例,来演示如何在C#当中使用NHibernate。

上次用EF演示了数据库多对多关系的操作,这次我们还是引用上次的案例,来演示如何在C#当中使用NHibernate。

首先介绍一下NHibernate框架的来源。熟悉Java编程的读者肯定知道Hibernate这个ORM。NHibernate就来源于Java中著名的ORM框架—Hibernate,这点从名称当中就能够知道。目前NHibernate的最新版本是3.3.3,好像有一阵子没有update了,说明当前的版本也比较稳定了。具体的资料可以到官网查询:http://nhforge.org/

1、下载NHibernate

官网首页就有下载链接,直接下载就可以了。

下载好之后会得到一个zip包。


我们就地解压可以看到如下目录和文件:


我们重点关注以下目录的内容:

Configuration_Templates目录:默认提供的一些配置模板。有支持Oracle、Sql Server、MySQL等等。

Required_Bins目录:这里面存放了我们开发时常用的dll文件。其中的两个xsd文件是能够提供智能提示的文件,我们需要将它们俩复制到你本地的VS的Schemas目录下,比如我的目录为:D:\Program Files (x86)\Microsoft Visual Studio 11.0\Xml\Schemas 。

复制好之后,重启VS,在我们写Hibernate配置文件时就有了智能提示了。


准备工作做好之后,我们就可以正式演示。

2、创建一个类库项目Model

我们定义好两个类,分别为Student和Subject,为了便于管理,我们将它们放到Entity文件夹里,但命名空间仍为Model。

namespace Model
{
    public enum Gender { Female, Male }

    public class Student
    {
        public virtual int? StudentId { get; set; }
        public virtual string StudentName { get; set; }
        public virtual Gender Gender { get; set; }
        public virtual DateTime? BirthDay { get; set; }

        public virtual IList<Subject> Subjects { get; set; }
    }
}
namespace Model
{
    public class Subject
    {
        public virtual int? SubjectId { get; set; }
        public virtual string SubjectName { get; set; }

        public virtual IList<Student> Students { get; set; }
    }
}
这是一个典型的多对多的应用场景。一个学生可以选修多个课程,一个课程可以被多个学生选修。

接下来我们再创建相应的Hibernate配置文件(就是普通的xml文件,取名为Student.hbm.xml和Subject.hbm.xml)。

Student.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Model" namespace="Model">
  <class name="Student" table="T_Student" lazy="true">
    <id name="StudentId"  type="int" column="StudentId">
      <generator class="native"/>
    </id>
    <property name="StudentName" type="string" column="StudentName">
      <column name="StudentName" length="50"/>
    </property>
    <property name="Gender" type="Gender" column="Gender">
      <column name="Gender" length="4"/>
    </property>
    <property name="BirthDay" type="datetime" column="BirthDay">
      <column name="BirthDay" length="20"/>
    </property>
    <bag name="Subjects" table="T_Student_Subject">
      <key column="StudentId"/>
      <many-to-many class="Subject" column="SubjectId"/>
    </bag>
  </class>
</hibernate-mapping>
Subject.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Model" namespace="Model">
  <class name="Subject" table="T_Subject" lazy="true">
    <id name="SubjectId" type="int" column="SubjectId">
      <generator class="native"/>
    </id>
    <property name="SubjectName" type="string">
      <column name="SubjectName" length="50"/>
    </property>
    <bag name="Students" table="T_Student_Subject">
      <key column="SubjectId"/>
      <many-to-many class="Student" column="StudentId"/>
    </bag>
  </class>
</hibernate-mapping>
便于管理我们同样的放到Config目录下(自己创建的文件夹)。

同时修改两个xml文件的生成操作由内容变为嵌入的资源(在vs中右键xml文件选择属性)


3、创建一个控制台应用程序

表和实体对应的内容已经定义好,下面关键的就是要写代码来测试NHibernate了,本着尽量降低学习难度的原则,我这里就用控制台应用程序来验证(你也可以新建一个类库项目,然后用VS的单元测试或者第三方测试工具NUnit进行验证)。

首先将下载的开发包里面的Configuration_Templates文件夹下的MSSQL.cfg.xml复制到控制台应用程序中(为方便管理,我新建了一个Config文件夹,并把这个xml文件放到这里面,重命名为hibernate.cfg.xml)。

修改这个xml文件内容为:

<?xml version="1.0" encoding="utf-8"?>
<!-- 
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it 
for your own use before compile tests in VisualStudio.
-->
<!-- This is the System.Data.dll provider for SQL Server -->
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
  <session-factory name="NHibernate.Test">
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string">
      Server=.;database=nhibernateTest;uid=sa;pwd=123456;
    </property>
    <property name="adonet.batch_size">10</property>
    <property name="show_sql">true</property>
    <property name="hbm2ddl.auto">update</property>
    <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
    <mapping assembly="Model"/>
  </session-factory>
</hibernate-configuration>
注意这里面的一些节点的配置。比如mapping assembly里面的Model,就是指的是程序集的名称。同时将此文件的复制到输出目录方式修改为始终复制。


接下来,给控制台项目添加两个dll的引用,分别为Iesi.Collections.dll和NHibernate.dll,也是在Required_Bins文件夹里面。

添加好引用,我们创建一个新的类NHibernateTest来写关键性代码。

namespace NHibernateDemo
{
    public class NHibernateTest
    {
        private ISessionFactory _sessionFactory;
        public ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    var cfg = new NHibernate.Cfg.Configuration().Configure("Config/hibernate.cfg.xml");
                    _sessionFactory = cfg.BuildSessionFactory();
                }
                return _sessionFactory;
            }
        }

        public void TestInit()
        {
            using (ISession session = SessionFactory.OpenSession())
            {
                IList<Subject> subjects = new List<Subject>() 
                {
                     new Subject { SubjectName = "数学" }, 
                     new Subject { SubjectName = "英语" },
                     new Subject { SubjectName = "计算机" },
                };

                IList<Student> students = new List<Student>()
                {
                    new Student
                    {
                        StudentName = "guwei4037",
                        Gender = Gender.Male,
                        BirthDay = new DateTime(1984, 11, 25),
                        Subjects = subjects.Where(x => x.SubjectName == "数学" || x.SubjectName == "计算机").ToArray(),
                    },
                    new Student
                    {
                        StudentName = "gary.gu",
                        Gender = Gender.Female,
                        BirthDay = new DateTime(1987, 9, 15),
                        Subjects = subjects.Where(x => x.SubjectName == "数学" || x.SubjectName == "英语").ToArray(),
                    },
                };

                ITransaction tran = session.BeginTransaction();
                try
                {
                    foreach (var subject in subjects)
                    {
                        session.Save(subject);
                    }

                    foreach (var student in students)
                    {
                        session.Save(student);
                    }

                    tran.Commit();
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    throw ex;
                }
            }
        }
    }
}
这是一个带事务的多表插入的操作。

最后在Main方法中,写入简单的调用方法。

 public class program
    {
        public static void Main(string[] args)
        {
            NHibernateTest test = new NHibernateTest();
            test.TestInit();
        }
    }
在运行这个程序之前,还要做一件事,就是要在你的Sql Server中新建一个空的数据库nhibernateTest,否则会提示登录失败。

好了,这时我们已经准备好了一切,让我们运行一下这个控制台应用程序吧。

由于我们在hibernate.cfg.xml文件中定义了输入sql,所以会看到窗口中的内容。


好,没有报错。我们打开Sql Server看一下最终的结果。


而且数据库的表、主外键的关联以及数据都为我们自动生成了。

好,双向多对多的关系就演示到这里。如果需要更多详细的信息请参考:http://nhforge.org/doc/nh/en/index.html

目录
相关文章
|
机器学习/深度学习 人工智能 监控
人工智能之人脸识别技术应用场景
人脸识别技术是一种通过计算机技术和模式识别算法来识别和验证人脸的技术。它可以用于识别人脸的身份、检测人脸的表情、年龄、性别等特征,以及进行人脸比对和活体检测等应用。
769 1
|
安全 计算机视觉
高通TrustZone接口QSEECOM Use-After-Free漏洞分析
#高通QSEECOM接口漏洞(CVE-2019-14040)分析 #阿里安全(侯客) ##背景:  上周五看到一篇国外的安全公司zimperium的研究人员写的一篇他们分析发现的高通的QSEECOM接口漏洞文章,[https://blog.zimperium.com/multiple-kernel-vulnerabilities-affecting-all-qualcomm-d
2185 0
高通TrustZone接口QSEECOM Use-After-Free漏洞分析
|
存储 机器学习/深度学习 Kubernetes
kubeflow系列:基于国内阿里云镜像解决kubeflow一键安装
google出品在国内都存在墙的问题,而kubeflow作为云原生的机器学习套件对团队的帮助很大,对于无条件的团队,基于国内镜像搭建kubeflow可以帮助大家解决不少麻烦,这里给大家提供一套基于国内阿里云镜像的kubeflow 0.6的安装方案。
9605 0
kubeflow系列:基于国内阿里云镜像解决kubeflow一键安装
|
运维 监控 安全
高效运维管理:提升系统稳定性的策略与实践
【10月更文挑战第2天】 在当今数字化时代,运维管理成为企业IT部门的重要任务。本文将探讨如何通过高效的运维管理策略和最佳实践,提升系统的稳定性,确保业务持续平稳运行。通过分析常见问题、预防措施以及应对策略,我们将揭示高效运维的关键要素,助您打造一个可靠的IT环境。
|
前端开发 开发者
CSS中的长度单位详解
通过合理选择和组合使用不同的长度单位,开发者可以实现高效、灵活和响应式的Web布局设计。以上详解希望能帮助你更好地理解和应用CSS中的长度单位,提高页面的表现力和可维护性。
439 3
|
算法
串ababaaababaa的next和串ababaabab的nextval
本文介绍了计算字符串的next数组和nextval数组的方法,通过分析两个具体的例子来展示如何计算这些数组,这些数组通常用于KMP算法中。
785 0
串ababaaababaa的next和串ababaabab的nextval
|
机器学习/深度学习 人工智能 算法
深度学习基础:从零开始的入门课
【8月更文挑战第21天】通过本文,我们简要介绍了深度学习的基本概念、基础框架以及入门实践。然而,深度学习是一个博大精深的领域,需要不断的学习和实践才能掌握其精髓。建议你在学习过程中,结合具体项目,通过解决实际问题来加深对理论知识的理解。同时,关注最新的研究成果和技术动态,保持对新技术的好奇心和学习热情,相信你会在深度学习的道路上越走越远。
|
存储 前端开发 C#
WPF/C#:更改界面的样式
WPF/C#:更改界面的样式
215 0
|
安全 Java Apache
使用BeanUtils进行属性拷贝
使用BeanUtils进行属性拷贝
|
SQL 安全 网络安全
直播软件源码开发搭建提高安全性方案
直播软件源码平台的防火墙功能是极为重要,且不可或缺的,它的加入有效提高了直播软件源码平台的安全性,保护了用户的信息,为用户构建一个绿色安全的直播软件平台。
直播软件源码开发搭建提高安全性方案