【翻译】How-To: Using the N* Stack, part 3

原文地址:http://jasondentler.com/blog/2009/08/how-to-using-the-n-stack-part-3/ 

Java – 一种代码松散的XML

在我们学习 Fluent NHibernate 之前, 应该先了解下老式的 NHibernate 映射文件应该是怎样写的。 在一个典型的 NHibernate 配置中,你会有很多类似这样的映射文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"><class name="NStackExample.Address, NStackExample.Core" table="Address"><composite-id><key-many-to-one name="Person" class="NStackExample.Person, NStackExample.Core" column="ID" /><key-property name="Type" type="Int32" /></composite-id><property name="City" type="String" length="255" /><property name="Lines" type="String" length="255" /><property name="State" type="String" length="2" /><property name="Zip" type="String" length="10" /></class>
</hibernate-mapping>

你必须为每一个实体类配置一个这样的映射文件,这种做法是从 Java 的 Hibernate 中遗留下来的。在我看来,这么做是非常痛苦的,不过幸运的是,有一个好办法来解决这个问题。

更好的选择: Fluent Mappings

有了 Fluent NHibernate ,上面的映射文件就可以用下面这个类来代替:

using FluentNHibernate.Mapping;namespace NStackExample.Data
{public class AddressMapping : ClassMap<Address>{public AddressMapping(){UseCompositeId().WithKeyReference(x => x.Person).WithKeyProperty(x => x.Type);Map(x => x.Lines).WithLengthOf(255);Map(x => x.City).WithLengthOf(255);Map(x => x.State).WithLengthOf(2);Map(x => x.Zip).WithLengthOf(5);}}
}

看起来这个类可能比之前的映射文件还要复杂,但是因为有智能感知,我们能轻而易举的完成,并且我们不用担心魔字符串(magic strings)的问题。当你使用重构工具来改变属性名称的时候,你的映射文件也会同步改变。

现在大家都知道基本的概念了吧,那么让我们继续。

Where?

因为数据库连接、 NHibernate 配置、实体类映射和 DAO 的实现只是我们选择的ORM的执行细节,所以应该把他们放到一个单独的程序集中。

  1. 创建一个新的类库项目,名字叫做:NStackExample.Data 。
  2. 添加新项目的引用,将 Core 项目,NHibernate.dll 和 FluentNHibernate.dll 添加进去。
  3. 为了以后我们能轻松的检索一些应用程序的设置,将System.Configuration.dll 也添加进去。
  4. 此外,在我们的 Web 项目中也需要将新建的项目添加到引用当中。

下面让我们来完成我们的映射文件。

using NStackExample;
using FluentNHibernate.Mapping;namespace NStackExample.Data
{public class CourseMapping : ClassMap<Course> {public CourseMapping(){Id(x => x.ID).GeneratedBy.GuidComb();Map(x => x.CourseNumber).Not.Nullable().WithLengthOf(4).UniqueKey("CourseNaturalKey");Map(x => x.Subject).Not.Nullable().WithLengthOf(4).UniqueKey("CourseNaturalKey");Map(x => x.Title).Not.Nullable().WithLengthOf(255);Map(x => x.Description).Not.Nullable().WithLengthOf(1024);Map(x => x.Hours).Not.Nullable();HasMany(x => x.Sections).AsSet().WithForeignKeyConstraintName("CourseSections");}}
}

上面的代码非常容易理解,最后得到的就是我们需要的映射文件。

我们的映射类继承自 ClassMap<Course> ,ClassMap 类是 Fluent NHibernate 搜索查找映射时的具体类型。在这里,这个类提供了 Course 实体类的映射。在构造函数中,我们定义了每个属性的具体映射。

  • 将 Id 设置成持久化对象标示符(POID),基本上这就是数据表的主键。对于有多个属性的主键,请参照我们上面 AddressMapping 示例中的 UseCompositeId 。我不建议使用多重主键,并且据我所知,Fluent NHibernate 也不支持多重主键。
  • GeneratedBy 是用来指定 POID 生成策略。在这里我们使用的是 GuidComb 。使用 GUID 做主键有非常多的好处,具体的内容大家可以参考 Davy Brion在NHForge博客上发表的随笔。
  • Map 只是将属性映射到数据库的列上。如果有需要的话,你可以指定 Not.Nullable 和 WithLengthOf 。
  • UniqueKey 指定了列的唯一索引。如果你对多个列指定了相同的名称,那么这些列都会变为这个唯一索引的一部分。在这个示例中,我们强制要求我们的自然键是唯一的。每个 subject 和 course number 都必须是唯一的。
  • HasMany 是定义了一个一对多的关系,你可以指定集合的确切行为。在这里有 Set 和 Bag 两个选项。
    • AsSet 不允许重复的项目
    • AsBag 允许重复的项目

默认情况下,所有关系都是延迟加载的。就是说当你从数据库中获取到了 course ,和其相关联的 sections 并不是马上获取出来,而是直到当你访问该属性的时候才会被加载进来,如果你从未访问过该属性的话,那么它永远都不会被加载,这样可以大大的提高性能。这些功能都是用代理来实现的。

下面容我们来映射 sections:

using NStackExample;
using FluentNHibernate.Mapping;namespace NStackExample.Data
{public class SectionMapping : ClassMap<Section> {public SectionMapping(){Id(x => x.ID).GeneratedBy.GuidComb();Map(x => x.FacultyName).WithLengthOf(255);Map(x => x.RoomNumber).WithLengthOf(10);Map(x => x.SectionNumber).WithLengthOf(4).Not.Nullable().UniqueKey("SectionNaturalKey");References(x => x.Course).Not.Nullable().UniqueKey("SectionNaturalKey");References(x => x.Term).Not.Nullable().UniqueKey("SectionNaturalKey");HasMany(x => x.StudentSections).AsSet().WithForeignKeyConstraintName("SectionStudentSections");}}
}

在这里引入了多对一关系的映射,可以把它看成一对多关系的另一边。 本示例中就是从孩子 section 到它的父亲 course 的关系。

练习:完成所有实体类的映射。

到这里或许你会在想这个系列是不是会很长很长呢?到现在我们甚至连数据库都还没有开始建立。不用担心,这些事 NHibernate 会帮我们做的。

8小时 or 8分钟?

在我没有使用 NHibernate 之前,我至少需要一天的时间来建立数据库。这让我很郁闷,估计大家也一样很不喜欢浪费这么多时间去建立数据库。不过,这样的事情将在今天结束。

声明: 如果你尝试使用现有的旧版数据库和数据库架构,没有什么调整的机会或者很渺茫,Fabio Maulo 的这篇随笔 将告诉你如何选择。

首先,让我们配置 NHibernate 。在 Fluent NHibernate Wiki 上 有一篇非常好的文章 介绍了应该如何配置。

using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using System.IO;
using System.Configuration;namespace NStackExample.Data
{public class Configuration{private ISessionFactory m_Factory;private string m_SchemaPath;public Configuration Configure(){m_SchemaPath = ConfigurationManager.AppSettings["NStackExample.Data.Configuration.SchemaPath"];m_Factory = Fluently.Configure().Database(MsSqlConfiguration.MsSql2005.ConnectionString(x => x.FromConnectionStringWithKey("NStackExample.Data.Configuration.Db"))).Mappings(x => x.FluentMappings.AddFromAssemblyOf<CourseMapping>().ExportTo(m_SchemaPath)).ExposeConfiguration(BuildSchema).BuildSessionFactory();return this;}private void BuildSchema(NHibernate.Cfg.Configuration cfg){SchemaExport SchemaExporter = new SchemaExport(cfg);SchemaExporter.SetOutputFile(Path.Combine(m_SchemaPath, "schema.sql"));SchemaExporter.Create(true, false);}public ISession OpenSession(){if (m_Factory == null) Configure();return m_Factory.OpenSession();}}
}

配置分为两个部分:数据库和映射。在本示例中,数据库使用的是 SQL 2005,连接字符串是从 Web.config 文件中读取的。 所有的映射部分都是从
fluent 中读取的,没有自动映射。注意,我们出口的映射是在 web.config 文件的 appsettings 节中指定的一个目录,这会将我们 fluent 的映射分别转换成 hbm.xml文件。这么做是为了方便我们映射部分的调试,尤其是在需要 NHibernate 在线帮助的时候。

这里有个附加项,我们使用 ExposeConfiguration 方法调用 BuildSchema 函数来完成对 NHibernate 的配置。

在 BuildSchema 中,我们使用NHibernate中非常好的一个工具:schema export 。这个工具将会帮助我们创建数据库。构造函数接受两个布尔值的参数。第一个参数指定是否输出 DDL 文件 -- 一个包含所有表、键、索引和关系的数据库脚本。 第二个参数指定了是否将脚本应用到指定的数据库上。

非常简单吧。

两个警告:

  • 执行脚本将删除并创建和你的 Model 相关的每一个表,这对已有的环境可能是极具破坏性的操作。
  • 脚本一般不会带有“use [databasename]”语句,所以你如果不小心执行了,可能会建立到 master 数据库中,在执行脚本的时候请注意选择数据库。

在下篇教程当中,我们将介绍如何对你的映射进行测试,包括读取、查询和写入数据库。

转载于:https://www.cnblogs.com/LeoXing/archive/2009/10/05/how-to-using-the-n-stack-part-3.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276372.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你可能需要的网易前端三轮面经

关注若川视野, 回复"pdf" 领取资料&#xff0c;回复"加群"&#xff0c;可加群长期交流前言最近一个星期面了几家公司&#xff0c;最后收获了心仪的网易有道offer&#xff0c;于是推掉了其他的面试&#xff0c;至于一些其他大厂&#xff0c;并没有投简历&am…

复习.net/c#时的小文章之万年草稿版 (全是基础概念,请懂的人绕行)

必读文&#xff1a;61条面向对象设计的经验原则&#xff08;体会篇&#xff09; C#知识点集合 (面试必备)一、显式(explicit)转换和隐式(implicit)转换的一般概念int i 100; Response.Write(i); // 这就是隐式 Response.Write(i.ToString()); // 这就是显式 一般来讲&#xff…

timertask run函数未执行_图执行模式下的 TensorFlow 2

文 / 李锡涵&#xff0c;Google Developers Expert本文节选自《简单粗暴 TensorFlow 2.0》尽管 TensorFlow 2 建议以即时执行模式(Eager Execution)作为主要执行模式&#xff0c;然而&#xff0c;图执行模式(Graph Execution)作为 TensorFlow 2 之前的主要执行模式&#xff0c…

如何从 0 到 1 打造团队 PC/H5 构建工具

关注若川视野, 回复"pdf" 领取资料&#xff0c;回复"加群"&#xff0c;可加群长期交流学习一、前言 大家好&#xff0c;我叫鳗鱼&#xff0c;这次分享的主题是如何从 0 到 1 打造适合自己的构建部署方案。image.png先例行的自我介绍&#xff0c;大概 14 年…

testng接口自动化测试_Java+Maven+TestNG接口(API)自动化测试教程(10) 使用 Jenkins 构建自动化测试持续集成...

现在代码可以运行了&#xff0c;但是每次运行都需要我们手工去执行&#xff0c;并且测试报告也只能在执行测试的电脑上才能看到&#xff0c;我们希望能够定时自动执行测试&#xff0c;并且能够做到自动发送测试报告到相关人员的电子邮箱中。Jenkins 正好可以很好的完成以上诉求…

论公众号内卷

关注若川视野, 回复"pdf" 领取资料&#xff0c;回复"加群"&#xff0c;可加群长期交流学习曾几何时公众号文章的标题单纯且没有套路七年前的我就是这样仅仅把公众号当做一个写文章的博客平台甚至是像有道云一样的在线笔记平台当时的标题是这样子滴《hashma…

程序异常异常代码: 0xc0000005_Java基础:看完这篇你还怕碰到异常吗?

前言在日常的开发以及平时的学习练习中&#xff0c;异常相信对于大家来讲并不陌生&#xff0c;但是对于异常的具体使用、底层实现以及分类等等可能并不是很了解。今天我就抽出了一点时间系统的整理了异常的各个知识点&#xff0c;希望能够帮助到大家对于Java 异常的理解与学习。…

写给初中级前端工程师的进阶指南

学习一门新技术的时候&#xff0c;最大的苦恼之一&#xff0c;大概就是不知道从何入手。典型的情况是&#xff0c;你大概知道学会以后&#xff0c;这门技术可以帮你解决什么问题。但是&#xff0c;怎么才能学会、循序渐进的学习路线是什么、学习范围有多大的深度和广度、涉及到…

千层套路 - Vue 3.0 初始化源码探秘

关注若川视野, 回复"pdf" 领取资料&#xff0c;回复"1"&#xff0c;可加群长期交流学习刘崇桢&#xff0c;微医云服务团队前端工程师&#xff0c;左手抱娃、右手持家的非典型码农。9 月初 Vue.js 3.0 正式发布&#xff0c;代号 "One Piece"。大秘…

2020年大前端技术趋势解读

导Lead语如今的前端早已不再拘泥于满足页面展示&#xff0c;而是开始延展到通过全栈来闭环产品。这表明前端已经有能力透过业务深入产业&#xff0c;继而影响商业结果。这种表象的改变背后是本质的转变&#xff0c;从更为宏观的角度来说&#xff0c;前端正在通过持续的技术革新…

lc滤波器是利用电感的感抗_你对LC谐振电路你都了解吗

根据在电路中电感器L和电容C的连接方式不同&#xff0c;可以有两种LC谐振电路&#xff0c;LC并联谐振电路和LC串联谐振电路。LC并联、串联谐振电路在应用中的变化较多&#xff0c;是电路中分析的一个难点&#xff0c;只有掌握LC并联、串联电路的阻抗特性等基本概念&#xff0c;…

给小程序再减重 30% 的秘密​(京喜小程序首页瘦身实践)

前言—在 web 开发场景&#xff0c;减少代码体积虽然是性能优化的一个方向&#xff0c;还没到锱铢必较的程度。但是在小程序场景&#xff0c;由于代码包上传阶段限制了主包 2M 和总包 16M&#xff08;近期微信官方正在内测将总包上限调整至 20M &#xff09;的尺寸&#xff0c;…

本周ASP.NET英文技术文章推荐[10/21 – 10/27]

这一篇是《本周ASP.NET英文技术文章推荐》系列的第一篇&#xff0c;在这个系列中&#xff0c;我将介绍5-10篇比较有价值的、本周发布的、与ASP.NET相关的英文技术文章&#xff0c;帮助各位朋友从良莠不齐的大量文章中挑出一些我认为非常有价值阅读的&#xff0c;在进行一段简要…

3 年前端面经和他在创业公司的成长历程

在掘金上当了几年的伸手党&#xff0c;最近也准备输出一些自己的东西。关于我首先介绍一下我自己&#xff0c;17 年毕业于一所 211 学校&#xff0c;但是由于大学四年驰骋在召唤师峡谷&#xff0c;毕业时也没有找到一份大厂的工作&#xff0c;随便找了一家创业公司签了三方就去…

Spring.NET学习笔记9——打造简易的依赖注入框架(练习篇) Level 100

我们在第三篇中学习里一个简易的IoC框架。今天我们接着上次的程序&#xff0c;实现带参数构造函数对象的实例和属性的注入 。  我们知道可以通过反射获取类的构造函数及参数(GetConstructors方法)&#xff1b;可以获取属性和属性的类型(GetProperties方法)。通过Activator的C…

android 单元测试

首先AndroidManifest.xml View Code <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"package"com.travelsky.test" android:versionCode"1"androi…

申万一级行业日指数_基金收评 | 指数震荡走弱,军工股成两市主线!后期行情如何?...

收评君复盘日记(2020年9月21日)三大指数集体收跌&#xff0c;北向资金全天大幅净流出近65亿元&#xff0c;军工板块表现强势。盘面回顾9月21日&#xff0c;两市全天高开低走&#xff0c;早盘指数弱势震荡&#xff0c;三大指数盘中一度翻红&#xff0c;但随后震荡走弱&#xff0…

若川的2016年度总结,毕业工作

可以点击上方的标签若川的故事、年度总结&#xff0c;查看往期文章有读者反馈说看我年度总结系列比我源码系列更有启发。所以打算把2016-2018的年度总结发布到公众号声明原创&#xff0c;希望对大家有所启发。&#xff08;虽然我的每一年都过得非常普通...&#xff09;以下是正…

jQuery之Ajax

转载链接&#xff1a;http://cargoj.iteye.com/blog/1008047 1 . jQuery帮助之Ajax请求&#xff08;一&#xff09;jQuery.ajax(options) 2 . jQuery帮助之Ajax请求&#xff08;二&#xff09;jQuery.get(url,[data],[callback] 3 . jQuery帮助之Ajax请求&#xff08;三&am…

面试官问:能否模拟实现JS的new操作符(高频考点)

可以点击上方的话题JS基础系列&#xff0c;查看往期文章这篇文章写于2018年11月05日&#xff0c;new模拟实现&#xff0c;Object.create是面试高频考点&#xff0c;之前发布在掘金有近2万人阅读&#xff0c;现在发布到公众号声明原创。1. 前言这是面试官问系列的第一篇&#xf…