继强's profileHappy Every DayBlogLists Tools Help

Custom HTML

继强 胡

Location
Interests
I love swimming

Happy Every Day

Welcom, my friends, I hope you are happy here!!!
6/15/2009

db2move用法

由于db2数据库需要移植,使用db2 backup和db2 restore 发现会因为文件系统等原因出现很多问题,使用db2move发现简单,但效率稍低。使用方法如下:

1、在原始机建立一个目录test,cd进后:db2move dbname export –u user –p password
2、会生成很多文件,其中db2move.lst记录所有导出的文件,可以进行编辑从而决定导入哪些数据表。
3、在目标机建立一个目录test,cd进入:db2move dbname import –u user –p password

这样就实现了数据表结构和数据的移植,据说可以跨平台使用,但没有测试过,在AIX平台下测试成功。

注意若两个数据库使用了多个表空间的话需要先建立表空间在进行数据的导入,而且两者的数据库编码应保持一致。这里备份一下数据库编码的设置方法:
db2set db2codepage=1386
db2 terminate
注意一定要进行terminate,就是因为这个费了半天的时间。

5/30/2009

数据类型和Json格式 - 阮一峰的网络日志

 

数据类型和Json格式

阮一峰 发表于 2009年05月30日 | 分类:首页 -> 档案 -> IT技术

1.

前几天,我才知道有一种简化的数据交换格式,叫做yaml

我翻了一遍它的文档,看懂的地方不多,但是有一句话令我茅塞顿开。

它说,从结构上看,所有的数据最终都可以分成三种类型

第一种类型是scalar(标量),也就是一个单独的string(字符串)或数字(numbers),比如“北京”这个单独的词。

第二种类型是sequence(序列),也就是若干个相关的数据按照一定顺序并列在一起,又叫做array(数组)或List(列表),比如“北京,东京”。

第三种类型是mapping(映射),也就是一个名/值对(Name/value),即数据有一个名称,还有一个与之相对应的值,这又称作hash(散列)或dictionary(字典),比如“首都:北京”。

我恍然大悟,数据构成的最小单位原来如此简单!难怪在编程语言中,只要有了数组(array)和对象(object)就能够储存一切数据了。

2.

我马上想到了json

21世纪初,Douglas Crockford寻找一种数据交换格式,能够在服务器之间交换数据。这其实需要二步,第一步是将各种数据转化为一个字符串,也就是数据的串行化(serialization),第二步才是交换这个字符串。

当时通用的数据交换语言是XML,但是Douglas Crockford觉得XML的生成和解析都太麻烦,所以他提出了一种简化格式,也就是Json。

Json的规格非常简单,只用一个页面、几百个字就能说清楚,而且Douglas Crockford声称这个规格永远不必升级,因为该规定都规定了。

1) 并列的数据之间用逗号(“,”)分隔。

2) 映射用冒号(“:”)表示。

3) 并列数据的集合(数组)用方括号("[]")表示。

4) 映射的集合(对象)用大括号(“{}”)表示。

上面四条规则,就是Json格式的所有内容。

比如,下面这句话:

“北京市的面积为16800平方公里,常住人口1600万人。上海市的面积为6400平方公里,常住人口1800万。”

写成json格式就是这样:

[
{"城市":"北京","面积":16800,"人口":1600},
{"城市":"上海","面积":6400,"人口":1800}
]

如果事先知道数据的结构,上面的写法还可以进一步简化:

[
["北京",16800,1600],
["上海",6400,1800]
]

由此可以看到,json非常易学易用。所以,在短短几年中,它就取代xml,成为了互联网上最受欢迎的数据交换格式。

我猜想,Douglas Crockford一定事先就知道,数据结构可以简化成三种形式,否则怎么可能将json定义得如此精炼呢!

3.

我还记得,在学习javascript的时候,我一度搞不清楚“数组”(array)和“对象”(object)的根本区别在哪里,两者都可以用来表示数据的集合。

比如有一个数组a=[1,2,3,4],还有一个对象a={0:1,1:2,2:3,3:4},然后你运行alert(a[1]),两种情况下的运行结果是相同的!这就是说,数据集合既可以用数组表示,也可以用对象表示,那么我到底该用哪一种呢?

我后来才知道,数组表示有序数据的集合,而对象表示无序数据的集合。如果数据的顺序很重要,就用数组,否则就用对象。

4.

当然,数组和对象的另一个区别是,数组中的数据没有“名称”(name),对象中的数据有“名称”(name)。

但是问题是,很多编程语言中,都有一种叫做“关联数组”(associative array)的东西。这种数组中的数据是有名称的。

比如在javascript中,可以这样定义一个对象:

var a={"城市":"北京","面积":16800,"人口":1600};

但是,也可以定义成一个关联数组:

a["城市"]="北京";
a["面积"]=16800;
a["人口"]=1600;

这起初也加剧了我对数组和对象的混淆,后来才明白,在Javascript语言中,关联数组就是对象,对象就是关联数组。这一点与php语言完全不同,在php中,关联数组也是数组。

比如运行下面这段javascript:

var a=[1,2,3,4];

a['foo']='Hello World';

alert(a.length);

最后的结果是4,也就是说,数组a的元素个数是4个。

但是,运行同样内容的php代码就不一样了:

$a=array(1,2,3,4);

$a["foo"]="Hello world";

echo count($a);

最后的结果是5,也就是说,数组a的元素个数是5个。

(完)

数据类型和Json格式 - 阮一峰的网络日志

5/17/2009

借助POI实现跨平台office文档解析

由于公司需要,网上搜索了一下office文档的解析框架,发现有很多是通过调用office的dll文件,做Java和office的桥梁,而Apache的poi框架使用纯Java技术实现了office文档的跨平台解析,还没有做深入研究,仅使用其实现了word文档的读取。

1、poi框架获取,http://poi.apache.org/提供poi框架的下载,有很多参考文档可下载。
2、新建项目,将相应的jar包加入到相关路径中即可使用。其中org.apache.poi.hwpf是对word进行操作的相关类。具体使用方法为:

File file = new File( currentPath + "test.doc");
HWPFDocument doc = new HWPFDocument(new FileInputStream(file));
Range rg = doc.getRange();
System.out.println(rg.text());

更详细的使用请参考相关文档。为便于阅读和参考,通过easyCHM将poi的Javadoc编译成chm格式,有需要的可以从以下地址进行下载

再次感叹apache的强大!

4/29/2009

IBM发布DB2 9.7和InfoSphere Warehouse 9.7___企业软件_eNet资讯频道

 

IBM发布DB2 9.7和InfoSphere Warehouse 9.7

http://www.enet.com.cn 2009年04月29日16:18 eNet硅谷动力

【导读】:新版数据库软件能够提高运营效率并削减最高75%的存储成本,特有的业务分析特性将帮助企业进行“新锐洞察”。

  (2009年4月29日,北京)IBM(NYSE:IBM)近日推出了最新版DB2和InfoSphere Warehouse软件——DB2 9.7和InfoSphere Warehouse 9.7,以帮助企业从IT投资中获得更多回报。这款代号为“Cobra”的最新版DB2可大幅减少数据存储空间,帮助客户节约高达75%的相关成本(包括能源成本),远胜市面上其它任一款数据库软件。该软件还是业内首款能够同时为关系型数据和XML数据提供业务分析功能的数据库软件。此外,IBM DB2 9.7还嵌入了开源数据库厂商EnterpriseDB的兼容性技术,实现了与Oracle数据库的兼容。
携手EnterpriseDB,兼容Oracle数据库
  EnterpriseDB是一家企业开源数据库厂商,通过其Postgres Plus平台,用户可以直接使用Oracle数据库。据EnterpriseDB的新闻资料显示:“根据IBM和EnterpriseDB达成的协议,DB2和EnterpriseDB的Postgres Plus Advanced Server将互相提供强大的兼容性解决方案,并为Oracle 数据库环境的用户提供扩展的便捷应用及技术支持。如此,客户便能够在DB2上运行专为Oracle数据库编写的程序,从而降低迁移的成本、时间和风险。”
  EnterpriseDB公司首席执行官Ed Boyajian表示:“我们非常高兴与IBM携手合作,共同改进我们的数据库技术。我们致力于在不断演进的数据库软件市场中做出令人振奋的改变。”
独门分析特性,助力企业“新锐洞察”
  纵观当前,企业生成的信息呈指数级增长,信息爆炸给数据库基础设施造成了沉重的负担,与数据相关的管理、电力、散热和存储成本大幅上扬。IBM调查显示,企业每天都会产生高达15TB的新信息。企业迫切需要一双“新锐洞察”的慧眼,在这些海量信息中发掘商业价值。
  新版DB2软件是业内首款能够同时为关系型数据和XML数据提供业务分析功能的数据库软件。它可使企业更充分地利用硬件、提高管理效率、轻松运行用其它数据库软件编写的应用,并从有价值的XML数据中生成“新锐洞察”,轻松解决上述问题。
  例如,加州大学洛杉矶分校(UCLA)医学中心正利用这款具有分析功能的软件管理病历,DB2的新特性帮助UCLA更好地分析和了解症状或病症相似的患者的病情发展规律和趋势,同时减少了50%的病历存储空间。目前,UCLA正利用该软件的新特性开发三款临床应用,以便为患者提供更好的服务。
多管齐下,节约时间、能源、部署及开发成本
  IBM信息管理开发副总裁Arvind Krishna表示:“为了获得更好的业务成果,银行、医疗和零售等行业在管理、分析和访问信息的同时,也在努力解决日益突出的能源成本问题。凭借DB2和InfoSphere Warehouse软件的创新特性,IBM再次为客户和合作伙伴提供了拥有更高性能和更低成本的选择。”
  几家客户从这项新技术中获益匪浅。例如:德国专营香料和时尚用品的零售商Douglas Holding AG公司,正在利用DB2管理其1,800家欧洲商店的销售记录,并借助XML应用连接商店收银机及其数据仓库。在最新版DB2与应用的测试运行中,公司证实,销售记录精确性得到了大幅提高,这有助于他们更全面地了解客户的购买习惯,从而提高整体的业务绩效。
  此外,位于美国密苏里州圣路易斯的一家医疗机构BJC Healthcare也选择使用DB2,使本机构及其附属医疗学校从过去的手动收集医学研究数据,发展至电子化数据收集。有了DB2,收集数据所需的时间从原来的几个月缩短至几个小时甚或几分钟。现在,BJC Healthcare已能够在海量数据中进行综合的查询,并对查询结果进行分析,确保研究人员及时查看到患者详细的医疗记录。借助这些数据,该机构还能够确定符合临床研究标准的病例,并根据需要调整疗程。
  InfoSphere Warehouse 9.7 Enterprise Edition采用DB2 9.7,其中包含了用于简化数据分析和数据挖掘的工具,以及面向小型机构和大型机构内部部门的最新Departmental Edition版软件。这个新版软件使组织机构能够将数据转变为可靠统一的商业情报,满足他们的业务需求。
  IBM的集成数据管理方案有助于提高开发人员的工作效率——对企业而言,这是一个减少成本的绝佳方式。DB2 9.7包括的最新技术能够帮助IT专家更轻松、更迅速地开发和部署应用,甚至对于专门为其它数据库编写的应用也能自如应对。利用这些最新技术,开发人员现在可以轻松地利用这些最新技术,借助IBM Data Studio设计、开发、部署和管理信息。
  加入DB2 9.7早期参与计划的企业发现,他们采用新版本DB2部署应用后节省了大量时间。Web解决方案ERP提供商、IBM的业务合作伙伴Openbravo公司首席技术官Paolo Juvara表示:“将我们的应用移植到前一版DB2上可能需要大约2年的时间,而移植到最新版DB2上只需要一个星期,这令我们惊喜不已。这将为我们扩展包括用户、合作伙伴和开发商在内的全球社区带来无限机遇。能够与IBM合作部署新方案,我们感到非常荣幸。”
  不仅如此,DB2 9.7还具有工作负载管理和自动计算特性,可提升高优先级应用(如完成季度财务报告,帮助IT员工更高效地管理不断增长的数据)的性能,节约35%的行政工作时间。
  DB2 9.7和InfoSphere Warehouse 9.7将于近期投放市场。客户、开发商及合作伙伴可通过IBM早期参与计划测试运行DB2 9.7。
  如欲了解更多信息,请访问http://ibm.com/db2和http://ibm.com/infosphere。

IBM发布DB2 9.7和InfoSphere Warehouse 9.7___企业软件_eNet资讯频道

4/28/2009

转载:抽象类与接口的区别

关键字: 抽象类与接口的区别

abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力。 abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于 abstract class和interface的选择显得比较随意。

其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意图的理解是否正确、合理。本文将对它们之间的区别进行一番剖析,试图给开发者提供一个在二者之间进行选择的依据。

一、理解抽象类

abstract class和interface在Java语言中都是用来进行抽象类(本文中的抽象类并非从abstract class翻译而来,它表示的是一个抽象体,而abstract class为Java语言中用于定义抽象类的一种方法,请读者注意区分)定义的,那么什么是抽象类,使用抽象类能为我们带来什么好处呢?

在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是 这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领 域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。

比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、三角形 这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念在问题 领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。

在面向对象领域,抽象类主要用来进行类型隐藏。我们可以构造出一个固定的一组行 为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可 以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。熟悉OCP的读 者一定知道,为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。

二、从语法定义层面看abstract class和interface

在语法层面,Java语言对于abstract class和interface给出了不同的定义方式,下面以定义一个名为Demo的抽象类为例来说明这种不同。使用abstract class的方式定义Demo抽象类的方式如下:

java 代码

  1. abstract class Demo {    
  2. abstract void method1();    
  3. abstract void method2();    
  4. …    
  5. }   

使用interface的方式定义Demo抽象类的方式如下:

java 代码

  1. interface Demo {    
  2. void method1();    
  3. void method2();    
  4. …    
  5. }   

在abstract class方式中,Demo可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface方式的实现中,Demo只能够有静态的 不能被修改的数据成员(也就是必须是static final的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。从某种意义上说,interface是一种特殊 形式的abstract class。

从编程的角度来看,abstract class和interface都可以用来实现"design by contract"的思想。但是在具体的使用上面还是有一些区别的。

首先,abstract class在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface。也许,这是Java语言的设计者在考虑Java对于多重继承的支持方面的一种折中考虑吧。

其次,在abstract class的定义中,我们可以赋予方法的默认行为。但是在interface的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会 增加一些复杂性,有时会造成很大的麻烦。

在抽象类中不能定义默认行为还存在另一个比较严重的问题,那就是可能会造成维护上的 麻烦。因为如果后来想修改类的界面(一般通过abstract class或者interface来表示)以适应新的情况(比如,添加新的方法或者给已用的方法中添加新的参数)时,就会非常的麻烦,可能要花费很多的时 间(对于派生类很多的情况,尤为如此)。但是如果界面是通过abstract class来实现的,那么可能就只需要修改定义在abstract class中的默认行为就可以了。

同样,如果不能在抽象类中定义默认行为,就会导致同样的方法实现出现在该抽象类 的每一个派生类中,违反了"one rule,one place"原则,造成代码重复,同样不利于以后的维护。因此,在abstract class和interface间进行选择时要非常的小心。

三、从设计理念层面看abstract class和interface

上面主要从语法定义和编程的角度论述了abstract class和interface的区别,这些层面的区别是比较低层次的、非本质的。本文将从另一个层面:abstract class和interface所反映出的设计理念,来分析一下二者的区别。作者认为,从这个层面进行分析才能理解二者概念的本质所在。

前面已经提到过,abstarct class在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is a"关系,即父类和派生类在概念本质上应该是相同的。对于interface 来说则不然,并不要求interface的实现者和interface定义在概念本质上是一致的,仅仅是实现了interface定义的契约而已。为了使 论述便于理解,下面将通过一个简单的实例进行说明。

考虑这样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示:

使用abstract class方式定义Door:

java 代码

  1. abstract class Door {    
  2. abstract void open();    
  3. abstract void close();    
  4. }   

使用interface方式定义Door:

java 代码

  1. interface Door {    
  2. void open();    
  3. void close();    
  4. }   

其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。看起来好像使用abstract class和interface没有大的区别。

如果现在要求Door还要具有报警的功能。我们该如何设计针对该例子的类结构呢(在 本例中,主要是为了展示abstract class和interface反映在设计理念上的区别,其他方面无关的问题都做了简化或者忽略)下面将罗列出可能的解决方案,并从设计理念层面对这些不 同的方案进行分析。

解决方案一:

简单的在Door的定义中增加一个alarm方法,如下:

java 代码

或者

java 代码

  1. interface Door {    
  2. void open();    
  3. void close();    
  4. void alarm();    
  5. }   

那么具有报警功能的AlarmDoor的定义方式如下:

java 代码

  1. class AlarmDoor extends Door {    
  2. void open() { … }    
  3. void close() { … }    
  4. void alarm() { … }    
  5. }   

或者

java 代码

  1. class AlarmDoor implements Door {    
  2. void open() { … }    
  3. void close() { … }    
  4. void alarm() { … }    
  5. }   

这种方法违反了面向对象设计中的一个核心原则ISP(Interface Segregation Priciple),在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。这样引起的一个问题是那些仅仅 依赖于Door这个概念的模块会因为"报警器"这个概念的改变(比如:修改alarm方法的参数)而改变,反之依然。

解决方案二:

既然open、close和alarm属于两个不同的概念,根据ISP原则应该把它 们分别定义在代表这两个概念的抽象类中。定义方式有:这两个概念都使用abstract class方式定义;两个概念都使用interface方式定义;一个概念使用abstract class方式定义,另一个概念使用interface方式定义。

显然,由于Java语言不支持多重继承,所以两个概念都使用abstract class方式定义是不可行的。后面两种方式都是可行的,但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。我们一一来分析、说明。

如果两个概念都使用interface方式来定义,那么就反映出两个问题:

1、我们可能没有理解清楚问题领域,AlarmDoor在概念本质上到底是Door还是报警器?

2、如果我们对于问题领域的理解没有问题,比如:我们通过对于问题领域的分析发现 AlarmDoor在概念本质上和Door是一致的,那么我们在实现时就没有能够正确的揭示我们的设计意图,因为在这两个概念的定义上(均使用 interface方式定义)反映不出上述含义。

如果我们对于问题领域的理解是:AlarmDoor在概念本质上是Door,同 时它有具有报警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢?前面已经说过,abstract class在Java语言中表示一种继承关系,而继承关系在本质上是"is a"关系。所以对于Door这个概念,我们应该使用abstarct class方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行为,所以报警概念可以通过interface方式定 义。如下所示:

java 代码

  1. abstract class Door {    
  2. abstract void open();    
  3. abstract void close();    
  4. }   

java 代码

  1. interface Alarm {    
  2. void alarm();    
  3. }   

java 代码

  1. class AlarmDoor extends Door implements Alarm {    
  2. void open() { … }    
  3. void close() { … }    
  4. void alarm() { … }    
  5. }   

这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计 意图。其实abstract class表示的是"is a"关系,interface表示的是"like a"关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有 Door的功能,那么上述的定义方式就要反过来了。

abstract class和interface是Java语言中的两种定义抽象类的方式,它们之间有很大的相似性。但是对于它们的选择却又往往反映出对于问题领域中的概 念本质的理解、对于设计意图的反映是否正确、合理,因为它们表现了概念间的不同的关系(虽然都能够实现需求的功能)。这其实也是语言的一种的惯用法。

抽象类与接口的区别 - 美丽人生 - JavaEye技术网站