初探SchemaExport工具使用

系统 1506 0

之前都是用最蠢的方法:SQL建立数据库相关的表,然后再Java写映射写配置文件.....

实际上使用Hibernate自带的工具 hbm2ddl ,建立根据你的对象建立数据库是很惬意的一件事;)

首先当然要建好POJO object, XML Mapping File(也可以使用工具根据POJO class建立),配置文件(hibernate.cfg.xml)

然后运行下面的Java代码

 

    import org.hibernate.cfg.Configuration; 
import org.hibernate.tool.hbm2ddl.SchemaExport;

public class SchemaUtil {
    public static void main(String[] args) {

        Configuration cfg = new Configuration().configure();
        SchemaExport schemaExport= new SchemaExport(cfg);
        schemaExport.create(false, true);
    }
}

  

再看看数据库,表是不是已经帮你建好了,对于我这样不熟悉数据库的人真是太方便了

 

 

  • 引入
  • SchemaExport工具
  • SchemaUpdate工具
  • 实例分析
  • 结语

引入

我其实都是一直先编写持久化类和映射文件,然后使用SchemaExport工具生成数据库架构。这样的方式就是领域驱动设计/开发(DDD,Domain Driven Design/Development)。我的理解是系统的设计应该基于对象模型,主要考虑对象的设计和逻辑上,然后按照对象模型建立数据库关系模型,这才是现在面向对象开发的步骤,并不是上一篇先设计数据库然后再设计对象。用一幅图可以形象的说明领域驱动设计:

领域驱动设计模型

当在设计时,我们的领域模型需要改变,只需修改Hibernate结构和应用程序,不需要修改数据库架构,只要利用SchemaExport工具重新生成数据库架构就可以了。但是使用数据库只是其中一种方式,我们也可以使用XML文件来存储数据。

SchemaExport工具

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

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

SchemaUpdate工具

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

实例分析

知道了上面的知识就好好实战一下:看看具体怎么使用呢?

1.SchemaExport工具实战

通常我们使用生成数据库架构代码实例像这样:

    
      Configuration 
    
    cfg=
    
      new 
    
    
      Configuration
    
    ();
cfg.Configure();

    
      SchemaExport 
    
    export =
    
      new 
    
    
      SchemaExport
    
    (cfg);
export.Execute(....);
  

1.准备工作

现在数据访问测试层新建一SchemaExportFixture.cs文件用于测试生成实战。声明一个全局变量_cfg,编写 [SetUp]方法在每个测试方法执行之前调用:

    [
    
      TestFixture
    
    ]

    
      public class 
    
    
      SchemaExportFixture

    
    {
    
    
      private 
    
    
      Configuration 
    
    _cfg;
    [
    
      SetUp
    
    ]
    
    
      public void 
    
    SetupContext()
    {
        _cfg = 
    
      new 
    
    
      Configuration
    
    ();
        _cfg.Configure();
    }
    
    
      //测试......
    
    
}
  

2.测试Drop(script, export)方法

    [
    
      Test
    
    ]

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

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

3.测试Create(script, export)方法

    [
    
      Test
    
    ]

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

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

4.测试Execute(script, export, justDrop, format)方法

    [
    
      Test
    
    ]

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

Execute(script, export, justDrop, format)方法根据持久类和映射文件先删除架构后创建删除数据库架构。有四个参数,第一个为True就是把DDL语句输出到控制台;第二个为True就是根据持久类和映射文件在数据库中先执行删除再执行创建操作;第三个为false表示不是仅仅执行Drop语句还执行创建操作,这个参数的不同就扩展了上面两个方法;第四个参数为false表示不是格式化输出DDL语句到控制台,是在一行输出的。

所谓格式化输出就像这样:

格式化输出

一行输出就像这样:

一行输出

5.测试Execute(script, export, justDrop, format, connection, exportOutput)方法

    [
    
      Test
    
    ]

    
      public void 
    
    ExecuteOutTest()
{
    
    
      var 
    
    export = 
    
      new 
    
    
      SchemaExport
    
    (_cfg);
    
    
      var 
    
    sb = 
    
      new 
    
    
      StringBuilder
    
    ();
    
    
      TextWriter 
    
    output = 
    
      new 
    
    
      StringWriter
    
    (sb);
    export.Execute(
    
      true
    
    , 
    
      false
    
    , 
    
      false
    
    , 
    
      false
    
    , 
    
      null
    
    , output);
}
  

Execute(script, export, justDrop, format, connection, exportOutput)方法根据持久类和映射文件先删除架构后创建删除数据库架构。有六个参数,第一个为True就是把DDL语句输出到控制台;第二个为false就是不执行DDL语句;第五个为自定义连接。当export为true执行语句时必须打开连接。该方法不关闭连接,null就是使用默认连接,最后一个参数自定义输出,这里我输出到TextWriter中。

2.SchemaUpdate工具实战

现在数据访问测试层新建一SchemaUpdateFixture.cs文件用于测试生成实战。先声明一个全局变量_cfg:

    
      private 
    
    
      Configuration 
    
    _cfg;
  

这里我用另外一种方式配置映射文件,先定义两个映射XML分别代表旧的和新的这样才能体现测试更新数据库架构的意义。

旧映射XML:这里我使用Product持久化类,由于在之前我们定义了Product持久化类,这里直接模拟定义映射XML:拥有主键ProductId和Name字段。

    
      public const string 
    
    product_xml =
    
    
      "<?xml version='1.0' encoding='utf-8' ?>" 
    
    +
    
    
      "<hibernate-mapping xmlns='urn:nhibernate-mapping-2.2'" 
    
    +
    
    
      "                 assembly='DomainModel'" 
    
    +
    
    
      "                 namespace='DomainModel'>" 
    
    +
    
    
      "  <class name='DomainModel.Entities.Product,DomainModel'>" 
    
    +
    
    
      "    <id name='ProductId'>" 
    
    +
    
    
      "      <generator class='native'/>" 
    
    +
    
    
      "    </id>" 
    
    +
    
    
      "    <property name='Name'/>" 
    
    +
    
    
      "  </class>" 
    
    +
    
    
      "</hibernate-mapping>"
    
    ;
  

新映射XML:更新上面映射XML:主键ProductId(没有改变);Name字段:添加不可为空和长度为50;另外增加了Cost字段,类型为float不可为空。

    
      public const string 
    
    newproduct_xml =
    
    
      "<?xml version='1.0' encoding='utf-8' ?>" 
    
    +
    
    
      "<hibernate-mapping xmlns='urn:nhibernate-mapping-2.2'" 
    
    +
    
    
      "                 assembly='DomainModel'" 
    
    +
    
    
      "                 namespace='DomainModel'>" 
    
    +
    
    
      "  <class name='DomainModel.Entities.Product,DomainModel'>" 
    
    +
    
    
      "    <id name='ProductId'>" 
    
    +
    
    
      "      <generator class='native'/>" 
    
    +
    
    
      "    </id>" 
    
    +
    
    
      "    <property name='Name' not-null='true' length='50' />" 
    
    +
    
    
      "    <property name='Cost' type='float' not-null='true'/>" 
    
    +
    
    
      "  </class>" 
    
    +
    
    
      "</hibernate-mapping>"
    
    ;
  

测试前利用旧映射XML创建数据库架构:使用[SetUp]在测试前执行,按照旧映射XML创建数据库架构并格式化输出DDL语句:

    [
    
      SetUp
    
    ]

    
      public void 
    
    SetupContext()
{
    
    
      //模拟旧系统
    
    
    _cfg = 
    
      new 
    
    
      Configuration
    
    ();
    _cfg.Configure();
    _cfg.AddXml(product_xml);
    
    
      var 
    
    export = 
    
      new 
    
    
      SchemaExport
    
    (_cfg);
    export.Execute(
    
      true
    
    , 
    
      true
    
    , 
    
      false
    
    , 
    
      true
    
    );
}
  

测试更新数据库架构:使用SchemaUpdate类提供的唯一的Execute(script, doUpdate)方法按照新映射XML更新数据库架构:

    [
    
      Test
    
    ]

    
      public void 
    
    UpdateExistingDatabaseSchemaTest()
{
    _cfg = 
    
      new 
    
    
      Configuration
    
    ();
    _cfg.Configure().AddXml(newproduct_xml);
    
    
      var 
    
    update = 
    
      new 
    
    
      SchemaUpdate
    
    (_cfg);
    update.Execute(
    
      true
    
    , 
    
      true
    
    );
}
  

测试输出结果如图所示,如果你觉得不放心再看看数据库Product表。

输出结果

看到了吗?这显然不是我要求的,首先按照旧映射XML创建了数据库架构,但是更新数据库架构显得无能为力,仅仅增加了Cost字段,我想更新Name字段属性为不可为空和长度为50,但是SchemaUpdate工具不能做到!我觉得这个类目前还没有什么作用,期待下一个版本来完善。

结语

这篇文章通过实例介绍Hibernate中提供两个实用工具SchemaExport工具利用持久化类和映射文件生成数据库架构。SchemaUpdate工具通过持久化类和映射文件更新数据库架构。

初探SchemaExport工具使用


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论