目录

写在前面

文档与系列文章

SchemaExport工具

SchemaUpdate工具

一个例子

总结

写在前面

上篇文章介绍了使用代码生成器的nhibernate模版来生成持久化类,映射文件等内容。本篇文章将继续介绍工具SchemaExport和SchemaUpdate。说实话,这东西我也是第一次使用,也只能边摸索,边学习了。

一般的开发模式是先将数据库架构设计好,然后再编写持久化类和映射文件,也就是数据库驱动的模式。然而也可以先编写持久化类和映射文件,然后通过SchemaExport工具生成数据库架构。通过面向对象的思想,来生成对应的数据库架构,似乎是更合理的(个人观点)。

这种先编写持久化类和映射文件在生成数据库架构有什么好处呢?

如果在设计的时候,我们的领域模型需要改变,只需修改NHibernate结构和应用程序,不需要修改数据库架构,只要利用SchemaExport工具重新生成数据库架构就可以了。

文档与系列文章

[Nhibernate]体系结构

[NHibernate]ISessionFactory配置

[NHibernate]持久化类(Persistent Classes)

[NHibernate]O/R Mapping基础

[NHibernate]集合类(Collections)映射 

[NHibernate]关联映射

[NHibernate]Parent/Child

[NHibernate]缓存(NHibernate.Caches)

[NHibernate]NHibernate.Tool.hbm2net

[NHibernate]Nullables

[NHibernate]Nhibernate如何映射sqlserver中image字段

[NHibernate]基本配置与测试 

[NHibernate]HQL查询 

[NHibernate]条件查询Criteria Query

[NHibernate]增删改操作

[NHibernate]事务

[NHibernate]并发控制

[NHibernate]组件之依赖对象

[NHibernate]一对多关系(级联删除,级联添加)

[NHibernate]一对多关系(关联查询)

[NHibernate]多对多关系(关联查询)

[NHibernate]延迟加载

[NHibernate]立即加载

[NHibernate]视图处理

[NHibernate]N+1 Select查询问题分析

[NHibernate]存储过程的使用(一)

[NHibernate]存储过程的使用(二)

[NHibernate]存储过程的使用(三)

SchemaExport工具

NHibernate的hbm2dll提供SchemaExport工具:给定一个连接字符串和映射文件,不需输入其他东西就可以按照持久化类和映射文件自动生成数据库架构,现在SchemaExport工具还不是很强大,但是一般应用足够了,它还是一个相当原始的API还在不断改进。

SchemaExport工具就是把DDL脚本输出到标准输出,同时/或者执行DDL语句。SchemaExport工具提供了三个方法,分别是Drop()、Create()、Execute(),前两个方法实质是调用Execute()方法。通常使用Execute()方法来生成数据库架构的。

SchemaUpdate工具

在NHibernate2.0中新添加SchemaUpdate工具,可以用来更新数据库架构。但是我觉得没有什么作用,因为它不能Drop现有的表或列,也不能更新现有的列,只能添加新的表和列。如果我需要删除表或者列或者修改其中列,SchemaUpdate工具就显得无能为力了。

一个例子

现在数据访问测试层新建一SchemaExportFixture.cs文件用于测试。

     /// <summary>
/// 描述:SchemaExport生成数据库架构操作类
/// 创建人:wolfy
/// 创建时间:2014-11-16
/// </summary>
public class SchemaExportFixture
{
private Configuration _cfg;
public SchemaExportFixture()
{
_cfg = new Configuration();
_cfg.Configure();
}
public void DropTest()
{
var export = new SchemaExport(_cfg);
export.Drop(true, true);
}
public void CreateTest()
{
var export = new SchemaExport(_cfg);
export.Create(true, true);
}
public void ExecuteTest()
{
var export = new SchemaExport(_cfg);
export.Execute(true, true, false);
}
}

需要引入命名空间

测试Drop方法

方法描述

Drop(script, export)方法根据持久类和映射文件执行删除数据库架构。有两个参数,第一个为True就是把DDL语句输出到控制台,第二个为True就是根据持久类和映射文件执行删除数据库架构操作,经过调试可以发现Drop(script, export)方法其实质是执行了Execute(script, export, true, true)方法。

         //
// 摘要:
// Run the schema creation script
//
// 参数:
// exportOutput:
// if non-null, the ddl will be written to this TextWriter.
//
// execute:
// true if the ddl should be executed against the Database.
//
// 备注:
// This is a convenience method that calls NHibernate.Tool.hbm2ddl.SchemaExport.Execute(System.Boolean,System.Boolean,System.Boolean)
// and sets the justDrop parameter to false.
public void Create(TextWriter exportOutput, bool execute);
//
// 摘要:
// Run the drop schema script
//
// 参数:
// useStdOut:
// true if the ddl should be outputted in the Console.
//
// execute:
// true if the ddl should be executed against the Database.
//
// 备注:
// This is a convenience method that calls NHibernate.Tool.hbm2ddl.SchemaExport.Execute(System.Boolean,System.Boolean,System.Boolean)
// and sets the justDrop parameter to true.
public void Drop(bool useStdOut, bool execute);
//
// 摘要:
// Run the drop schema script
//
// 参数:
// exportOutput:
// if non-null, the ddl will be written to this TextWriter.
//
// execute:
// true if the ddl should be executed against the Database.
//
// 备注:
// This is a convenience method that calls NHibernate.Tool.hbm2ddl.SchemaExport.Execute(System.Action<System.String>,System.Boolean,System.Boolean,System.IO.TextWriter)
// and sets the justDrop parameter to true.
public void Drop(TextWriter exportOutput, bool execute);

Drop

         public void DropTest()
{
var export = new SchemaExport(_cfg);
export.Drop(true, true);
}

生成的sql语句

测试Create方法

方法描述

Create(script,export)方法根据持久类和映射文件先删除架构后创建删除数据库架构。有两个参数,第一个为True就是把DDL语句输出到控制台,第二个为True就是根据持久类和映射文件先执行删除再执行创建操作,经过调试可以发现这个方法其实质是执行Execute(script,export, false, true)方法。

         // 摘要:
// Run the schema creation script
//
// 参数:
// scriptAction:
// an action that will be called for each line of the generated ddl.
//
// execute:
// true if the ddl should be executed against the Database.
//
// 备注:
// This is a convenience method that calls NHibernate.Tool.hbm2ddl.SchemaExport.Execute(System.Boolean,System.Boolean,System.Boolean)
// and sets the justDrop parameter to false.
public void Create(Action<string> scriptAction, bool execute);
//
// 摘要:
// Run the schema creation script
//
// 参数:
// useStdOut:
// true if the ddl should be outputted in the Console.
//
// execute:
// true if the ddl should be executed against the Database.
//
// 备注:
// This is a convenience method that calls NHibernate.Tool.hbm2ddl.SchemaExport.Execute(System.Boolean,System.Boolean,System.Boolean)
// and sets the justDrop parameter to false.
public void Create(bool useStdOut, bool execute);
//
// 摘要:
// Run the schema creation script
//
// 参数:
// exportOutput:
// if non-null, the ddl will be written to this TextWriter.
//
// execute:
// true if the ddl should be executed against the Database.
//
// 备注:
// This is a convenience method that calls NHibernate.Tool.hbm2ddl.SchemaExport.Execute(System.Boolean,System.Boolean,System.Boolean)
// and sets the justDrop parameter to false.
public void Create(TextWriter exportOutput, bool execute);

Create

         public void CreateTest()
{
var export = new SchemaExport(_cfg);
export.Create(true, true);
}

生成的sql语句

通过最后一条你也会发现,连视图也生成了。

测试Execute方法

方法描述

Execute(script, export, justDrop)方法根据持久类和映射文件先删除架构后再创建删除数据库架构。(nhibernate4.0中已经将第四个参数format去掉了)

有三个参数,第一个为True就是把DDL语句输出到控制台;

第二个为True就是根据持久类和映射文件在数据库中先执行删除再执行创建操作;

第三个为false表示不是仅仅执行Drop语句还执行创建操作,这个参数的不同就扩展了上面两个方法;

    public void Execute(Action<string> scriptAction, bool execute, bool justDrop);
//
// 摘要:
// Executes the Export of the Schema.
//
// 参数:
// useStdOut:
// true if the ddl should be outputted in the Console.
//
// execute:
// true if the ddl should be executed against the Database.
//
// justDrop:
// true if only the ddl to drop the Database objects should be executed.
//
// 备注:
// This method allows for both the drop and create ddl script to be executed.
public void Execute(bool useStdOut, bool execute, bool justDrop);
public void Execute(Action<string> scriptAction, bool execute, bool justDrop, TextWriter exportOutput);
public void Execute(Action<string> scriptAction, bool execute, bool justDrop, IDbConnection connection, TextWriter exportOutput);
//
// 摘要:
// Executes the Export of the Schema in the given connection
//
// 参数:
// useStdOut:
// true if the ddl should be outputted in the Console.
//
// execute:
// true if the ddl should be executed against the Database.
//
// justDrop:
// true if only the ddl to drop the Database objects should be executed.
//
// connection:
// The connection to use when executing the commands when export is true. Must
// be an opened connection. The method doesn't close the connection.
//
// exportOutput:
// The writer used to output the generated schema
//
// 备注:
// This method allows for both the drop and create ddl script to be executed.
// This overload is provided mainly to enable use of in memory databases. It
// does NOT close the given connection!
public void Execute(bool useStdOut, bool execute, bool justDrop, IDbConnection connection, TextWriter exportOutput);

Execute

        public void ExecuteTest()
{
var export = new SchemaExport(_cfg);
export.Execute(true, true, false);
}

生成的sql语句

通过比较你会发现Execute和Create生成的sql语句很相似

测试Execute(Action<string> scriptAction, bool execute, bool justDrop, TextWriter exportOutput)方法

方法描述

根据持久类和映射文件先删除架构后创建删除数据库架构。有四个参数。

第一个为一个带一个字符串类型输入参数的委托方法。

第二个为true表示对数据库执行DDL。

第三个为true表示如果只有DDL删除数据库对象应该被执行。

第四个为一个TextWriter输出到一个TextWriter中。

         public void ExecuteOutTest()
{
var export = new SchemaExport(_cfg);
StringBuilder sb=new StringBuilder();
TextWriter tw=new StringWriter(sb);
export.Execute(new Action<string>((string x) => { Console.Write(x); }), true, true,tw);
}

测试

 SchemaUpadte使用

原来的映射文件Product.hbm.xml。

 <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Wolfy.Shop.Domain" namespace="Wolfy.Shop.Domain.Entities">
<class name="Wolfy.Shop.Domain.Entities.Product,Wolfy.Shop.Domain" table="TB_Product">
<id name="ProductID" column="ProductID" type="Guid" unsaved-value="null">
<generator class="assigned" />
</id>
<property name="Name" column="Name" type="String"
not-null="true" />
<property name="Price" column="Price" type="decimal"
not-null="true" />
<!--多对多关系:product属于多个orders-->
<bag name="Orders" generic="true" table="TB_OrderProduct" >
<key column="ProductID" foreign-key="FK_TB_OrderProduct_TB_Product"/>
<many-to-many column="OrderID" class="Wolfy.Shop.Domain.Entities.Order,Wolfy.Shop.Domain"
foreign-key="FK_TB_OrderProduct_TB_Order"/>
</bag>
</class>
</hibernate-mapping>

修改映射文件,添加一个库存量的字段。

 <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Wolfy.Shop.Domain" namespace="Wolfy.Shop.Domain.Entities">
<class name="Wolfy.Shop.Domain.Entities.Product,Wolfy.Shop.Domain" table="TB_Product">
<id name="ProductID" column="ProductID" type="Guid" unsaved-value="null">
<generator class="assigned" />
</id>
<property name="Name" column="Name" type="String"
not-null="true" />
<property name="Price" column="Price" type="decimal"
not-null="true" />
<!--库存-->
<property name="ProductCount" column="ProductCount" type="int"
not-null="true" />
<!--多对多关系:product属于多个orders-->
<bag name="Orders" generic="true" table="TB_OrderProduct" >
<key column="ProductID" foreign-key="FK_TB_OrderProduct_TB_Product"/>
<many-to-many column="OrderID" class="Wolfy.Shop.Domain.Entities.Order,Wolfy.Shop.Domain"
foreign-key="FK_TB_OrderProduct_TB_Order"/>
</bag>
</class>
</hibernate-mapping>

测试,在数据层添加一个类SchemaUpdateFixture

     /// <summary>
/// 描述:SchemaExport修改数据库架构操作类
/// 创建人:wolfy
/// 创建时间:2014-11-16
/// </summary>
public class SchemaUpdateFixture
{
private Configuration _cfg;
public SchemaUpdateFixture()
{
_cfg = new Configuration();
_cfg.Configure();
var export = new SchemaExport(_cfg);
export.Execute(true, true, false); }
public void UpdateTest()
{
_cfg = new Configuration();
_cfg.Configure();
var export = new SchemaUpdate(_cfg);
export.Execute(true, true);
}
}

查看生成的数据表TB_Product

细心的你可能会发现,我们在修改过映射文件后并没有修改对应的持久化类。通过SchemaUpdate(_cfg)你就会发现,初始化该工具的时候只是加载对应的配置文件,跟持久化类并没关系,不过为了对应关系,还是在修改过映射文件后,将添加的或者删除的字段,在持久化类中修改一下,以免忘记,造成打错。

总结

本篇文章通过实例介绍NHibernate中提供的两个实用工具SchemaExport如何利用持久化类和映射文件生成数据库架构。本篇文章就介绍到这里。

参考文章:http://www.cnblogs.com/lyj/archive/2008/11/11/1331509.html

[Nhibernate]SchemaExport工具的使用(一)——通过映射文件修改数据表的更多相关文章

  1. [Nhibernate]SchemaExport工具的使用(二)——创建表及其约束、存储过程、视图

    目录 写在前面 文档与系列文章 表及其约束 存储过程 视图 总结 写在前面 由于一直在山西出差,有几天没更新博客了.昨晚回到家,将博客园最近三天更新的文章搜集了一下,花费了半天的时间,看了看,有些文章 ...

  2. 使用 hibernate 根据映射文件生成数据库表

    为了更好的显示效果,可以在hibernate.cfg.xml配置文件的<session-factory>标签里加入以下内容: 显示sql语句和格式化显示sql语句: <propert ...

  3. 【mybatis xml】数据层框架应用--Mybatis 基于XML映射文件实现数据的CRUD

    使用MyBatis框架进行持久层开发 MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架. MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索. MyBa ...

  4. Mybatis映射文件中数据库表列名称和POJO成员域的联系

    下面是Mybatis的SQL映射文件. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ma ...

  5. myeclipse自动生成可持久化类的映射文件的方法

    1.打开DB Browser,新建一个数据库的连接,找到想要持久化操作的数据库表的图标,右键选择hibernate reverse engineering 2.之后出现如下所示: java src f ...

  6. Hibernate的映射文件

    映射文件的结构和属性 一个映射文件(mapping file)由一个根节点<hibernate-mapping>和多个<class>节点组成, 首先看看根节点<hiber ...

  7. Hibernate之深入Hibernate的映射文件

    这周周末 要把hibernate的映射文件搞定 .. 1.映射文件的主结构 主要结构  :根元素为<hibernate-mapping ></hibernate-mapping> ...

  8. .NET 4.0中使用内存映射文件实现进程通讯

    操作系统很早就开始使用内存映射文件(Memory Mapped File)来作为进程间的共享存储区,这是一种非常高效的进程通讯手段.Win32 API中也包含有创建内存映射文件的函数,然而,这些函数都 ...

  9. 【原创】MySQL+MyEclipse+对象映射文件,schema与category的关系

    (一) 1.映射文件的类如下写法:class name="com.sanqing.po.SysUser" table="sys_user"  catalog=& ...

随机推荐

  1. Eclipse下还原删除的文件

    做项目的时候,不小心把Eclipse下的么个文件删除了,虽然有svn但是最新修改的代码没有提交,怎么办,在网上查了下,eclipse是可以还原删除文件的.具体做法如下所示 恢复删除的文件 1 在项目上 ...

  2. Vim自动补全神器–YouCompleteMe

    一.简介 YouCompleteMe是Vim的自动补全插件,与同类插件相比,具有如下优势 1.基于语义补全 2.整合实现了多种插件 clang_complete.AutoComplPop .Super ...

  3. 1、策略模式(Strategy)

    //抽象接口 class ReplaceAlgorithm { public: ; }; //三种具体的替换算法 class LRU_ReplaceAlgorithm : public Replace ...

  4. Canvas绘图基础(一)

    简单图形绘制 矩形:描边与填充 Canvas的API提供了三个方法,分别用于矩形的清除.描边及填充 clearRect(double x, double y, double w, double h) ...

  5. 如何用python在Windows系统下,生成UNIX格式文件

    平时测试工作中,少不了制造测试数据.最近一个项目,我就需要制造一批可在UNIX下正确读取的文件.为确保这批文件能从FTP下载成功,开发叮嘱我:“文件中凡是遇到换行,换行符必须是UNIX下的LF,而不是 ...

  6. HDU3555 Bomb[数位DP]

    Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submi ...

  7. spring初次体验

    1.BeanFactory:实际上是实例化,配置和管理众多bean的容器.这些bean通常会彼此合作,因而它们之间会相互依赖.BeanFactory使用的配置数据可以反映这些依赖关系中(一些依赖可能不 ...

  8. JSHint配置项说明

    转自:http://www.jianshu.com/p/4cb23f9e19d3 什么是JSHint? 官方网站这样介绍: JSHint, A Static Code Analysis Tool fo ...

  9. VS 常用高效 快捷键

    强迫智能感知:Ctrl+J.智能感知是Visual Studio最大的亮点之一,选择Visual Studio恐怕不会没有这个原因. 2 撤销:Ctrl+Z.除非你是天才,那么这个快捷键也是最常用的. ...

  10. C++学习笔记(3)

    本学习笔记是C++ primer plus(第六版)学习笔记.是C++学习笔记(2)的后续.复习C++基础知识的可以瞄瞄. 转载请注明出处http://www.cnblogs.com/zrtqsk/p ...