`
kt431128
  • 浏览: 37256 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
收藏列表
标题 标签 来源
ETL的考虑 etl
做数据仓库系统,ETL是关键的一环。说大了,ETL是数据整合解决方案,说小了,就是倒数据的工具。回忆一下工作这么些年来,处理数据迁移、转换的工作倒还真的不少。但是那些工作基本上是一次性工作或者很小数据量,使用access、DTS或是自己编个小程序搞定。可是在数据仓库系统中,ETL上升到了一定的理论高度,和原来小打小闹的工具使用不同了。究竟什么不同,从名字上就可以看到,人家已经将倒数据的过程分成3个步骤,E、T、L分别代表抽取、转换和装载。
其实ETL过程就是数据流动的过程,从不同的数据源流向不同的目标数据。但在数据仓库中,ETL有几个特点,一是数据同步,它不是一次性倒完数据就拉到,它是经常性的活动,按照固定周期运行的,甚至现在还有人提出了实时ETL的概念。二是数据量,一般都是巨大的,值得你将数据流动的过程拆分成E、T和L。
现在有很多成熟的工具提供ETL功能,例如powercenter、datastage、powermart等,且不说他们的好坏。从应用角度来说,ETL的过程其实不是非常复杂,这些工具给数据仓库工程带来和很大的便利性,特别是开发的便利和维护的便利。但另一方面,开发人员容易迷失在这些工具中。举个例子,VB是一种非常简单的语言并且也是非常易用的编程工具,上手特别快,但是真正VB的高手有多少?微软设计的产品通常有个原则是“将使用者当作傻瓜”,在这个原则下,微软的东西确实非常好用,但是对于开发者,如果你自己也将自己当作傻瓜,那就真的傻了。ETL工具也是一样,这些工具为我们提供图形化界面,让我们将主要的精力放在规则上,以期提高开发效率。从使用效果来说,确实使用这些工具能够非常快速地构建一个job来处理某个数据,不过从整体来看,并不见得他的整体效率会高多少。问题主要不是出在工具上,而是在设计、开发人员上。他们迷失在工具中,没有去探求ETL的本质。
可以说这些工具应用了这么长时间,在这么多项目、环境中应用,它必然有它成功之处,它必定体现了ETL的本质。如果我们不透过表面这些工具的简单使用去看它背后蕴涵的思想,最终我们作出来的东西也就是一个个独立的job,将他们整合起来仍然有巨大的工作量。大家都知道“理论与实践相结合”,如果在一个领域有所超越,必须要在理论水平上达到一定的高度

探求ETL本质之一 

ETL的过程就是数据流动的过程,从不同异构数据源流向统一的目标数据。其间,数据的抽取、清洗、转换和装载形成串行或并行的过程。ETL的核心还是在于T这个过程,也就是转换,而抽取和装载一般可以作为转换的输入和输出,或者,它们作为一个单独的部件,其复杂度没有转换部件高。和OLTP系统中不同,那里充满这单条记录的insert、update和select等操作,ETL过程一般都是批量操作,例如它的装载多采用批量装载工具,一般都是DBMS系统自身附带的工具,例如Oracle SQLLoader和DB2的autoloader等。

ETL本身有一些特点,在一些工具中都有体现,下面以datastage和powermart举例来说。

1、静态的ETL单元和动态的ETL单元实例;一次转换指明了某种格式的数据如何格式化成另一种格式的数据,对于数据源的物理形式在设计时可以不用指定,它可以在运行时,当这个ETL单元创建一个实例时才指定。对于静态和动态的ETL单元,Datastage没有严格区分,它的一个Job就是实现这个功能,在早期版本,一个Job同时不能运行两次,所以一个Job相当于一个实例,在后期版本,它支持multiple instances,而且还不是默认选项。Powermart中将这两个概念加以区分,静态的叫做Mapping,动态运行时叫做Session。

2、ETL元数据;元数据是描述数据的数据,他的含义非常广泛,这里仅指ETL的元数据。主要包括每次转换前后的数据结构和转换的规则。ETL元数据还包括形式参数的管理,形式参数的ETL单元定义的参数,相对还有实参,它是运行时指定的参数,实参不在元数据管理范围之内。

3、数据流程的控制;要有可视化的流程编辑工具,提供流程定义和流程监控功能。流程调度的最小单位是ETL单元实例,ETL单元是不能在细分的ETL过程,当然这由开发者来控制,例如可以将抽取、转换放在一个ETL单元中,那样这个抽取和转换只能同时运行,而如果将他们分作两个单元,可以分别运行,这有利于错误恢复操作。当然,ETL单元究竟应该细分到什么程度应该依据具体应用来看,目前还没有找到很好的细分策略。比如,我们可以规定将装载一个表的功能作为一个ETL单元,但是不可否认,这样的ETL单元之间会有很多共同的操作,例如两个单元共用一个Hash表,要将这个Hash表装入内存两次。

4、转换规则的定义方法;提供函数集提供常用规则方法,提供规则定义语言描述规则。

5、对数据的快速索引;一般都是利用Hash技术,将参照关系表提前装入内存,在转换时查找这个hash表。Datastage中有Hash文件技术,Powermart也有类似的Lookup功能。

探求ETL本质之二(分类) 

昨在IT-Director上阅读一篇报告,关于ETL产品分类的。一般来说,我们眼中的ETL工具都是价格昂贵,能够处理海量数据的家伙,但是这是其中的一种。它可以分成4种,针对不同的需求,主要是从转换规则的复杂度和数据量大小来看。它们包括
1、交互式运行环境,你可以指定数据源、目标数据,指定规则,立马ETL。这种交互式的操作无疑非常方便,但是只能适合小数据量和复杂度不高的ETL过程,因为一旦规则复杂了,可能需要语言级的描述,不能简简单单拖拖拽拽就可以的。还有数据量的问题,这种交互式必然建立在解释型语言基础上,另外他的灵活性必然要牺牲一定的性能为代价。所以如果要处理海量数据的话,每次读取一条记录,每次对规则进行解释执行,每次在写入一条记录,这对性能影响是非常大的。
2、专门编码型的,它提供了一个基于某种语言的程序框架,你可以不必将编程精力放在一些周边的功能上,例如读文件功能、写数据库的功能,而将精力主要放在规则的实现上面。这种近似手工代码的性能肯定是没话说,除非你的编程技巧不过关(这也是不可忽视的因素之一)。对于处理大数据量,处理复杂转换逻辑,这种方式的ETL实现是非常直观的。
3、代码生成器型的,它就像是一个ETL代码生成器,提供简单的图形化界面操作,让你拖拖拽拽将转换规则都设定好,其实他的后台都是生成基于某种语言的程序,要运行这个ETL过程,必须要编译才行。Datastage就是类似这样的产品,设计好的job必须要编译,这避免了每次转换的解释执行,但是不知道它生成的中间语言是什么。以前我设计的ETL工具大挪移其实也是归属于这一类,它提供了界面让用户编写规则,最后生成C++语言,编译后即可运行。这类工具的特点就是要在界面上下狠功夫,必须让用户轻松定义一个ETL过程,提供丰富的插件来完成读、写和转换函数。大挪移在这方面就太弱了,规则必须手写,而且要写成标准c++语法,这未免还是有点难为最终用户了,还不如做成一个专业编码型的产品呢。另外一点,这类工具必须提供面向专家应用的功能,因为它不可能考虑到所有的转换规则和所有的读写,一方面提供插件接口来让第三方编写特定的插件,另一方面还有提供特定语言来实现高级功能。例如Datastage提供一种类Basic的语言,不过他的Job的脚本化实现好像就做的不太好,只能手工绘制job,而不能编程实现Job。
4、最后还有一种类型叫做数据集线器,顾名思义,他就是像Hub一样地工作。将这种类型分出来和上面几种分类在标准上有所差异,上面三种更多指ETL实现的方法,此类主要从数据处理角度。目前有一些产品属于EAI(Enterprise Application Integration),它的数据集成主要是一种准实时性。所以这类产品就像Hub一样,不断接收各种异构数据源来的数据,经过处理,在实施发送到不同的目标数据中去。
虽然,这些类看似各又千秋,特别在BI项目中,面对海量数据的ETL时,中间两种的选择就开始了,在选择过程中,必须要考虑到开发效率、维护方面、性能、学习曲线、人员技能等各方面因素,当然还有最重要也是最现实的因素就是客户的意象。

探求ETL本质之三(转换)

ETL探求之一中提到,ETL过程最复杂的部分就是T,这个转换过程,T过程究竟有哪些类型呢?
一、宏观输入输出
从对数据源的整个宏观处理分,看看一个ETL过程的输入输出,可以分成下面几类:
1、大小交,这种处理在数据清洗过程是常见了,例如从数据源到ODS阶段,如果数据仓库采用维度建模,而且维度基本采用代理键的话,必然存在代码到此键值的转换。如果用SQL实现,必然需要将一个大表和一堆小表都Join起来,当然如果使用ETL工具的话,一般都是先将小表读入内存中再处理。这种情况,输出数据的粒度和大表一样。
2、大大交,大表和大表之间关联也是一个重要的课题,当然其中要有一个主表,在逻辑上,应当是主表Left Join辅表。大表之间的关联存在最大的问题就是性能和稳定性,对于海量数据来说,必须有优化的方法来处理他们的关联,另外,对于大数据的处理无疑会占用太多的系统资源,出错的几率非常大,如何做到有效错误恢复也是个问题。对于这种情况,我们建议还是尽量将大表拆分成适度的稍小一点的表,形成大小交的类型。这类情况的输出数据粒度和主表一样。
3、站着进来,躺着出去。事务系统中为了提高系统灵活性和扩展性,很多信息放在代码表中维护,所以它的“事实表”就是一种窄表,而在数据仓库中,通常要进行宽化,从行变成列,所以称这种处理情况叫做“站着进来,躺着出去”。大家对Decode肯定不陌生,这是进行宽表化常见的手段之一。窄表变宽表的过程主要体现在对窄表中那个代码字段的操作。这种情况,窄表是输入,宽表是输出,宽表的粒度必定要比窄表粗一些,就粗在那个代码字段上。
4、聚集。数据仓库中重要的任务就是沉淀数据,聚集是必不可少的操作,它是粗化数据粒度的过程。聚集本身其实很简单,就是类似SQL中Group by的操作,选取特定字段(维度),对度量字段再使用某种聚集函数。但是对于大数据量情况下,聚集算法的优化仍是探究的一个课题。例如是直接使用SQL的Group by,还是先排序,在处理。
二、微观规则
从数据的转换的微观细节分,可以分成下面的几个基本类型,当然还有一些复杂的组合情况,例如先运算,在参照转换的规则,这种基于基本类型组合的情况就不在此列了。ETL的规则是依赖目标数据的,目标数据有多少字段,就有多少条规则。
1、直接映射,原来是什么就是什么,原封不动照搬过来,对这样的规则,如果数据源字段和目标字段长度或精度不符,需要特别注意看是否真的可以直接映射还是需要做一些简单运算。
2、字段运算,数据源的一个或多个字段进行数学运算得到的目标字段,这种规则一般对数值型字段而言。
3、参照转换,在转换中通常要用数据源的一个或多个字段作为Key,去一个关联数组中去搜索特定值,而且应该只能得到唯一值。这个关联数组使用Hash算法实现是比较合适也是最常见的,在整个ETL开始之前,它就装入内存,对性能提高的帮助非常大。
4、字符串处理,从数据源某个字符串字段中经常可以获取特定信息,例如身份证号。而且,经常会有数值型值以字符串形式体现。对字符串的操作通常有类型转换、字符串截取等。但是由于字符类型字段的随意性也造成了脏数据的隐患,所以在处理这种规则的时候,一定要加上异常处理。
5、空值判断,对于空值的处理是数据仓库中一个常见问题,是将它作为脏数据还是作为特定一种维成员?这恐怕还要看应用的情况,也是需要进一步探求的。但是无论怎样,对于可能有NULL值的字段,不要采用“直接映射”的规则类型,必须对空值进行判断,目前我们的建议是将它转换成特定的值。
6、日期转换,在数据仓库中日期值一般都会有特定的,不同于日期类型值的表示方法,例如使用8位整型20040801表示日期。而在数据源中,这种字段基本都是日期类型的,所以对于这样的规则,需要一些共通函数来处理将日期转换为8位日期值、6位月份值等。
7、日期运算,基于日期,我们通常会计算日差、月差、时长等。一般数据库提供的日期运算函数都是基于日期型的,而在数据仓库中采用特定类型来表示日期的话,必须有一套自己的日期运算函数集。
8、聚集运算,对于事实表中的度量字段,他们通常是通过数据源一个或多个字段运用聚集函数得来的,这些聚集函数为SQL标准中,包括sum,count,avg,min,max。
9、既定取值,这种规则和以上各种类型规则的差别就在于它不依赖于数据源字段,对目标字段取一个固定的或是依赖系统的值。

探求ETL本质之四(数据质量)

“不要绝对的数据准确,但要知道为什么不准确。”
这是我们在构建BI系统是对数据准确性的要求。确实,对绝对的数据准确谁也没有把握,不仅是系统集成商,包括客户也是无法确定。准确的东西需要一个标准,但首先要保证这个标准是准确的,至少现在还没有这样一个标准。客户会提出一个相对标准,例如将你的OLAP数据结果和报表结果对比。虽然这是一种不太公平的比较,你也只好认了吧。

首先在数据源那里,已经很难保证数据质量了,这一点也是事实。在这一层有哪些可能原因导致数据质量问题?可以分为下面几类:
1、数据格式错误,例如缺失数据、数据值超出范围或是数据格式非法等。要知道对于同样处理大数据量的数据源系统,他们通常会舍弃一些数据库自身的检查机制,例如字段约束等。他们尽可能将数据检查在入库前保证,但是这一点是很难确保的。这类情况诸如身份证号码、手机号、非日期类型的日期字段等。
2、数据一致性,同样,数据源系统为了性能的考虑,会在一定程度上舍弃外键约束,这通常会导致数据不一致。例如在帐务表中会出现一个用户表中没有的用户ID,在例如有些代码在代码表中找不到等。
3、业务逻辑的合理性,这一点很难说对与错。通常,数据源系统的设计并不是非常严谨,例如让用户开户日期晚于用户销户日期都是有可能发生的,一个用户表中存在多个用户ID也是有可能发生的。对这种情况,有什么办法吗?

构建一个BI系统,要做到完全理解数据源系统根本就是不可能的。特别是数据源系统在交付后,有更多维护人员的即兴发挥,那更是要花大量的时间去寻找原因。以前曾经争辩过设计人员对规则描述的问题,有人提出要在ETL开始之前务必将所有的规则弄得一清二楚。我并不同意这样的意见,倒是认为在ETL过程要有处理这些质量有问题数据的保证。一定要正面这些脏数据,是丢弃还是处理,无法逃避。如果没有质量保证,那么在这个过程中,错误会逐渐放大,抛开数据源质量问题,我们再来看看ETL过程中哪些因素对数据准确性产生重大影响。
1、规则描述错误。上面提到对设计人员对数据源系统理解的不充分,导致规则理解错误,这是一方面。另一方面,是规则的描述,如果无二义性地描述规则也是要探求的一个课题。规则是依附于目标字段的,在探求之三中,提到规则的分类。但是规则总不能总是用文字描述,必须有严格的数学表达方式。我甚至想过,如果设计人员能够使用某种规则语言来描述,那么我们的ETL单元就可以自动生成、同步,省去很多手工操作了。
2、ETL开发错误。即时规则很明确,ETL开发的过程中也会发生一些错误,例如逻辑错误、书写错误等。例如对于一个分段值,开区间闭区间是需要指定的,但是常常开发人员没注意,一个大于等于号写成大于号就导致数据错误。
3、人为处理错误。在整体ETL流程没有完成之前,为了图省事,通常会手工运行ETL过程,这其中一个重大的问题就是你不会按照正常流程去运行了,而是按照自己的理解去运行,发生的错误可能是误删了数据、重复装载数据等。

探求ETL本质之五(质量保证) 

上回提到ETL数据质量问题,这是无法根治的,只能采取特定的手段去尽量避免,而且必须要定义出度量方法来衡量数据的质量是好还是坏。对于数据源的质量,客户对此应该更加关心,如果在这个源头不能保证比较干净的数据,那么后面的分析功能的可信度也都成问题。数据源系统也在不断进化过程中,客户的操作也在逐渐规范中,BI系统也同样如此。本文探讨一下对数据源质量和ETL处理质量的应对方法。
如何应对数据源的质量问题?记得在onteldatastage列表中也讨论过一个话题-"-1的处理",在数据仓库模型维表中,通常有一条-1记录,表示“未知”,这个未知含义可广了,任何可能出错的数据,NULL数据甚至是规则没有涵盖到的数据,都转成-1。这是一种处理脏数据的方法,但这也是一种掩盖事实的方法。就好像写一个函数FileOpen(filename),返回一个错误码,当然,你可以只返回一种错误码,如-1,但这是一种不好的设计,对于调用者来说,他需要依据这个错误码进行某些判断,例如是文件不存在,还是读取权限不够,都有相应的处理逻辑。数据仓库中也是一样,所以,建议将不同的数据质量类型处理结果分别转换成不同的值,譬如,在转换后,-1表示参照不上,-2表示NULL数据等。不过这仅仅对付了上回提到的第一类错误,数据格式错误。对于数据一致性和业务逻辑合理性问题,这仍有待探求。但这里有一个原则就是“必须在数据仓库中反应数据源的质量”。
对于ETL过程中产生的质量问题,必须有保障手段。从以往的经验看,没有保障手段给实施人员带来麻烦重重。实施人员对于反复装载数据一定不会陌生,甚至是最后数据留到最后的Cube,才发现了第一步ETL其实已经错了。这个保障手段就是数据验证机制,当然,它的目的是能够在ETL过程中监控数据质量,产生报警。这个模块要将实施人员当作是最终用户,可以说他们是数据验证机制的直接收益者。
首先,必须有一个对质量的度量方法,什么是高质什么是低质,不能靠感官感觉,但这却是在没有度量方法条件下通常的做法。那经营分析系统来说,联通总部曾提出测试规范,这其实就是一种度量方法,例如指标的误差范围不能高于5%等,对系统本身来说其实必须要有这样的度量方法,先不要说这个度量方法是否科学。对于ETL数据处理质量,他的度量方法应该比联通总部测试规范定义的方法更要严格,因为他更多将BI系统看作一个黑盒子,从数据源到展现的数据误差允许一定的误差。而ETL数据处理质量度量是一种白盒的度量,要注重每一步过程。因此理论上,要求输入输出的指标应该完全一致。但是我们必须正面完全一致只是理想,对于有误差的数据,必须找到原因。
在质量度量方法的前提下,就可以建立一个数据验证框架。此框架依据总量、分量数据稽核方法,该方法在高的《数据仓库中的数据稽核技术》一文中已经指出。作为补充,下面提出几点功能上的建议:
1、提供前端。将开发实施人员当作用户,同样也要为之提供友好的用户界面。《稽核技术》一文中指出测试报告的形式,这种形式还是要依赖人为判断,在一堆数据中去找规律。到不如用OLAP的方式提供界面,不光是加上测试统计出来的指标结果,并且配合度量方法的计算。例如误差率,对于误差率为大于0的指标,就要好好查一下原因了。
2、提供框架。数据验证不是一次性工作,而是每次ETL过程中都必须做的。因此,必须有一个框架,自动化验证过程,并提供扩展手段,让实施人员能够增加验证范围。有了这样一个框架,其实它起到规范化操作的作用,开发实施人员可以将主要精力放在验证脚本的编写上,而不必过多关注验证如何融合到流程中,如何展现等工作。为此,要设计一套表,类似于DM表,每次验证结果数据都记录其中,并且自动触发多维分析的数据装载、发布等。这样,实施人员可以在每次装载,甚至在流程过程中就可以观察数据的误差率。特别是,如果数据仓库的模型能够统一起来,甚至数据验证脚本都可以确定下来,剩下的就是规范流程了。
3、规范流程。上回提到有一种ETL数据质量问题是由于人工处理导致的,其中最主要原因还是流程不规范。开发实施人员运行单独一个ETL单元是很方便的,虽然以前曾建议一个ETL单元必须是“可重入”的,这能够解决误删数据,重复装载数据问题。但要记住数据验证也是在流程当中,要让数据验证能够日常运作,就不要让实施者感觉到他的存在。总的来说,规范流程是提高实施效率的关键工作,这也是以后要继续探求的。

探求ETL本质之六(元数据漫谈) 

对于元数据(Metadata)的定义到目前为止没有什么特别精彩的,这个概念非常广,一般都是这样定义,“元数据是描述数据的数据(Data about Data)”,这造成一种递归定义,就像问小强住在哪里,答,在旺财隔壁。按照这样的定义,元数据所描述的数据是什么呢?还是元数据。这样就可能有元元元...元数据。我还听说过一种对元数据,如果说数据是一抽屉档案,那么元数据就是分类标签。那它和索引有什么区别?
元数据体现是一种抽象,哲学家从古至今都在抽象这个世界,力图找到世界的本质。抽象不是一层关系,它是一种逐步由具体到一般的过程。例如我->男人->人->哺乳动物->生物这就是一个抽象过程,你要是在软件业混会发现这个例子很常见,面向对象方法就是这样一种抽象过程。它对世界中的事物、过程进行抽象,使用面向对象方法,构建一套对象模型。同样在面向对象方法中,类是对象的抽象,接口又是对类的抽象。因此,我认为可以将“元”和“抽象”换一下,叫抽象数据是不是好理解一些。
常听到这样的话,“xx领导的讲话高屋建瓴,给我们后面的工作指引的清晰的方向”,这个成语“高屋建瓴”,站在10楼往下到水,居高临下,能砸死人,这是指站在一定的高度看待事物,这个一定的高度就是指他有够“元”。在设计模式中,强调要对接口编程,就是说你不要处理这类对象和那类对象的交互,而要处理这个接口和那个接口的交互,先别管他们内部是怎么干的。
元数据存在的意义也在于此,虽然上面说了一通都撤到哲学上去,但这个词必须还是要结合软件设计中看,我不知道在别的领域是不是存在Metadata这样的叫法,虽然我相信别的领域必然有类似的东东。元数据的存在就是要做到在更高抽象一层设计软件。这肯定有好处,什么灵活性啊,扩展性啊,可维护性啊,都能得到提高,而且架构清晰,只是弯弯太多,要是从下往上看,太复杂了。很早以前,我曾看过backorifice的代码,我靠,一个简单的功能,从这个类转到父类,又转到父类,很不理解,为什么一个简单的功能不在一个类的方法中实现就拉到了呢?现在想想,还真不能这样,这虽然使代码容易看懂了,但是结构确实混乱的,那他只能干现在的事,如果有什么功能扩展,这些代码就废了。
我从98年刚工作时就开始接触元数据的概念,当时叫做元数据驱动的系统架构,后来在QiDSS中也用到这个概念构建QiNavigator,但是现在觉得元数据也没啥,不就是建一堆表描述界面的元素,再利用这些数据自动生成界面吗。到了数据仓库系统中,这个概念更强了,是数据仓库中一个重要的部分。但是至今,我还是认为这个概念过于玄乎,看不到实际的东西,市面上有一些元数据管理的东西,但是从应用情况就得知,用的不多。之所以玄乎,就是因为抽象层次没有分清楚,关键就是对于元数据的分类(这种分类就是一种抽象过程)和元数据的使用。你可以将元数据抽象成0和1,但是那样对你的业务有用吗?必须还得抽象到适合的程度,最后问题还是“度”。
数据仓库系统的元数据作用如何?还不就是使系统自动运转,易于管理吗?要做到这一步,可没必要将系统抽象到太极、两仪、八卦之类的,业界也曾定义过一些元数据规范,向CWM、XMI等等,可以借鉴
struts2标签的使用 struts2
1、textfield值得获取显示

<s:textfield cssStyle="width:300px;"
	id="batchNum" name="#request.batchNum" readonly="true"
	 />
获取后台的值放在name属性里面,而不是value里面。
2、Struts2标签 select 如何获取Map的值:
  <s:select name="tempTableName" id="tempTableName" list="#request.libMap"  listKey="key" listValue="value"
						cssStyle="width:120px;" cssClass="select_s"  />

3、Struts2标签 select 如何获取List的值:
<s:select label="测试" list="#request.temps" listKey="ids" 
       listValue="name" headerKey="0" headerValue="-请选择-"
       multiple="true"  />
4、引用的JSTL Core Taglib
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>

5、Jsp页面下拉框选定特定的值:
<select name="workInfo.projectid" id="projectid" >
<option value="">
 请选择---
</option>                                                                                                                                                                        <s:iterator value="#request.projectList"  id="result0">
<option value="${result0.projectid}"  ${result0.projectid == projectid ? 'selected' : ''} >
<s:property value="#result0.projectname" />
</option>
</s:iterator>
</select>

6、<s:if>标签的使用
<s:iterator value="libDetailInformationList" status="arr">
	<s:if test="status==0||status==1">
		<div class="table_item">
		<div class="row_time"><s:property value="title" /></div>
		<div class="row_time"><s:property value="cdoi" /></div>
		<div class="row_time"><s:property value="createUser" /></div>
		<div class="row_time"><s:property value="publisher" /></div>
		<div class="row_time"><s:property value="batch" /></div>
		<div class="row_time"><s:if test="reserve3==0">pdf</s:if> <s:elseif
			test="reserve3==null">swf</s:elseif> <s:else></s:else></div>
		<div class="row_time"><s:property value="identifier" /></div>
		<div class="row_time"><s:property value="bookid" /></div>
		</div>
	</s:if>
</s:iterator>
获取查询结果集的序号 struts2
<s:iterator value="objects" status="arr">
	<div class="row_list"><s:property value="#arr.index+1" /></div>
</s:iterator>
Struts2的iterator各种用法 struts2
4、普通属性 
public String execute(){ 
   username = "zhangsan"; 
   password = "123"; 
} 
<s:property value="username"/><br> 
   <s:property value="password"/><br> 

5、自定义对象 
public String execute(){ 
  userInfo = new UserInfo(); 
  userInfo.setUsername("hhh"); 
  userInfo.setPassword("111"); 
} 
<s:property value="userInfo.username"/><br> 
   <s:property value="userInfo.password"/><br> 

6、List(普通属性) 
  public String execute(){ 
  list = new ArrayList<String>(); 
  list.add("aaa"); 
  list.add("bbb"); 
  list.add("ccc"); 
} 
<s:iterator value="list" var="var"> 
    <s:property value="var"/><br> 
   </s:iterator> 
   或者: 
   <s:iterator value="list"> 
    <s:property/><br> 
   </s:iterator> 
  
6、List(自定义对象属性) 
public String execute(){ 
  list = new ArrayList<UserInfo>(); 
  UserInfo userInfo = new UserInfo(); 
  userInfo.setUsername("u1"); 
  userInfo.setPassword("p1"); 
  userInfo.setRoleInfo(new RoleInfo("r1")); 
  list.add(userInfo); 
  userInfo = new UserInfo(); 
  userInfo.setUsername("u2"); 
  userInfo.setPassword("p2"); 
  userInfo.setRoleInfo(new RoleInfo("r2")); 
  list.add(userInfo); 
} 
<s:iterator value="list" var="var"> 
    <s:property value="#var.username"/> 
    <s:property value="#var.password"/> 
    <s:property value="#var.roleInfo.rolename"/><br> 
</s:iterator> 
或者: 
<s:iterator value="list"> 
    <s:property value="username"/> 
    <s:property value="password"/> 
    <s:property value="roleInfo.rolename"/><br> 
</s:iterator> 

7、数组(普通属性) 
public String execute(){ 
  strs = new String[2]; 
  strs[0] = "as"; 
  strs[1] = "asd"; 
} 
<s:iterator value="strs"> 
    <s:property/><br> 
   </s:iterator> 
或者: 
<s:iterator value="strs" var="var"> 
    <s:property value="var"/><br> 
   </s:iterator> 
  
8、数组(自定义对象属性) 
public String execute(){ 
  strs = new UserInfo[2]; 
  UserInfo userInfo = new UserInfo(); 
  userInfo.setUsername("u11"); 
  userInfo.setPassword("11"); 
  strs[0] = userInfo; 
  userInfo = new UserInfo(); 
  userInfo.setUsername("u22"); 
  userInfo.setPassword("22"); 
  strs[1] = userInfo; 
} 
<s:iterator value="strs"> 
    <s:property value="username"/> 
    <s:property value="password"/><br> 
   </s:iterator> 
或者: 
<s:iterator value="strs" var="var"> 
    <s:property value="#var.username"/> 
    <s:property value="#var.password"/><br> 
</s:iterator> 

8、数组(自定义对象属性) 
public String execute(){ 
  strs = new UserInfo[2]; 
  UserInfo userInfo = new UserInfo(); 
  userInfo.setUsername("u11"); 
  userInfo.setPassword("11"); 
  userInfo.setRoleInfo(new RoleInfo("r11")); 
  strs[0] = userInfo; 
  userInfo = new UserInfo(); 
  userInfo.setUsername("u22"); 
  userInfo.setPassword("22"); 
  userInfo.setRoleInfo(new RoleInfo("r22")); 
  strs[1] = userInfo; 
} 
<s:iterator value="strs" var="var"> 
    <s:property value="#var.username"/> 
    <s:property value="#var.password"/> 
    <s:property value="#var.roleInfo.rolename"/><br> 
</s:iterator> 
或者: 
<s:iterator value="strs"> 
    <s:property value="username"/> 
    <s:property value="password"/> 
    <s:property value="roleInfo.rolename"/><br> 
</s:iterator> 

8、Map(普通属性) 
public String execute(){ 
  map = new HashMap<String,String>(); 
  map.put("k1", "v1"); 
  map.put("k2", "v2"); 
} 
<s:iterator value="map" var="var"> 
    <s:property value="#var.key"/> 
    <s:property value="#var.value"/><br> 
</s:iterator> 
或者: 
<s:iterator value="map"> 
    <s:property value="key"/> 
    <s:property value="value"/><br> 
</s:iterator> 

8、Map(自定义对象属性) 
public String execute(){ 
  map = new HashMap<String,UserInfo>(); 
  UserInfo userInfo = new UserInfo(); 
  userInfo.setUsername("u1"); 
  userInfo.setPassword("p1"); 
  userInfo.setRoleInfo(new RoleInfo("r1")); 
  map.put("k1", userInfo); 
  userInfo = new UserInfo(); 
  userInfo.setUsername("u2"); 
  userInfo.setPassword("p2"); 
  userInfo.setRoleInfo(new RoleInfo("r2")); 
  map.put("k2", userInfo); 
} 
<s:iterator value="map" var="var"> 
    <s:property value="#var.key"/> 
    <s:property value="#var.value.username"/> 
    <s:property value="#var.value.password"/> 
    <s:property value="#var.value.roleInfo.rolename"/><br> 
</s:iterator> 
或者 
<s:iterator value="map"> 
    <s:property value="key"/> 
    <s:property value="value.username"/> 
    <s:property value="value.password"/> 
    <s:property value="value.roleInfo.rolename"/><br> 
</s:iterator> 

8、Map嵌套Map(自定义对象属性) 
public String execute(){ 
  map = new TreeMap<String,Map<String,UserInfo>>(); 
  Map<String,UserInfo> innerMap = new TreeMap<String,UserInfo>(); 
  UserInfo userInfo = new UserInfo(); 
  userInfo.setUsername("u1"); 
  userInfo.setPassword("p1"); 
  userInfo.setRoleInfo(new RoleInfo("r1")); 
  userInfo = new UserInfo(); 
  userInfo.setUsername("u11"); 
  userInfo.setPassword("p11"); 
  userInfo.setRoleInfo(new RoleInfo("r11")); 
  innerMap.put("k1", userInfo); 
  innerMap.put("k11", userInfo); 
  map.put("key1", innerMap); 
  ////////////////////////// 
  innerMap = new TreeMap<String,UserInfo>(); 
  userInfo = new UserInfo(); 
  userInfo.setUsername("u2"); 
  userInfo.setPassword("p2"); 
  userInfo.setRoleInfo(new RoleInfo("r2")); 
  userInfo = new UserInfo(); 
  userInfo.setUsername("u22"); 
  userInfo.setPassword("p22"); 
  userInfo.setRoleInfo(new RoleInfo("r22")); 
  innerMap.put("k2", userInfo); 
  innerMap.put("k22", userInfo); 
  map.put("key2", innerMap); 
} 
<s:iterator value="map" var="var"> 
    <s:iterator value="value"> 
     <s:property value="#var.key"/> 
     <s:property value="key"/> 
     <s:property value="value.username"/> 
     <s:property value="value.password"/> 
     <s:property value="value.roleInfo.rolename"/><br> 
    </s:iterator> 
</s:iterator> 
var属性的含义: 
  1、var属性为可选,如果无, <s:property value="集合中元素的属性"/> 因为集合中的对象被置于compoundRoot栈顶 
2、如果有var属性,则 <s:property value="#var.key"/> 此时集合中对象会以var为key置于Map中 
Oracle数据库导出导入 oracle
导出数据库
C:\Documents and Settings\Administrator>exp ris_u_admin/nlc_neusoft_2012@192.168.180.241/riss file=d:\ris_u_admin241.dmp owner=ris_u_admin buffer=640000
导入数据库  先要创建表空间如果表空间不存在
C:\Documents and Settings\Administrator>imp ris_u_admin/nlc_neusoft_2012@192.168
.180.242/portal file=d:\ris_u_admin241.dmp ignore=y fromuser=ris_u_admin touser=
ris_u_admin
oracle创建表空间
--创建数据表空间
create tablespace user_data     --注意user_data要和先前的数据库
logging  
datafile 'ris_u_admin241.dmp' 
size 50m  
autoextend on  
next 50m maxsize 20480m  
extent management local;  
--创建用户
create user ris_u_admin identified by nlc_neusoft_2012  
default tablespace user_data  
--赋权限
grant connect,resource,dba to ris_u_res;  

-- Grant/Revoke system privileges 
grant create any materialized view to ris_u_res;
grant create materialized view to ris_u_res;
grant select any table to ris_u_res;
grant unlimited tablespace to ris_u_res;
grant create any table to ris_u_index;
grant drop any table to ris_u_index;
grant update any table to ris_u_index;
grant insert any table to ris_u_index;
oracle 大字段操作 oracle
oracle更新大字段某个节点的sql语句
update t_data_402 t
set t.other_description = 
(select sys.xmlType.createXML(REPLACE(t2.other_description.getStringVal(),'copyright','COPYRIGHT')) from t_data_402 t2 where t2.id = t.id and t2.l_id = t.l_id) where t.batch=‘20120622_01’

XMLType字段使用方法
刚才研究了一下XMLType字段使用方法 ,现在给大家介绍一下。  主要是新增、查询、修改XMLType字段
表结构:
 
 
建表sql:
 
-- Create table
create table T_BOOK
(
  ID          VARCHAR2(32) not null,
  SYS_ID      VARCHAR2(32),
  TYPE        VARCHAR2(200),
  LIBRARY     VARCHAR2(32),
  TITLE       VARCHAR2(200),
  CREATE_USER VARCHAR2(64),
  SUBJECT     VARCHAR2(200),
  DESCRIPTION VARCHAR2(200),
  PUBLISHER   VARCHAR2(200),
  CONTRIBUTOR VARCHAR2(200),
  CREATE_DATE DATE,
  FORMAT      VARCHAR2(200),
  INENTIFIER  VARCHAR2(200),
  SOURCE      VARCHAR2(200),
  LANGUAGE    VARCHAR2(200),
  OTHER_DESC  XMLTYPE
)
tablespace DCP
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
-- Add comments to the table 
comment on table T_BOOK
  is '数字资源结构表';
-- Add comments to the columns 
comment on column T_BOOK.LIBRARY
  is '分区键';
-- Create/Recreate primary, unique and foreign key constraints 
alter table T_BOOK
  add constraint PK_T_BOOK primary key (ID)
  using index 
  tablespace DCP
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
 
 
新增记录:
 
insert into t_book 
(id,other_desc) 
values (1 , sys.xmlType.createXML('<name><a id="1" value="some values">abc</a></name>') );
 
insert into t_book 
(id,other_desc) 
values (2 , sys.xmlType.createXML('<name><a id="1" value="some values">abc</a><b id="2" value="some2 values">abc2</b></name> ') );
 
 
查询记录:
查询一个字段中不存在的元素时,返回null值
 
得到id=1的value变量的值 
select i.other_desc.extract('//name/a[@id=1]/@value').getStringVal() as ennames, id from t_book i 
 
rowid ennames id
1 some values 1
2 some values 2
 
得到a节点的值
select id,i.other_desc.getclobval(), i.other_desc.extract('//name/a/text()').getStringVal() as truename from t_book i
 添加节点
update ris_u_res.t_data_402 t
set t.other_description=insertchildxml(other_description,
'//xmlType','COPYRIGHT',xmltype('<COPYRIGHT>1</COPYRIGHT>'))
    where t.id='721577'  

得到b节点id属性的值
Select i.other_desc.extract('/name/b/@id').getStringVal()    As Name FROM t_book i where i.id='1' 
 
修改记录:
修改一个字段中不存在的元素时,不会对数据有修改,但是1rows updated,所以需要提交事务。
 
更新id为1的记录的XMLType字段的a元素的id为1的value的值为some new value 
update t_book set other_desc=updateXML(other_desc,'//name/a[@id=1]/@value','some new value') where id=1 
更新节点里面的数据
update T_DATA_892 t
   set t.other_description = updateXML(t.other_description,
                                       '//xmlType/SERIALNUM_905S',
                                       '<SERIALNUM_905S>12072</SERIALNUM_905S>')
                                                  
                                       where t.id='1591083'
JS截取字符串substr 和 substring方法的区别 js
substr 方法
返回一个从指定位置开始的指定长度的子字符串。

stringvar.substr(start [, length ])

参数
stringvar

必选项。要提取子字符串的字符串文字或 String 对象。

start

必选项。所需的子字符串的起始位置。字符串中的第一个字符的索引为 0。

length

可选项。在返回的子字符串中应包括的字符个数。

说明
如果 length 为 0 或负数,将返回一个空字符串。如果没有指定该参数,则子字符串将延续到 stringvar 的最后。

示例
下面的示例演示了substr 方法的用法。

function SubstrDemo(){
   var s, ss;                // 声明变量。
   var s = "The rain in Spain falls mainly in the plain.";
   ss = s.substr(12, 5); // 获取子字符串。
   return(ss);               // 返回 "Spain"。
}


substring 方法
返回位于 String 对象中指定位置的子字符串。

strVariable.substring(start, end)
"String Literal".substring(start, end)

参数
start

指明子字符串的起始位置,该索引从 0 开始起算。

end

指明子字符串的结束位置,该索引从 0 开始起算。

说明
substring 方法将返回一个包含从 start 到最后(不包含 end )的子字符串的字符串。

substring 方法使用 start 和 end 两者中的较小值作为子字符串的起始点。例如, strvar.substring(0, 3) 和 strvar.substring(3, 0) 将返回相同的子字符串。

如果 start 或 end 为 NaN 或者负数,那么将其替换为0。

子字符串的长度等于 start 和 end 之差的绝对值。例如,在 strvar.substring(0, 3) 和 strvar.substring(3, 0) 返回的子字符串的的长度是 3。

示例
下面的示例演示了 substring 方法的用法。

function SubstringDemo(){
   var ss;                         // 声明变量。
   var s = "The rain in Spain falls mainly in the plain..";
   ss = s.substring(12, 17);   // 取子字符串。
   return(ss);                     // 返回子字符串。
}
JS 判断字符串包含 js
1.  例子:

     var tempStr =  "tempText" ;  

     tempStr.indexOf("Texxt"); //返回大于等于0的整数值,若不包含"Text"则返回"-1。

 2. indexOf用法:

     strObj.indexOf(subString[, startIndex])

     JavaScript中indexOf函数方法返回一个整数值,指出 String 对象内子字符串的开始位置。如果没有找到子字符

     串, 则返回 -1。如果 startindex 是负数,则 startindex 被当作零。如果它比最大的字符位置索引还大,则它

     被当作最大的可能索引。 
     参数: 
     strObj : 必选项,String 对象或文字。    
     subString :必选项,要在 String 对象中查找的子字符串。  
     starIndex :可选项,该整数值指出在 String 对象内开始查找的索引。如果省略,则从字符串的开始处查找;

     如果 startindex 是负数,则 startindex 被当作零。如果它比最大的字符位置索引还大,则它被当作最大的可能

     索引。 
 3. 与lastIndexOf的区别:

     lastIndexOf() 方法则是从字符串的结尾开始检索子串。
Linux oracle 监听启动 oracle http://blog.csdn.net/xrt95050/article/details/5995692
环境:
操作系统:SUSE Linux9
数据库: oracle10gR2
 
1:更改主机host
 
[root@www ~]# hostname
linux
[root@www ~]# hostname test11
[root@www ~]# hostname
test11
[root@www ~]#
 
2:尝试重启监听
 
oracle@linux:/> lsnrctl stop
www.ixdba.net

 

LSNRCTL for Linux: Version 10.2.0.1.0 - Production on 29-11月-2006 16:51:09
Copyright (c) 1991, 2005, Oracle.  All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))
The command completed successfully
oracle@linux:/> lsnrctl start
LSNRCTL for Linux: Version 10.2.0.1.0 - Production on 29-11月-2006 16:51:32
Copyright (c) 1991, 2005, Oracle.  All rights reserved.
Starting /free/oracle/product/10.2.0/db_1/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 10.2.0.1.0 - Production
System parameter file is /free/oracle/product/10.2.0/db_1/network/admin/listener.ora
Log messages written to /free/oracle/product/10.2.0/db_1/network/log/listener.log
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 10.2.0.1.0 - Production
Start Date                29-11月-2006 16:51:32
Uptime                    0 days 0 hr. 0 min. 42 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /free/oracle/product/10.2.0/db_1/network/admin/listener.ora
Listener Log File         /free/oracle/product/10.2.0/db_1/network/log/listener.log
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))
Services Summary...
Service "PLSExtProc" has 1 instance(s).
  Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully
 
可以看到,监听启动很慢,但是最后还是能启动成功,其实这是假象,我们即可得知。
其实监听在每次启动时刻会去读系统的主机名,然后根据主机名启动lsnrctl。
 
3:测试监听连接的有效性
 
下面的standby是本地目录服务名。
oracle@linux:> sqlplus "sys/cicro@standby as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 11月 29 17:04:24 2006
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
ERROR:
ORA-12541: TNS:no listener
oracle@linux:> sqlplus "/as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 11月 29 17:07:32 2006
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
Connected.
SQL> shutdown immediate
ORA-24324: service handle not initialized
ORA-24323: value not allowed
ORA-00600: internal error code, arguments: [%s], [%s], [%s], [%s], [%s], [%s], [%s], [%s]
SQL>
SQL> select host_name from v$instance;
HOST_NAME
--------------------------------------------------------------------------------
linux
 
可以看到,此时关闭数据库也报错。数据库 v$instance中记录的hostname是linux,但是此时host name已经修改成了test11
 
5:增加 新的主机名到host中
linux:~ # vi /etc/hosts
#
# hosts         This file describes a number of hostname-to-address
#               mappings for the TCP/IP subsystem.  It is mostly
#               used at boot time, when no name servers are running.
#               On small systems, this file can be used instead of a
#               "named" name server.
# Syntax:
#
# IP-Address  Full-Qualified-Hostname  Short-Hostname
127.0.0.1       localhost
ff00::0         ipv6-mcastprefix
ff02::1         ipv6-allnodes
ff02::2         ipv6-allrouters
ff02::3         ipv6-allhosts
127.0.0.1       linux
192.168.60.253  linux
192.168.60.253  test11
 
6:重启数据库和监听
 
oracle@linux:/> lsnrctl stop
LSNRCTL for Linux: Version 10.2.0.1.0 - Production on 29-11月-2006 17:20:02
Copyright (c) 1991, 2005, Oracle.  All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))
The command completed successfully
oracle@linux:/> lsnrctl start
LSNRCTL for Linux: Version 10.2.0.1.0 - Production on 29-11月-2006 17:20:10
Copyright (c) 1991, 2005, Oracle.  All rights reserved.
Starting /free/oracle/product/10.2.0/db_1/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 10.2.0.1.0 – Production System parameter file is /free/oracle/product/10.2.0/db_1/network/admin/listener.ora
Log messages written to /free/oracle/product/10.2.0/db_1/network/log/listener.log
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.60.253)(PORT=1521)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 10.2.0.1.0 - Production
Start Date                29-11月-2006 17:20:10
Uptime                    0 days 0 hr. 0 min. 0 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /free/oracle/product/10.2.0/db_1/network/admin/listener.ora
Listener Log File         /free/oracle/product/10.2.0/db_1/network/log/listener.log
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.60.253)(PORT=1521)))
Services Summary...
Service "PLSExtProc" has 1 instance(s).
  Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully
 
看到,监听很快启动完毕。
(1):查看监听日志:
[oracle@gaojf~]$
tail  -f  /free/oracle/product/10.2.0/db_1/network/log/listener.log
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.60.144)(PORT=1521)))
Listener completed notification to CRS on start
TIMESTAMP * CONNECT DATA [* PROTOCOL INFO] * EVENT [* SID] * RETURN CODE
WARNING: Subscription for node down event still pending
05-DEC-2006 10:31:14 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=gaojf)(USER=oracle))(COMMAND=status)(ARGUMENTS=64)(SERVICE=LISTENER)(VERSION=169869568)) * status * 0
 
可以看到监听在启动的时候去读取了系统的主机名gaojf和登陆的用户oracle,因此这个主机名gaojf应该在/etc/hosts中唯一存在的,并且对oracle用户是可以使用的,
 
(2):试试用目录名连接登陆数据库试试:
oracle@linux:/> sqlplus "sys/cicro@standby as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 11月 29 17:28:07 2006
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
ERROR:
ORA-12514: TNS:listener does not currently know of service requested in connect
descriptor
 
无法连接数据库,可能是监听刚刚启动,服务没有完全启动的原因,等上5分钟
 
oracle@linux:/> sqlplus "sys/cicro@standby as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 11月 29 17:35:15 2006
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
ERROR:
ORA-12514: TNS:listener does not currently know of service requested in connect
Descriptor
 
可以看到,还是无法用目录名连接数据库:
 
(3):下面继续启动数据库
oracle@linux:> sqlplus "/as sysdba"
SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 11月 29 17:37:00 2006
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
 
oracle@linux:> sqlplus "/as sysdba"                
SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 11月 29 17:39:32 2006
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
Connected to an idle instance.
SQL> startup
ORACLE instance started.
Total System Global Area  167772160 bytes
Fixed Size                  1218316 bytes
Variable Size              62916852 bytes
Database Buffers          100663296 bytes
Redo Buffers                2973696 bytes
Database mounted.
Database opened.
SQL> select host_name from v$instance;
HOST_NAME
--------------------------------------------------------------------------------
test11
SQL>
 
看到,测试数据库中的host_name变成了test11,这个现象也说明了数据库在每次启动的时候都会读系统的主机名,然后记录到数据库中的v$instance中。
 
(4):查看此时的监听日志信息如下:
[oracle@gaojf~]$
tail  -f  /free/oracle/product/10.2.0/db_1/network/log/listener.log
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.60.144)(PORT=1521)))
Listener completed notification to CRS on start
TIMESTAMP * CONNECT DATA [* PROTOCOL INFO] * EVENT [* SID] * RETURN CODE
WARNING: Subscription for node down event still pending
05-DEC-2006 10:31:14 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=gaojf)(USER=oracle))(COMMAND=status)(ARGUMENTS=64)(SERVICE=LISTENER)(VERSION=169869568)) * status * 0
05-DEC-2006 10:33:57 * service_register * orcl * 0
05-DEC-2006 10:34:03 * service_update * orcl * 0
05-DEC-2006 10:34:18 * service_update * orcl * 0
 
可以看到,比刚才多出了几行信息,因为上面是对数据库做的open操作,所以,对数据库nomount操作就是这里的service_register,mount数据库就是这里的第二个service_update,open对应的监听信息也是service_update。
ant:如何用ant将web project打包成war包 http://blog.csdn.net/christine_ruan/article/details/7636686

        
Oracle错误 ora-12514 解决方法 oracle http://www.cnblogs.com/qixin622/archive/2012/02/23/2364412.html
成功连到数据库上之后,查看listener状态:lsnrctl status



status READY 状态,需要由非归档转为归档模式,故操作如下:

1.关闭数据库shutdown immediate 正常关闭;

2.启动数据库到mount状态,startup mount,发生报错:



3.此时查看listener状态: lsnrctl status



为status BLOCKED状态,网上搜索解决方法http://zhidao.baidu.com/question/278798900.html

4.重写listener.ora文件(蓝色为增加部分)

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc) 

      (ORACLE_HOME = f:\oracle\product\10.1.0\Db_1)
      (PROGRAM = extproc) 

    )

 (SID_DESC =
      (GLOBAL_DBNAME = orcl)
      (ORACLE_HOME = f:\oracle\product\10.1.0\Db_1)
      (SID_NAME = orcl)
    )
)

5.重启监听:lsnrctl start;查看状态lsnrctl status:



为status UNKNOWN状态。

6.连到实例,关闭数据库,启动数据库到mount状态,均正常!

查看某服务是动态注册或是静态注册。

可以使用命令lsnrctl status 来查看数据库是动态注册还是静态注册。

实例状态为UNKNOWN时,表示此服务是静态注册的设置,监听器表明他不知道关于该实例的任何信息,只有当用户发出连接请求时,他才检查该实例是否存在。

而动态注册的数据库通过状态信息中的状态为READY或BLOCKED来指明。不管何时关闭数据库,动态注册的数据库都会动态的从监听器中注销掉,而与之相关的信息将会从状态列表消失,这样不管数据库是在运行还是已经关闭,监听器都知道他的状态。

待补充。。。

************************************************************

ORACLE XE 修改方法

解决办法:

  修改目录E:\Oracle10gXEUniv\app\oracle\product\10.2.0\server\NETWORK\ADMIN下的文件tnsnames.ora、listener.ora将这两个文件中HOST后面的主机都修改为127.0.0.1然后重启OracleServiceXE、OracleXETNSListener服务
这时pl/sql developer连接oracle时报出“ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务”的错误,再次修改listener.ora文件,修改前该文件内容为
SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = E:\Oracle10gXEUniv\app\oracle\product\10.2.0\server)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (SID_NAME = CLRExtProc)
      (ORACLE_HOME = E:\Oracle10gXEUniv\app\oracle\product\10.2.0\server)
      (PROGRAM = extproc)
    )
  )
 
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
    )
  )
 
DEFAULT_SERVICE_LISTENER = (XE)
 
修改的方式是:再在该文件中添加一个需要连接的数据库实例的描述,就是添加一个SID_DESC,我自己连接的数据库实例是XE,添加后的文件内容为:
SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = E:\Oracle10gXEUniv\app\oracle\product\10.2.0\server)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (SID_NAME = CLRExtProc)
      (ORACLE_HOME = E:\Oracle10gXEUniv\app\oracle\product\10.2.0\server)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (SID_NAME = XE)
      (ORACLE_HOME = E:\Oracle10gXEUniv\app\oracle\product\10.2.0\server)
)
/*红色字体部分即为新加的数据库实例XE的实例描述,注意该实例描述的ORACLE_HOME后面不能像其它实例那样加(PROGRAM = extproc),否则会报“ORA-28547: TNS: 连接服务器失败,可能是Net8管理错误。”*/
  )
 
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
    )
  )
 
DEFAULT_SERVICE_LISTENER = (XE)
oracle查看编码以及修改编码 oracle http://blog.csdn.net/angus_17/article/details/7762472
首先查看oracle数据库的编码


SQL> select * from nls_database_parameters where parameter ='NLS_CHARACTERSET';


PARAMETER
--------------------
VALUE
--------------------
NLS_CHARACTERSET
AL32UTF8


这其来源于props$,这是表示数据库的字符集。


oracle客户端编码


SQL> select * from nls_instance_parameters where parameter='NLS_LANGUAGE';


PARAMETER
--------------------
VALUE
--------------------
NLS_LANGUAGE
SIMPLIFIED CHINESE


其来源于v$parameter,表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表会话字符集环境


select * from nls_session_parameters,其来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是alter session完成,如果会话没有特殊的设置,将与nls_instance_parameters一致。


再来说一下怎么修改oracle的字符集:


目前我的数据库环境的字符集是AL32UTF8,那么把它改成ZHS16GBK


1.首先以sysdba的身份登录上去 conn /as sysdba


2.关闭数据库shutdown immediate;


3.以mount打来数据库,startup mount


4.设置session 


 SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;


5.启动数据库


alter database open;


6.修改字符集


ALTER DATABASE CHARACTER SET ZHS16GBK;


这会可能会报错,提示我们的字符集:新字符集必须为旧字符集的超集,这时我们可以跳过超集的检查做更改:


 ALTER DATABASE character set INTERNAL_USE ZHS16GBK;


这条语句就可以了,TERNAL_USE提供的帮助就会使oracle绕过了子集与超集的验证,这条语句和上面的语句内部操作时完全相同的。


7.关闭,重新启动


SQL>shutdown immediate;
SQL> startup


当然字符集最好不要轻易修改,因为这会对数据库的数据有直接的影响,如果是生产环境的话,可能会造成不可估计得损失。
Oracle数据库如何查看当前用户角色权限及默认表空间 oracle
--查看用户的角色权限

1、查看当前用户拥有的角色权限信息:select * from role_sys_privs; 

2、查看所有用户:select * from all_users;  

3、查看当前用户的详细信息:select * from user_users; 

4、查看所有角色:select * from dba_roles;  

5、查看当前用户的角色信息:select * from user_role_privs;  

总结:ORACLE中数据字典视图分为3大类,用前缀区别,分别为:USER,ALL 和 DBA,许多数据字典视图包含相似的信息。

USER_*:有关用户所拥有的对象信息,即用户自己创建的对象信息。

ALL_*:有关用户可以访问的对象的信息,即用户自己创建的对象的信息加上其他用户创建的对象但该用户有权访问的信息。

DBA_*:有关整个数据库中对象的信息。

--查看用户和默认表空间的关系

select username,default_tablespace from dba_users; select * from user_tables;

--Oracle查询用户表空间

select * from user_all_tables; select * from user_source; select * from all_users;  
 
select * from dba_users select * from v$Session; SELECT * FROM USER_ROLE_PRIVS; select * from session_privs; SELECT * FROM DBA_ROLE_PRIVS; select * from dba_roles;   
 
SELECT NAME FROM V$DATABASE; select a.file_id "FileNo",  
 
a.tablespace_name "Tablespace_name",  
 
a.bytes "Bytes",  
 
a.bytes - sum(nvl(b.bytes, 0)) "Used",  
 
sum(nvl(b.bytes, 0)) "Free",  
 
sum(nvl(b.bytes, 0)) / a.bytes * 100 "%free"  
 
from dba_data_files a, dba_free_space b  
 
where a.file_id = b.file_id(+)  
 
group by a.tablespace_name, a.file_id, a.bytes  
 
order by a.tablespace_name; 
jdbc录入oracle clob字段信息 java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;


import oracle.jdbc.OracleConnection;
import oracle.sql.CLOB;

public class Test
{

	static Connection conn = null;
	static PreparedStatement pstm ;
	  public static void main(String[] args)
	{
			String sql = "insert into RIS_U_RES.t_data_template"
					+ "(ID, SHOW_ORDERBY, FLAG, TEMPLATE, THUMBNAIL_URL, FIELD_NUMBER, JSP_URL)" + "values (?,?,?,?,?,?,?)";
			try
			{
				File file = new File("F:/id1bak.txt");
				conn = getConnection();
				CLOB clobEN = oracle.sql.CLOB.createTemporary((OracleConnection) conn, true, 1);
				clobEN.putChars(1, readFile(file).toCharArray());
				pstm = conn.prepareStatement(sql);
				pstm.setString(1, "1");
				pstm.setString(2, "1");
				pstm.setString(3, "1");
				pstm.setClob(4, clobEN);
				pstm.setString(5, "");
				pstm.setString(6, "19");
				pstm.setString(7, "");
				pstm.executeUpdate();
				System.out.println("zkt end");

			} catch (Exception e)
			{
				// TODO: handle exception
			} finally
			{
				if (conn != null)
				{
					try
					{
						conn.close();
					} catch (SQLException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}

		}

	// 获得jdbc连接
	public static Connection getConnection()
	{

		try
		{
			Class.forName("oracle.jdbc.driver.OracleDriver");
			Connection con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.180.241:1521:riss", "ris_u_res",
					"nlc_neusoft_2012");
			con.setAutoCommit(true);
			return con;
		} catch (ClassNotFoundException cnf)
		{
			// log.error("驱动没有找到:" + cnf);
			return null;
		} catch (SQLException sqle)
		{
			// log.info("不能连接数据库:" + sqle);
			return null;
		} catch (Exception e)
		{
			// log.info("加载驱动失败:" + e);
			return null;
		}
	}

	/**
	 * 返回txt文件的编码格式.
	 * 
	 * @param file
	 * @return
	 */
	public static String getCode(File file)
	{

		InputStream inputStream = null;
		String code = "";
		try
		{
			inputStream = new FileInputStream(file);
			byte[] head = new byte[3];
			inputStream.read(head);
			code = "gb2312";
			if (head[0] == -1 && head[1] == -2)
				code = "UTF-16";
			if (head[0] == -2 && head[1] == -1)
				code = "Unicode";
			if (head[0] == -17 && head[1] == -69 && head[2] == -65)
				code = "UTF-8";
		} catch (IOException e)
		{
			e.printStackTrace();
		} finally
		{
			if (inputStream != null)
				try
				{
					inputStream.close();
				} catch (IOException e)
				{
					e.printStackTrace();
				}
		}
		return code;
	}

	public static String readFile(File file)
	{

		StringBuffer sb = new StringBuffer(10000);
		InputStream is = null;
		BufferedReader br = null;
		String line = null;
		try
		{
			String code = getCode(file);
			System.out.println(file.getAbsolutePath() + ":" + code);
			is = new FileInputStream(file);
			br = new BufferedReader(new InputStreamReader(is, code));
			while ((line = br.readLine()) != null)
			{
				sb.append(line);
				sb.append("\r\n");
			}
		} catch (FileNotFoundException e)
		{
			// e.printStackTrace();
			System.out.println(file.getAbsolutePath() + " dose not exist!");
		} catch (IOException e)
		{
			e.printStackTrace();
		} finally
		{
			if (br != null)
			{
				try
				{
					br.close();
				} catch (IOException e)
				{
					e.printStackTrace();
				}
			}
		}
		return sb.toString();
	}

	
	

}
导航菜单 js
/**
样式
*/

.chanel_list
{
	float:left;
width:auto;
background-color:#F0F0EE;
border-top:solid 3px #288dab;
}
.chanel_list_item
{
	height: 33px;
    line-height: 33px;
    border:solid 1px #DEDEDE;
	border-top:none;
	text-align:left;
	font-size:14px;
	padding-left:30px;
	cursor:pointer;
	margin-top:2px;
	background:url(../images/common/pixel_round2.png) no-repeat 15px center;
	color:#666;
}
.chanel_list_item_hover
{
	font-weight:bold;
	color:#288dab;
	border-right: none;
	background:none;
	background: url("../images/common/arrow_left.png") no-repeat scroll left center #FFFFFF;
}
.chanel_list_item_bottom
{
	height: 87px;
    border:solid 1px #DEDEDE;
	border-top:none;
}
.chanel_list_right
{
width:740px;
background-color:#fff;
border:solid 1px #288dab;
border-left:none;
border-top:solid 2px #F0F0EE;
}
.chanel_list_right_title
{
float:left;
border-left:none;
height:33px;
line-height:33px;
padding-left:20px;
width:720px;
}
.chanel_list_right_content
{
float:left;
border-left:solid 1px #288dab;
padding:10px;
padding-top:0px;

}
.chanel_list_right_item
{
background:url(../images/common/arrow.gif) no-repeat 10px 16px;
float:left;
height:35px;
line-height:35px;
margin-top:5px;
margin-left:5px;
font-size:13px;
padding-left:25px;
width:690px;
background-color:#efefef;
overflow:hidden;
}
.chanel_list_right_item_hover
{
	background-color:#FF9;
	
}



<script type="text/javascript">
<!--
var y = 0;
var x = 0;

var classid = "";
var timeoutId = 0;
jQuery(function() {
	jQuery(".chanel_list_item").bind("mouseenter", function() {
		afterMouseLeaveRes();

		var temp = jQuery(this).attr("id");
		

		y = jQuery(this).offset().top-2;
		x = jQuery(this).offset().left+jQuery(this).width()+23;
		jQuery(".chanel_list_right").css("top", y);
		jQuery(".chanel_list_right").css("left", 210);

		classid = jQuery(this).attr("id");
		jQuery(".chanel_list_right_children").hide();
		jQuery("#class_" + classid).show();

		jQuery(this).addClass("chanel_list_item_hover");
		jQuery(".chanel_list_right").show();
	});

	jQuery(".chanel_list_item").bind("mouseleave", function(e) {
		mouseX = e.pageX;
		divX = jQuery(this).offset().left + jQuery(this).width() + 23;
		if (mouseX > divX) {
			afterMouseLeaveRes();
		}
	});

	jQuery(".chanel_list_right").bind("mouseleave", function() {
		afterMouseLeaveRes();
	});
	jQuery(".chanel_list_right_item")
			.bind(
					"mouseenter",
					function() {
						jQuery(
								".chanel_list_right_item .chanel_list_right_item_hover")
								.removeClass("chanel_list_right_item_hover");
						jQuery(this).addClass(
								"chanel_list_right_item_hover");
					});
	jQuery(".chanel_list_right_item").bind("mouseleave", function() {
		jQuery(this).removeClass("chanel_list_right_item_hover");
	});
});



function afterMouseLeaveRes() {
	jQuery(".chanel_list_item_hover").removeClass("chanel_list_item_hover");
	jQuery(".chanel_list_right_item_hover").removeClass(
			"chanel_list_right_item_hover");
	jQuery("#chanel_list_right").hide();
}
	
	function secondarySearch(subjectId,parentId,parentName)
	{
		document.location.href = "<%=realPath%>/search/searchresult?subjectId="
				+ subjectId + "&parentId=" + parentId
				+ "&parentIdLevel=1&parentName=" + parentName;
	}
//-->
</script>
<!--content1-->
<div class="content_top">

	<div class="content_top_left">
		<!-- 导航菜单 -->
		<div class="chanel_list">
			<s:iterator value="menuNavigationsList" status="arr">
				<div class="chanel_list_item"
					id="<s:property value="viewClaRelEntity.cid"/>">
					<a
						href="javascript:secondarySearch('<s:property value="#request.libId"/>','<s:property value="viewClaRelEntity.cid"/>','<s:property value="viewClaRelEntity.name"/>')"><s:property
							value="viewClaRelEntity.name" /></a>
					<%-- <s:property value="viewClaRelEntity.name" /> --%>
				</div>
			</s:iterator>
		</div>

		<div id="chanel_list_right" class="chanel_list_right"
			style="left: 0px; overflow: hidden; position: absolute; top: 0px; display: none;">
			<s:iterator value="menuNavigationsList" status="arr">
				<div id="class_<s:property value="viewClaRelEntity.cid"/>"
					class="chanel_list_right_children" style="display: none">
					<div class="chanel_list_right_content">
						<s:iterator value="lsNavigationsA" status="arr">
							<div class="chanel_list_right_item"
								style=" height: auto; line-height: 15px;">
								<a style="font-weight: 900; color: #288DAB;"
									href="javascript:secondarySearch('<s:property value="#request.libId"/>','<s:property value="viewClaRelEntity.cid"/>','<s:property value="viewClaRelEntity.name"/>')">
									<s:property value="viewClaRelEntity.name" />
								</a>:
								<s:iterator value="lsNavigationBs" status="arr1">
								<s:if test="%{viewClaRelEntity.name==null}">
								<br/>
								</s:if>
								<s:else>
									<a style="font-weight: 900;"
										href="javascript:secondarySearch('<s:property value="#request.libId"/>','<s:property value="viewClaRelEntity.cid"/>','<s:property value="viewClaRelEntity.name"/>')">
										<s:property value="viewClaRelEntity.name" />、
									</a>
									</s:else>
								</s:iterator>
<br/>
							</div>
							<div style="height: 2px;"></div>

						</s:iterator>
					</div>
				</div>

			</s:iterator>
		</div>
	</div>
</div>
struts2文件下载 struts2
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
        xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
        http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
 
  <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  </filter>
  <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
  </filter-mapping>
 
</web-app>


struts.xml——这里是重点

<!DOCTYPE struts PUBLIC
         "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
         "http://struts.apache.org/dtds/struts-2.0.dtd">
 <struts>
     <package name="default" extends="struts-default">
        <action name="download" class="action.DownloadAction">
           <result type="stream">
                                <param name="contentType">application/octet-stream</param>
                                <param name="inputName">inputStream</param>
                                <param name="contentDisposition">attachment;filename="${fileName}"</param>
                                <param name="bufferSize">4096</param>
           </result>
        </action>
     </package>
 </struts>

当result为stream类型时,struts2会自动根据你配置好的参数下载文件。

其中主要使用的参数是:
contentType 指定下载文件的文件类型 —— application/octet-stream 表示无限制
inputName 流对象名 —— 比如这里写inputStream,它就会自动去找Action中的getInputStream方法。
contentDisposition 使用经过转码的文件名作为下载文件名 —— 默认格式是attachment;filename="${fileName}",将调用该Action中的getFileName方法。
bufferSize 下载文件的缓冲大小

之后写个DownloadAction:
package action;
 
import java.io.InputStream;
 
import org.apache.struts2.ServletActionContext;
 
public class DownloadAction {
       
        private String fileName;
       
        public void setFileName(String fileName) {
                this.fileName = fileName;
        }
        public InputStream getInputStream() {
                return ServletActionContext.getServletContext().getResourceAsStream("/" + fileName);
        }
       
        public String execute(){
                return "success";
        }
 
}
* 注意使用getResourceAsStream方法时,文件路径必须是以“/”开头,且是相对路径。这个路径是相对于项目根目录的。
* 可以用return new FileInputStream(fileName)的方法来得到绝对路径的文件。

在WEB-INF下随意丢一个test.txt,部署好后进入浏览器,输入tomcat地址/项目路径/download.action?fileName=test.txt即可下载到该文件。

附:contentType类型.
'ez' => 'application/andrew-inset', 
'hqx' => 'application/mac-binhex40', 
'cpt' => 'application/mac-compactpro', 
'doc' => 'application/msword', 
'bin' => 'application/octet-stream', 
'dms' => 'application/octet-stream', 
'lha' => 'application/octet-stream', 
'lzh' => 'application/octet-stream', 
'exe' => 'application/octet-stream', 
'class' => 'application/octet-stream', 
'so' => 'application/octet-stream', 
'dll' => 'application/octet-stream', 
'oda' => 'application/oda', 
'pdf' => 'application/pdf', 
'ai' => 'application/postscript', 
'eps' => 'application/postscript', 
'ps' => 'application/postscript', 
'smi' => 'application/smil', 
'smil' => 'application/smil', 
'mif' => 'application/vnd.mif', 
'xls' => 'application/vnd.ms-excel', 
'ppt' => 'application/vnd.ms-powerpoint', 
'wbxml' => 'application/vnd.wap.wbxml', 
'wmlc' => 'application/vnd.wap.wmlc', 
'wmlsc' => 'application/vnd.wap.wmlscriptc', 
'bcpio' => 'application/x-bcpio', 
'vcd' => 'application/x-cdlink', 
'pgn' => 'application/x-chess-pgn', 
'cpio' => 'application/x-cpio', 
'csh' => 'application/x-csh', 
'dcr' => 'application/x-director', 
'dir' => 'application/x-director', 
'dxr' => 'application/x-director', 
'dvi' => 'application/x-dvi', 
'spl' => 'application/x-futuresplash', 
'gtar' => 'application/x-gtar', 
'hdf' => 'application/x-hdf', 
'js' => 'application/x-javas

cript', 
'skp' => 'application/x-koan', 
'skd' => 'application/x-koan', 
'skt' => 'application/x-koan', 
'skm' => 'application/x-koan', 
'latex' => 'application/x-latex', 
'nc' => 'application/x-netcdf', 
'cdf' => 'application/x-netcdf', 
'sh' => 'application/x-sh', 
'shar' => 'application/x-shar', 
'swf' => 'application/x-shockwave-flash', 
'sit' => 'application/x-stuffit', 
'sv4cpio' => 'application/x-sv4cpio', 
'sv4crc' => 'application/x-sv4crc', 
'tar' => 'application/x-tar', 
'tcl' => 'application/x-tcl', 
'tex' => 'application/x-tex', 
'texinfo' => 'application/x-texinfo', 
'texi' => 'application/x-texinfo', 
't' => 'application/x-troff', 
'tr' => 'application/x-troff', 
'roff' => 'application/x-troff', 
'man' => 'application/x-troff-man', 
'me' => 'application/x-troff-me', 
'ms' => 'application/x-troff-ms', 
'ustar' => 'application/x-ustar', 
'src' => 'application/x-wais-source', 
'xhtml' => 'application/xhtml+xml', 
'xht' => 'application/xhtml+xml', 
'zip' => 'application/zip', 
'au' => 'audio/basic', 
'snd' => 'audio/basic', 
'mid' => 'audio/midi', 
'midi' => 'audio/midi', 
'kar' => 'audio/midi', 
'mpga' => 'audio/mpeg', 
'mp2' => 'audio/mpeg', 
'mp3' => 'audio/mpeg', 
'aif' => 'audio/x-aiff', 
'aiff' => 'audio/x-aiff', 
'aifc' => 'audio/x-aiff', 
'm3u' => 'audio/x-mpegurl', 
'ram' => 'audio/x-pn-realaudio', 
'rm' => 'audio/x-pn-realaudio', 
'rpm' => 'audio/x-pn-realaudio-plugin', 
'ra' => 'audio/x-realaudio', 
'wav' => 'audio/x-wav', 
'pdb' => 'chemical/x-pdb', 
'xyz' => 'chemical/x-xyz', 
'bmp' => 'image/bmp', 
'gif' => 'image/gif', 
'ief' => 'image/ief', 
'jpeg' => 'image/jpeg', 
'jpg' => 'image/jpeg', 
'jpe' => 'image/jpeg', 
'png' => 'image/png', 
'tiff' => 'image/tiff', 
'tif' => 'image/tiff', 
'djvu' => 'image/vnd.djvu', 
'djv' => 'image/vnd.djvu', 
'wbmp' => 'image/vnd.wap.wbmp', 
'ras' => 'image/x-cmu-raster', 
'pnm' => 'image/x-portable-anymap', 
'pbm' => 'image/x-portable-bitmap', 
'pgm' => 'image/x-portable-graymap', 
'ppm' => 'image/x-portable-pixmap', 
'rgb' => 'image/x-rgb', 
'xbm' => 'image/x-xbitmap', 
'xpm' => 'image/x-xpixmap', 
'xwd' => 'image/x-xwindowdump', 
'igs' => 'model/iges', 
'iges' => 'model/iges', 
'msh' => 'model/mesh', 
'mesh' => 'model/mesh', 
'silo' => 'model/mesh', 
'wrl' => 'model/vrml', 
'vrml' => 'model/vrml', 
'css' => 'text/css', 
'html' => 'text/html', 
'htm' => 'text/html', 
'asc' => 'text/plain', 
'txt' => 'text/plain', 
'rtx' => 'text/richtext', 
'rtf' => 'text/rtf', 
'sgml' => 'text/sgml', 
'sgm' => 'text/sgml', 
'tsv' => 'text/tab-separated-values', 
'wml' => 'text/vnd.wap.wml', 
'wmls' => 'text/vnd.wap.wmlscript', 
'etx' => 'text/x-setext', 
'xsl' => 'text/xml', 
'xml' => 'text/xml', 
'mpeg' => 'video/mpeg', 
'mpg' => 'video/mpeg', 
'mpe' => 'video/mpeg', 
'qt' => 'video/quicktime', 
'mov' => 'video/quicktime', 
'mxu' => 'video/vnd.mpegurl', 
'avi' => 'video/x-msvideo', 
'movie' => 'video/x-sgi-movie', 
'ice' => 'x-conference/x-cooltalk'
ftp服务的安装、部署和配置 linux
1.1.1 部署环境概要说明
这个服务要配置在存储服务器,图片电子书加密下载服务器,文档服务器上。
该服务是linux自带的,无需安装额外的的软件,只要在使用时启动该服务就可以了。
启动该服务后,可以在不同服务器之间进行文件的传输,上传,下载等功能。
1.1.2安装、部署前的准备工作
   Red Hat Linux5.5操作系统,安装系统时安装了ftp服务。
1.1.3 依赖
   无依赖关系
1.1.4 安装、部署和配置步聚
1)   创建用户neusoft
useradd -d /home/neusoft neusoft
2)   为neusoft设置密码
passwd neusoft
输入两次密码,如neusoft
3)   创建neusoft的配置文件
首先进入vsftpd.conf目录下:cd /etc/vsftpd/
打开vsftpd.conf文件:vi vsftpd.conf
向vsftpd.conf中添加用户配置文件指向信息(尾部):user_config_dir=/etc/vsftpd_user_conf
在etc目录下创建文件夹vsftpd_user_conf:mkdir vsftpd_user_conf
在vsftpd_user_conf中添加用户配置文件:vi neusoft。
向neusoft中加入指定功能,如
可上传:write_enable=YES
可下载:download_enable=YES
登录后的目录路径:local_root=/software
4)   控制用户目录的显示和禁止用户向上级目录跳转
进入vsftpd.conf目录下:cd /etc/vsftpd/
打开vsftpd.conf:vi vsftpd.conf
添加以下内容:
chroot_list_enable=YES  
chroot_local_user=YES   
即在chroot_list中列出的用户,可以向上级目录跳转,未在chroot_list中列出的用户,不可以向上级目录跳转 
chroot_list_file=/etc/vsftpd/chroot_list
进入/etc/vsftpd目录:cd /etc/vsftpd  
在/etc/vsftpd下创建文件chroot_list:vi chroot_list
添加允许向上级目录跳转的用户名称: root
再次登录后默认显示的路径便是:"/"(注意,此时要用FlashFXP工具登陆测试;若使用ssh工具,则无法实现这个效果,因为ssh工具做了安全处理。)
5)   ftp的使用
开启ftp服务执行:service vsftpd restart
即启动了ftp服务,以neusoft用户登录后便可进行文件的上传和下载
6)   不允许匿名用户登陆
进入vsftpd.conf目录下:cd  /etc/vsftpd
打开vsftpd.conf:vi vsftpd.conf
修改anonymous_enable=NO 即可阻止匿名用户登陆。
将java后台的代码加载到前台页面select标签 java
java 后台代码:
List<SuperRecord> list = new ArrayList<SuperRecord>();
		list = this.resClassifyService.getChildeNodeList(nodeId);
		JSONArray jsonArray = new JSONArray();
		for (int i = 0; i < list.size(); i++)
		{
			JSONObject p_json = new JSONObject();
			p_json.put("id", list.get(i).get("nodeid"));
			p_json.put("name", list.get(i).get("nodename"));
			jsonArray.add(p_json);
		}
		this.getResponse().setContentType("text/html; charset=UTF-8");
		try
		{
			this.getResponse().getWriter().write(jsonArray.toString());
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


前台js处理:
jQuery.post("/system/classify/getDropDownList.action", {
			'nodeId' : nodeId
		}, function(data) {
			var sec = document.getElementById("sec");
			
			/*
			 * 每次动态加载先清空下拉单,再添加新的选项
			 */
			sec.options.length = 0;
			var myobj = eval(data);
			for ( var i = 0; i < myobj.length; i++) {
				sec.options.add(new Option(myobj[i].name, myobj[i].id));
			}

		});


页面
 <select id="sec" style="width: 120px;" 
						<option value="">请选择---</option>
					</select>
JS动态添加select下拉框 js
动态删除select中的所有options:
       document.getElementById("ddlResourceType").options.length=0;

     动态删除select中的某一项option:
       document.getElementById("ddlResourceType").options.remove(indx); 

     动态添加select中的项option:
       document.getElementById("ddlResourceType").options.add(new Option(text,value));

     上面在IE和FireFox都能测试成功,希望以后你可以用上。
其实用标准的DOM操作也可以,就是document.createElement,appendChild,removeChild之类的。

取值方面
    function getvalue(obj)
    {
        var m=obj.options[obj.selectedIndex].value
        alert(m);//获取value
        var n=obj.options[obj.selectedIndex].text
        alert(n);//获取文本
    }

==============================================================================
1 检测是否有选中
if (objSelect.selectedIndex > - 1 ) {
// 说明选中
} else {
// 说明没有选中
}

将option设为选中:document.getElementById("province").options.selected = true;

2 删除被选中的项
objSelect.options[objSelect.selectedIndex] = null ;

3 增加项
objSelect.options[objSelect.length] = new Option( " 你好 " , " hello " );

4 修改所选择中的项
objSelect.options[objSelect.selectedIndex] = new Option( " 你好 " , " hello " );

5 得到所选择项的文本
objSelect.options[objSelect.selectedIndex].text;

6 得到所选择项的值
objSelect.options[objSelect.selectedIndex].value;
Js操作Select大全 js
判断select选项中 是否存在Value="paraValue"的Item 
向select选项中 加入一个Item 
从select选项中 删除一个Item 
删除select中选中的项 
修改select选项中 value="paraValue"的text为"paraText" 
设置select中text="paraText"的第一个Item为选中 
设置select中value="paraValue"的Item为选中 
得到select的当前选中项的value 
得到select的当前选中项的text 
得到select的当前选中项的Index 
清空select的项 
js 代码
// 1.判断select选项中 是否存在Value="paraValue"的Item        
function jsSelectIsExitItem(objSelect, objItemValue) {        
    var isExit = false;        
    for (var i = 0; i < objSelect.options.length; i++) {        
        if (objSelect.options[i].value == objItemValue) {        
            isExit = true;        
            break;        
        }        
    }        
    return isExit;        
}         
   
// 2.向select选项中 加入一个Item        
function jsAddItemToSelect(objSelect, objItemText, objItemValue) {        
    //判断是否存在        
    if (jsSelectIsExitItem(objSelect, objItemValue)) {        
        alert("该Item的Value值已经存在");        
    } else {        
        var varItem = new Option(objItemText, objItemValue);      
        objSelect.options.add(varItem);     
        alert("成功加入");     
    }        
}        
   
// 3.从select选项中 删除一个Item        
function jsRemoveItemFromSelect(objSelect, objItemValue) {        
    //判断是否存在        
    if (jsSelectIsExitItem(objSelect, objItemValue)) {        
        for (var i = 0; i < objSelect.options.length; i++) {        
            if (objSelect.options[i].value == objItemValue) {        
                objSelect.options.remove(i);        
                break;        
            }        
        }        
        alert("成功删除");        
    } else {        
        alert("该select中 不存在该项");        
    }        
}    
   
   
// 4.删除select中选中的项    
function jsRemoveSelectedItemFromSelect(objSelect) {        
    var length = objSelect.options.length - 1;    
    for(var i = length; i >= 0; i--){    
        if(objSelect[i].selected == true){    
            objSelect.options[i] = null;    
        }    
    }    
}      
   
// 5.修改select选项中 value="paraValue"的text为"paraText"        
function jsUpdateItemToSelect(objSelect, objItemText, objItemValue) {        
    //判断是否存在        
    if (jsSelectIsExitItem(objSelect, objItemValue)) {        
        for (var i = 0; i < objSelect.options.length; i++) {        
            if (objSelect.options[i].value == objItemValue) {        
                objSelect.options[i].text = objItemText;        
                break;        
            }        
        }        
        alert("成功修改");        
    } else {        
        alert("该select中 不存在该项");        
    }        
}        
   
// 6.设置select中text="paraText"的第一个Item为选中        
function jsSelectItemByValue(objSelect, objItemText) {            
    //判断是否存在        
    var isExit = false;        
    for (var i = 0; i < objSelect.options.length; i++) {        
        if (objSelect.options[i].text == objItemText) {        
            objSelect.options[i].selected = true;        
            isExit = true;        
            break;        
        }        
    }              
    //Show出结果        
    if (isExit) {        
        alert("成功选中");        
    } else {        
        alert("该select中 不存在该项");        
    }        
}        
   
// 7.设置select中value="paraValue"的Item为选中    
document.all.objSelect.value = objItemValue;    
       
// 8.得到select的当前选中项的value    
var currSelectValue = document.all.objSelect.value;    
       
// 9.得到select的当前选中项的text    
var currSelectText = document.all.objSelect.options[document.all.objSelect.selectedIndex].text;    
       
// 10.得到select的当前选中项的Index    
var currSelectIndex = document.all.objSelect.selectedIndex;    
       
// 11.清空select的项    
document.all.objSelect.options.length = 0;  
struts2中s:select标签的使用 js
1.第一个例子:

 

<s:select list="{'aa','bb','cc'}" theme="simple" headerKey="00" headerValue="00"></s:select>

 

2.第二个例子:

 

<s:select list="#{1:'aa',2:'bb',3:'cc'}"  label="abc" listKey="key" listValue="value"  headerKey="0" headerValue="aabb">

 

3.第三个例子:

 

<%

 

HashMap map = new LinkedHashMap();

map.put(1,"aaa");map.put(2,"bbb");

map.put(3,"ccc");

request.setAttribute("map",map);

request.setAttribute("aa","2");

 

%>

 

<s:select list="#request.map"  label="abc" listKey="key" listValue="value" value="#request.aa"  headerKey="0" headerValue="aabb"></s:select>


struts2的select标签中,常用的有以下几个属性:

(1)struts2中的select 标签中,必须设置的属性只有一个,即是list。

(2)select标签的list中必须有值,不然会报错。如果没有值,可以加上headerKey, headerValue,这样就可以通过了。如:

xml 代码
<s:select   name="geElement.childType" list="childTypeList" listKey="key"  listValue="value" headerKey="0" headerValue="--请选择子类型--"/>  
其中,即使list中有值,我们也通常会加上headerKey, headerValue,即列表中显示的第一个选项。注意,headerKey不可以为空,不可以为-1。

(3)list属性:通常是在action中定义的,必须是一个可以迭代的源,如为一个List, Map, Set等。如果是一个Map,那么map的key就对应于select标签中的value,map中的value就对应于select标签中的option。而如果是一个List或者是一个Set,那么可以通过listKey和listValue指定。

(4)listKey和listValue:listKey即对应于select标签中的value, listValue即对应于select标签中的option。

(5)name属性:即是表单中select的名称。

使用例子:

     比如在做人员信息管理系统中,需要设置人员的民族、籍贯等信息,而这些信息一把不需要用户手动输入,而是通过下拉框进行选择,那么使用struts2的select标签应该如何实现呢,好,请看下面:
    在Action类中,添加一个成员,String nationId;民族Id,设置getter和setter方法,添加一个Map类型的成员变量,Map nationMap;里面存放民族Id和对应的民族名称,设置getter和setter方法,在execute方法中,添加如下代码:
    nationMap.put("1","汉族");
    nationMap.put("2","苗族");
     然后,在jsp页面中使用select标签,注意要加入标签库的引用:<% taglib uri="/struts-tags" prefix="s" %>,当然了一定要加入struts2的jar包才可以哦

   使用标签:   <s:select name="nationId" list="nationMap"></s:select>
这样就可以了,简单吧!
   上面list里面用的是Map类型的变量,其实list里面也可以是List类型的变量,那么如果是List类型的变量,select标签就需要使用这种形式
      <s:select name="nationId" list="nations" key="name" value="id"/>
   其中nations是List类型的变量,里面封装了一个Bean,Bean里面定义了两个变量,一个是id,一个是name。这样就可以了。

 

 


javascript js js鼠标滑轮滚动事件绑定(兼容主流浏览器)
/** Event handler for mouse wheel event.
		 *鼠标滚动事件
		 */
		var wheel = function(event) {
			var delta = 0;
			if (!event) /* For IE. */
				event = window.event;
			if (event.wheelDelta) { /* IE/Opera. */
				delta = event.wheelDelta / 120;
			} else if (event.detail) {
				/** Mozilla case. */
				/** In Mozilla, sign of delta is different than in IE.
				 * Also, delta is multiple of 3.
				 */
				delta = -event.detail / 3;
			}
			/** If delta is nonzero, handle it.
			 * Basically, delta is now positive if wheel was scrolled up,
			 * and negative, if wheel was scrolled down.
			 */
			if (delta)
				handle(delta);
			/** Prevent default actions caused by mouse wheel.
			 * That might be ugly, but we handle scrolls somehow
			 * anyway, so don't bother here..
			 */
			if (event.preventDefault)
				event.preventDefault();
			event.returnValue = false;
		}

		/** Initialization code. 
		 * If you use your own event management code, change it as required.
		 */
		if (window.addEventListener) {
			/** DOMMouseScroll is for mozilla. */
			window.addEventListener('DOMMouseScroll', wheel, false);
		}
		/** IE/Opera. */
		window.onmousewheel = document.onmousewheel = wheel;

		/** This is high-level function.
		 * It must react to delta being more/less than zero.
		 */
		var handle = function(delta) {
			var random_num = Math.floor((Math.random() * 100) + 50);
			if (delta < 0) {
				// alert("鼠标滑轮向下滚动:" + delta + "次!"); // 1
				$("btn_next_pic").onclick(random_num);
				return;
			} else {
				// alert("鼠标滑轮向上滚动:" + delta + "次!"); // -1
				$("btn_last_pic").onclick(random_num);
				return;
			}
		}
Global site tag (gtag.js) - Google Analytics