#
先来看一张简单的文档树
很明显树的顶层节点是NodeA节点,接下来可以通过指定的合适节点移动到树中的任何点,结合以下的代码你可以更好的了解这棵树节点间的相互关系:
NodeA.firstChild = NodeA1
NodeA.lastChild = NodeA3
NodeA.childNodes.length = 3
NodeA.childNodes[0] = NodeA1
NodeA.childNodes[1] = NodeA2
NodeA.childNodes[2] = NodeA3
NodeA1.parentNode = NodeA
NodeA1.nextSibling = NodeA2
NodeA3.prevSibling = NodeA2
NodeA3.nextSibling = null
NodeA.lastChild.firstChild = NodeA3a
NodeA3b.parentNode.parentNode = NodeA
DOM定义对操作一个文档对象的节点结构提供了实用的方法,它提供了像执行对象插入,更新,删除,克隆等这些常用的方法。
insertBefore()--在参考子节点之前插入一个新的子节点.如果参考的子节点为null,则新的子节点将作为调用节点的最后一个子节点插入。
replaceChild()--在childNodes集合种使用指定的newChild来代替oldChild;如果代替成功,则返回oldChild;如果newChild是null,则只需删除oldChild即可。
removeChild()--从节点的ChildNodes集合中删除removeChild指定的节点,如果删除成功,则返回删除的子节点。
appendChild()--添加一个新节点到childNodes集合的末尾,如果成功,则返回新节点。
cloneNode()--创建一个新的、复制的节点,并且如果传入的参数是true时,还将复制子节点,如果节点是一个元素,那么还将复制相应属性,返回新的节点。
为了在一棵文档树中访问或者建立一个新的节点,可以用下面这些方法:
getElementById()
getElementsByTagName()
createElement()
createAttribute()
createTextNode()
注意:在一个页面中只有一个文档对象,除了getElementsByTagName()外,其它方法均只能通过document.methodName()调用。
再看一下下面这个例子:
<html>
<head>
<title></title>
</head>
<body>
<p>This is a sample paragraph.</p>
<SCRIPT LANGUAGE="JavaScript">
<!--
alert(document.documentElement.lastChild.firstChild.tagName);
//-->
</SCRIPT>
</body>
</html>
结果将会显示"P",下面是一些解释
document.documentElement - gives the page's HTML tag.
lastChild - gives the BODY tag.
firstChild - gives the first element in the BODY.
tagName - gives that element's tag name, "P" in this case.
另一个:
<html>
<head>
<title></title>
</head>
<body>
<p>This is a sample paragraph.</p>
<SCRIPT LANGUAGE="JavaScript">
<!--
alert(document.documentElement.lastChild.firstChild.tagName);
//-->
</SCRIPT>
</body>
</html>
这个例子和上面并没有什么大的区别,仅仅是多了一个空行,但是在NS中,会自动为空行加上一个节点所以返回值是"undefined",而在IE中将跳过空行仍然指向P标签。
更常用的方法:
<p id="myParagraph">This is a sample paragraph.</p>
...
alert(document.getElementById("myParagraph").tagName);
这种方法你不用关心节点在文档树的哪一个地方,而只要保证在页面中它的ID号是唯一的就可以了。
接下来一种访问元素节点的方法是document.getElementsByTagName(),它的返回值是一个数组,例如你可以通过下面的例子改变整个页面的连接:
var nodeList = document.getElementsByTagName("A");
for (var i = 0; i < nodeList.length; i++)
nodeList[i].style.color = "#ff0000";
attribute和attributes
attribute对象和元素相关,但是却没有被认为是文档树的一部分,因此属性不能作为子节点集合的一部分来使用。
有三种方法可以为元素建立新的属性
1.
var attr = document.createAttribute("myAttribute");
attr.value = "myValue";
var el = document.getElementById("myParagraph");
el.setAttributeNode(attr);
2.
var el = document.getElementById("myParagraph");
el.setAttribute("myAttribute", "myValue");
3.
var el = document.getElementById("myParagraph");
el.myAttribute = "myValue";
你可以在html标签种定义自己的属性:
<p id="myParagraph" myAttribute="myValue">This is a sample paragraph.</p>
...
alert(document.getElementById("myParagraph").getAttribute("myAttribute"));
返回值将是"myValue".但是请注意这里必须使用getAttribute,而不是AttributeName,因为有一些浏览器并不支持自定义属性。
attributes也可以被轻易的从一个元素中删除,你可以使用removeAttribute()或者将element.attributeName指向一个null值。
通过attributes我们就可以产生一些动态效果:
<p id="sample1" align="left">Text in a paragraph element.</p>
... code for the links ...
document.getElementById('sample1').setAttribute('align', 'left');
document.getElementById('sample1').setAttribute('align', 'right');
另一种:
<p id="sample2" style="text-align:left;">Text in a paragraph
element.</p>
... code for the links ...
document.getElementById('sample2').style.textAlign = 'left';
document.getElementById('sample2').style.textAlign = 'right';
跟上面的例子一样,展示了可用通过元素修改style中的属性,甚至是class中的.唯一要提到的是textAlign是从style中的text-align中演变而来的,有一条基本规律,就是style中的属性如果出现-则在dom中将会被去掉并且随后的一个字母将改为大写,还有一点就是如果即使元素中没有style属性,上述例子同样可以使用。
text nodes:
先看一下例子:
<p id="sample1">This is the initial text.</p>
... code for the links ...
document.getElementById('sample1').firstChild.nodeValue =
'Once upon a time...';
document.getElementById('sample1').firstChild.nodeValue =
'...in a galaxy far, far away';
首先text nodes并没有像elements那样具有id属性,所有它并不能直接通过document.getElementById()或者document.getElementsByTagName()访问
看一下下面的结构也许会更明白一些:
可以看出通过document.getElementById('sample1').firstChild.nodeValue就可以读取或者设置text nodes的值了。
另一个更加复杂一点的例子:
<p id="sample2">This is the <b>initial</b> text.</p>
它的文档结构
在这里通过document.getElementById('sample1').firstChild.nodeValue讲仅仅改变"This is the"
而initial text.将不会改变.在这里大家应该看到了它和innerHTML的不同了.当然你也可以这样用:
document.getElementById('sample3').firstChild.nodeValue =
'<b>Once</b> upon a time...';
document.getElementById('sample3').firstChild.nodeValue =
'...in a galaxy <i>far, far</i> away';
其中的html代码将不会被解释,浏览器将把他们当成普通的文本来显示。
创建和删除text nodes:
var myTextNode = document.createTextNode("my text");
通过上面的代码你可以创建一个新的text node,但是它并不是文档树的一部分,要让它显示在页面上就必须让它成为文档树中某一个节点的child,因为
text nodes不能有儿子,所以你不能将它加入到一个text nodes中,attribute也不属于文档树的一部分,这条路也不行,现在只剩下elements nodes
了,以下的例子展示了如何添加和删除一个text node:
<p id="sample1">Initial text within a paragraph element.</p>
... code to add a text node ...
var text = document.createTextNode(" new text " + (++counter1));
var el = document.getElementById("sample1");
el.appendChild(text);
... code to remove the last child node ...
var el = document.getElementById("sample1");
if (el.hasChildNodes())
el.removeChild(el.lastChild);
增加文本是很容易的,上面的代码建立了一个新的text node并且通过appendChild()方法将其加入到childNodes数组的末尾,并设置了一个counter1的全局变量,利于观察
hasChildNodes()的返回值是true or false;用来判断当前节点是否还有child,以阻止当其没有child的时候调用removeChild()产生的错误。
创建element nodes
有了上面的基础,应该更容易理解了,先看一下下面的代码
<div id="sample1">This text is in a DIV element.</div>
... code for the link ...
var paraEl, boldEl;
paraEl = document.createElement("p");
boldEl = document.createElement("b");
paraEl.appendChild(document.createTextNode("This is a new paragraph with "));
boldEl.appendChild(document.createTextNode("bold"));
paraEl.appendChild(boldEl);
paraEl.appendChild(document.createTextNode(" text added to the DIV"));
document.getElementById("sample1").appendChild(paraEl);
你还可以直接为新加的element nodes设置attribute,以下两种都可以:
boldEl.style.color = "#ffff00";
paraEl.appendChild(boldEl);
或者:
paraEl.appendChild(boldEl);
boldEl.style.color = "#ffff00";
|
、帧标志
1.<frameset></frameset>
2.<frame>
3.<noframes></noframes>
帧是由英文Frame翻译过来的,它可以用来向浏览器窗口中装载多个Html文件。即每个Html文件占据一个帧,而多个帧可以同时显示在同一个浏览器窗口中,它们组成了一个最大的帧,也即是一个包含多个Html文档的Html文件(我称它为
主文档)。帧通常的使用方法是在一个帧中放置目录(即可供选择的链接),然后将Html文件显示在另一个帧中。
1.<frameset></frameset>
<frameset></frameset>标志对放在帧的
主文档的<body></body>标志对的
外边,也可以嵌在其他帧文档中,并且可以
嵌套使用。此标志对用来定义主文档中有几个帧并且各个帧是如何排列的。它具有
rows和
cols属性,使用<frameset>标志时这两个属性
至少必须选择一个,否则浏览器只显示第一个定义的帧,剩下的一概不管,<frameset></frameset>标志对也就没有起到任何作用了。rows用来规定主文档中各个帧的
行定位,而cols用来规定主文档中各个帧的
列定位。这两个属性的取值可以是百分数、绝对像素值或
星号(“*”),其中星号代表那些未被说明的空间,如果同一个属性中出现多个星号则将
剩下的未被说明的空间平均分配。同时,所有的帧按照rows和cols的值
从左到右,然后
从上到下排列。示例如下:
<frameset rows="*,*,*"> |
总共有三个按列排列的帧,每个帧占整个浏览器窗口的1/3 |
<frameset cols="40%,*,*"> |
总共有三个按行排列的帧,第一个帧占整个浏览器窗口的40%,剩下的空间平均分配给另外两个帧 |
<frameset rows="40%,*" cols="50%,*,200"> |
总共有六个帧,先是在第一行中从左到右排列三个帧,然后在第二行中从左到右再排列三个帧,即两行三列,所占空间依据rows和cols属性的值,其中200的单位是像素 |
2.<frame>
<frame>标志放在<frameset></frameset>之间,用来定义某一个具体的帧。<frame>标志具有src和name属性,这两个属性都是必须赋值的。src是此帧的源Html文件名(包括网络路径,即相对路径或网址),浏览器将会在此帧中显示src指定的Html文件;name是此帧的名字,这个名字是用来供超文本链接标志<a
href=""
target="">中的target属性用来指定链接的Html文件将显示在哪一个帧中。例如定义了一个帧,名字是main,在帧中显示的Html文件名是jc.htm,则代码是<frame
src="jc.htm" name="main">,当您有一个链接,在点击了这个链接后,文件new.htm将要显示在名为main的帧中,则代码为<a
href="new.htm"
target="main">需要链接的文本</a>。这样一来,就可以在一个帧中建立网站的目录,加入一系列链接,当点击链接以后在另一个帧中显示被链接的Html文件。
此外,<frame>标志还有scrolling和noresize属性,scrolling用来指定是否显示滚动轴,取值可以是“yes”(显示)、“no”(不显示)或“auto”(若需要则会自动显示,不需要则自动不显示)。noresize属性直接加入标志中即可使用,不需赋值,它用来禁止用户调整一个帧的大小。
3.<noframes></noframes>
<noframes></noframes>标志对也是放在<frameset></frameset>标志对之间,用来在那些不支持帧的浏览器中显示文本或图像信息。在此标志对之间先紧跟<body></body>标志对,然后才可以使用我们在教程七以前讲过的任何标志。
下边是一个综合示例:
例8 帧标志的综合示例
主文档:
<html>
<head>
<title>帧标志的综合示例</title>
</head>
<frameset cols="25%,*">
<frame src="menu.htm" scrolling="no" name="Left">
<frame src="page1.htm" scrolling="auto" name="Main">
<noframes>
<body>
<p>对不起,您的浏览器不支持“帧”!</p>
</body>
</noframes>
</frameset>
</html>
menu.htm
<html>
<head>
<title>目录</title>
</head>
<body>
<p><font color="#FF0000">目录</font></p>
<p><a href="page1.htm" target="Main">链接到第一页</a></p>
<p><a href="page2.htm" target="Main">链接到第二页</a></p>
</body>
</html>
page1.htm
<html>
<head>
<title>第一页</title>
</head>
<body>
<p align="center"><font color="#8000FF">这是第一页!</font></p>
</body>
</html>
page2.htm
<html>
<head>
<title>第二页</title>
</head>
<body>
<p align="center"><font color="#FF0080">这是第二页!</font></p>
</body>
</html>
现在在Java开发中,使用的开发工具大部分都是Eclipse,并且和Eclipse关系紧密的要数MyEclipse了,但是MyEclipse是一个EXE可执行程序,对于没有安装Eclipse与MyEclilpse的电脑来说,首先得先解压Eclipse,然后再安装MyEclipse,这不光很麻烦,而且还很费时,对于已经安装好的电脑来说,如果哪天电脑出了问题或是Eclipse崩溃了,导致工具不能用,这时又不得不重新安装时,那可真够郁闷滴~~~,因此,大象本着我为人人,人人为我的奉献精神,在此,将Eclipse+MyEclipse的完全绿色版制作方法写出来,和大家一起分享,让大家都能享受到这种方便。
在这里,大象采用Eclipse3.3.1与MyEclipse_6.0.1GA_E3.3.1_Installer版来举例说明,其它的版本做法与此相同。
第1步:下载Eclipse3.3.1和MyEclipse_6.0.1GA
这里我要提醒大家注意一下:下载Eclipse时不要选择3.2的版本,因为MyEclipse6.0需要3.3版本以上的支持,另外就是下载MyEclipse时不要下完全版,而应该只下插件版,我的这个MyEclipse6.0.1的插件版是176M。
第2步:解压Eclipse3.3.1
将Eclipse3.3.1的压缩包解压到D盘根目录下。
做这个绿色版,把它放在根目录下是因为这样做很方便,在这里,大象以D盘为例,来说明制作方法。
第3步:安装MyEclipse6.0.1GA
双击"MyEclipse_6.0.1GA_E3.3.1_Installer.exe"开始安装MyEclipse,在第3步:"Choose Eclipse Folder"时,注意 "Please Choose Existing Eclipse Installation Folder",点击"Choose...",请选择你解压的Eclipse文件夹,选择好之后如下图:
点击"Next",出现"Where Would You Like to Install MyEclipse 6.0.1?",点击"Choose...",选择上面的eclipse文件夹,这时记得在eclipse后面加一个目录名,否则,MyEclipse的安装文件就会全部放在eclipse的根目录下,这可不是我们希望看到滴,设置好之后如下图:
下面的安装没什么好说的,就是一路Next了。安装结束后,可以在eclipse目录下看到有一个"MyEclipse 6.0.1GA"这个文件夹,进去看看,是不是有两个文件夹,两个文件?
OK,到此MyEclipse插件已经安装完成了,下面来进行我们的绿色插件制作。
第4步:插件制作
在eclipse目录下,新建一个文件夹,命名为"ThirdPlugins"(你要取别的名字也可以,不过一定要和links目录里面的配置文件中的路径一致,后面会有说明),将"MyEclipse 6.0.1GA"这个文件夹复制到"ThirdPlugins"目录下,别用剪切喔,这可是刚才安装MyEclipse的目录,等会还要缷载MyEclipse,如果这个目录没有了,到时缷载不了,出了什么问题可不要怪大象喔!
MyEclipse安装好之后,会在eclipse目录下生成一个links文件夹,里面有一个"com.genuitec.eclipse.MyEclipse.link"文件,我们删除它,另外新建一个"MyEclipse 6.0.1GA.ini"文件,内容为:path=ThirdPlugins/MyEclipse 6.0.1GA
保存完之后,我们的插件制作也结束了,然后就是缷载MyEclipse,千万不要直接把那个文件夹删掉,而应该缷载它。
其实所有的插件都可以按这个方式来做,这样做的好处就是,想用就放进去,不想用就删掉,如果放到eclipse的features和plugins里面,会很不好管理。
第5步:配置参数
虽然插件已经安装好了,但是,此时我们还不能启动它,应该对eclipse的启动参数设置一下,提高它的启动速度和运行时的稳定性。在eclipse.exe上点右键,选择"创建快捷方式",在快捷方式上点右键,选择"属性",在"D:\eclipse\eclipse.exe后面加上空格,将这些参数加在后面:
-vmargs -Xverify:none -XX:+UseParallelGC -XX:PermSize=20M -XX:MaxPermSize=128M -Xms256M -Xmx512M
-Xms256M -Xmx512M:这是堆,根据内存大小来设置,比如大象的内存是1G,我就设成256和512,这样一般都够用了。
当然了,你也可以什么都不设置,不过大象还是建议设置这些参数,可以很大程度上提升eclipse的启动速度。在安装完MyEclipse时,还会生成一个eclipse.ini的备份文件,这个不需要,删掉。我们可以修改下eclipse.ini文件,原始的如下:
-showsplash
com.genuitec.myeclipse.product
--launcher.XXMaxPermSize
256m
-vmargs
-Xms128m
-Xmx512m
-Dosgi.splashLocation=D:\eclipse\MyEclipse 6.0.1GA\eclipse\MyEclipseSplash.bmp
-Duser.language=en
-XX:PermSize=128M
-XX:MaxPermSize=256M
其实这个文件为空都没关系,大象试过,全部删除,没有错误,不过我还是建议大家里面至少保留这些东东
-vmargs
-Xms256m
-Xmx512m
我将128改成了256,如果你想在MyEclipse插件中用"MyEclipse 6.0.1"快捷方式来启动的话,可以写成这样
-vmargs
-Xms256m
-Xmx512m
-Dosgi.splashLocation=D:\Eclipse-3.3.1\ThirdPlugins\MyEclipse 6.0.1GA\eclipse\MyEclipseSplash.bmp
最下面一行是启动时,显示MyEclipse的图片,如果没有这句话运行"MyEclipse 6.0.1"快捷方式,则会显示eclipse的启动画面,其实"MyEclipse 6.0.1"快捷方式还是连接着eclipse.exe这个执行程序,在"MyEclipse 6.0.1"上点右键,选择属性,在目标里就可以看到。
第6步:注册MyEclipse
MyEclipse6.0的注册一定要断开网络,否则肯定不成功!
6.0.1GA注册码
Subscriber: administrator
Subscription Code: nLR7ZL-655342-54657656405281154
这里有一点大象要提醒大家注意,如果你电脑上现在正有使用的MyEclipse,就是说已经注册了,那么在C:\Documents and Settings\"自己的用户名" 目录下,会有一个".myeclipse.properties"文件,这时请先备份此文件,然后删除它,断开网络,再来注册MyEclipse6.0.1,成功后如下:
第7步:打包eclipse
到现在所有的工作都已经完成,启动eclipse的速度快不快?好了,该做最后一步操作了,将"configuration"文件夹下的内容除"config.ini"文件外全部删除,另外再把workspace文件夹删除,大象一般会把workspace放在eclipse根目录下,方法是在第一次启动选择路径时把前面的目录都删除,只保留workspace(前面什么都不要保留)。这样方便管理,你要放在其它的地方随便,这个看各人喜好。做完这两步之后,最好还是在eclipse目录下建一个txt文本文件,把上面的注册码放到里面,另外加上一句话:"注册时一定要断开网络,否则肯定注册不成功!"这样以后用时,可以提醒自己一下。里面有注册码,要用时很方便。
在eclipse文件夹上点右键,选择"添加到eclipse.rar",等到压缩完成,至此,终于大功告成!
大家尽管放心按着我的方法试,大象前前后后做了不下十遍,今天又在公司的电脑上做了一遍,图片都是刚刚截取的,嘿嘿,今天老板不在,大象小小的放松一下,写写博客。有了这个压缩包,以后大家在使用时就会方便很多,特别是保存到移动硬盘里,想在哪用就在哪用。哇哈哈哈哈~~~~~~~~祝大家好运,都成功做出来!
此帖为菠萝大象原创,如要转载请注明出处。
存款准备金是指金融机构为保证客户提取存款和资金清算需要而准备的在
中央银行的存款,中央银行要求的存款准备金占其存款总额的比例就是
存款准备金率。
存款准备金,是限制金融机构信贷扩张和保证客户提取存款和资金清算需要而准备的资金。法定存款准备金率,是金融机构按规定向中央银行缴纳的存款准备金占其存款的总额的比率。这一部分是一个风险准备金,是不能够用于发放贷款的。这个比例越高,执行的紧缩政策力度越大。存款准备金率变动对商业银行的作用过程如下:
当中央银行提高法定准备金率时,
商业银行可提供放款及创造信用的能力就下降。因为准备金率提高,货币乘数就变小,从而降低了整个商业银行体系创造信用、扩大信用规模的能力,其结果是社会的
银根偏紧,货币供应量减少,
利息率提高,投资及社会支出都相应缩减。反之,亦然。
打比方说,如果存款准备金率为7%,就意味着金融机构每吸收100万元存款,要向央行缴存7万元的存款准备金,用于发放贷款的资金为93万元。倘若将存款准备金率提高到7.5%,那么金融机构的可贷资金将减少到92.5万元。
在存款准备金制度下,金融机构不能将其吸收的存款全部用于发放贷款,必须保留一定的资金即存款准备金,以备客户提款的需要,因此存款准备金制度有利于保证金融机构对客户的正常支付。随着金融制度的发展,存款准备金逐步演变为重要的
货币政策工具。当中央银行降低存款准备金率时,金融机构可用于贷款的资金增加,社会的贷款总量和
货币供应量也相应增加;反之,社会的贷款总量和货币供应量将相应减少。
中央银行通过调整存款准备金率,可以影响金融机构的
信贷扩张能力,从而间接调控货币供应量。超额存款准备金率是指商业银行超过法定存款准备金而保留的准备金占全部
活期存款的比率。从形态上看,
超额准备金可以是现金,也可以是具有高流动性的
金融资产,如在中央银行账户上的准备存款等。
2006年以来,中国经济快速增长,但经济运行中的矛盾也进一步凸显,投资增长过快的势头不减。而投资增长过快的主要原因之一就是货币信贷增长过快。提高存款准备金率可以相应地减缓货币信贷增长,保持国民经济健康、协调发展。
一般地,存款准备金率上升,利率会有上升压力,这是实行紧缩的货币政策的信号。存款准备金率是针对银行等金融机构的,对最终客户的影响是间接的;利率是针对最终客户的,比如你存款的利息,影响是直接的。
1、因为
流动性过剩造成的
通货膨胀,上调准备金率可以有效降低流动性 。
2、因为现在美国的信贷危机,上调准备金率可以保证金融系统的支付能力,增加银行的抗风险能力,防止金融风险的产生。
7月19日,中国经济半年报发布。2007年上半年,中国经济增长率达11.5%,消费物价指数(CPI)则创下了33个月来的新高。一些投行当天即预测,紧缩政策已近在眼前。
我国货币供应量多、贷款增长快、超额存款准备金率较高、市场利率走低。这一“多”、一“快”、一“高”、一“低”,表明流动性过剩问题确实比较突出。
始自2003年下半年的这一轮宏观调控,一直试图用“点刹”的办法让经济减速,而今看来,这列快车的“刹车”效率似乎有问题。11.9%的增速,偏离8%的预期目标近4个百分点。中国经济不仅没有软着陆,反而有一发难收之势。
次数 时间 调整前 调整后 调整幅度
26 08年06月25日 17% 17.5% 1%
26 08年06月15日 16.5% 17%
25 08年05月20日 16% 16.5% 0.5%
24 08年04月25日 15.5% 16% 0.5%
23 08年03月25日 15% 15.5% 0.5%
22 08年01月25日 14.5% 15% 0.5%
21 07年12月25日 13.5% 14.5% 1%
20 07年11月26日 13% 13.5% 0.5%
19 07年10月13日 12.5% 13% 0.5%
18 07年09月25日 12% 12.5% 0.5%
17 07年08月15日 11.5% 12% 0.5%
16 07年06月5日 11% 11.5% 0.5%
15 07年05月15日 10.5% 11% 0.5%
14 07年04月16日 10% 10.5% 0.5%
13 07年02月25日 9.5% 10% 0.5%
12 07年01月15日 9% 9.5% 0.5%
11 06年11月15日 8.5% 9% 0.5%
10 06年08月15日 8% 8.5% 0.5%
9 06年07月05日 7.5% 8% 0.5%
8 04年04月25日 7% 7.5% 0.5%
7 03年09月21日 6% 7% 1%
6 99年11月21日 8% 6% -2%
5 98年03月21日 13% 8% -5%
4 88年9月 12% 13% 1%
3 87年 10% 12% 2%
2 85年 央行将法定存款准备金率统一调整为10%
1 84年 央行按存款种类规定法定存款准备金率,企业存款20%,农村存款25%,储蓄存款40%
今天在学习的过程中遇到了一篇关于java中使用oracle导入导出的文章,感觉还不错,为了学习和以后工作的需要,我整理如下:
String[] cmds = new String[3];
cmds[0] = "cmd";
cmds[1] = "/C";
cmds[2]=commandBuf.toString();
Process process=Runtime.getRuntime().exec(cmds);
boolean shouldClose=false;
try {
InputStreamReader isr = new InputStreamReader(process.getErrorStream());
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null){
if(line.indexOf("错误")!=-1){
shouldClose=true;
break;
}
}
}
catch (IOException ioe) {
shouldClose=true;
}
if(shouldClose)
process.destroy();
int exitVal = process.waitFor();
下面还有一种形式:
exp和imp的输出是要从ErrorStream中获取,这是我以前写的
Process proc = null;
try
{
proc = Runtime.getRuntime().exec(cmd.toString());
InputStream istr = proc.getErrorStream();
BufferedReader br = new BufferedReader(new InputStreamReader(istr));
String str;
while ((str=br.readLine()) != null)
{
errorInfo.append(str + "\n");
}
proc.waitFor();
}
catch (Exception e)
{
...
}
if (proc.exitValue() == 0)
{
proc.destroy();
return true;
}
else
{
if(logger.isDebugEnabled())
logger.debug(errorInfo);
proc.destroy();
return false;
}
两者可以比较的看看
注意:在执行oracle的exp时,出现了一个很怪的现象,就是exp在console输出的信息没有被放入InputStream,反而是放到了ErrorStream中(即使正确的情况也是),这就导致了按照正常的情况去写这段代码的话反而会出问题。---这是在jdk1.4环境下实现的。
还有中建议是在jdk1.5环境下:可以如下实现
1,把对InputStream的处理放到一个单独Thread里面。
2,用ProcessBuilder的redirectErrorStream来合并OutputStream和ErrorStream。注意子进程的InputStream对应父进程的OutStream。如果不合并这两个流的话则必须并行排空它们,顺序的排空会导致思索。
Java数据库连接(JDBC)API是一系列能够让Java编程人员访问数据库的接口,各个开发商的接口并不完全相同。在使用多年的Oracle公司的JDBC后,我积累了许多技巧,这些技巧能够使我们更好地发挥系统的性能和实现更多的功能。
1、在客户端软件开发中使用Thin驱动程序
在开发Java软件方面,Oracle的数据库提供了四种类型的驱动程序,二种用于应用软件、applets、servlets等客户端软件,另外二种用于数据库中的Java存储过程等服务器端软件。在客户机端软件的开发中,我们可以选择OCI驱动程序或Thin驱动程序。OCI驱动程序利用Java本地化接口(JNI),通过Oracle客户端软件与数据库进行通讯。Thin驱动程序是纯Java驱动程序,它直接与数据库进行通讯。为了获得最高的性能,Oracle建议在客户端软件的开发中使用OCI驱动程序,这似乎是正确的。但我建议使用Thin驱动程序,因为通过多次测试发现,在通常情况下,Thin驱动程序的性能都超过了OCI驱动程序。
2、关闭自动提交功能,提高系统性能
在第一次建立与数据库的连接时,在缺省情况下,连接是在自动提交模式下的。为了获得更好的性能,可以通过调用带布尔值false参数的Connection类的setAutoCommit()方法关闭自动提交功能,如下所示:
conn.setAutoCommit(false);
值得注意的是,一旦关闭了自动提交功能,我们就需要通过调用Connection类的commit()和rollback()方法来人工的方式对事务进行管理。
3、在动态SQL或有时间限制的命令中使用Statement对象
在执行SQL命令时,我们有二种选择:可以使用PreparedStatement对象,也可以使用Statement对象。无论多少次地使用同一个SQL命令,PreparedStatement都只对它解析和编译一次。当使用Statement对象时,每次执行一个SQL命令时,都会对它进行解析和编译。这可能会使你认为,使用PreparedStatement对象比使用Statement对象的速度更快。然而,我进行的测试表明,在客户端软件中,情况并非如此。因此,在有时间限制的SQL操作中,除非成批地处理SQL命令,我们应当考虑使用Statement对象。
此外,使用Statement对象也使得编写动态SQL命令更加简单,因为我们可以将字符串连接在一起,建立一个有效的SQL命令。因此,我认为,Statement对象可以使动态SQL命令的创建和执行变得更加简单。
4、利用helper函数对动态SQL命令进行格式化
在创建使用Statement对象执行的动态SQL命令时,我们需要处理一些格式化方面的问题。例如,如果我们想创建一个将名字O'Reilly插入表中的SQL命令,则必须使用二个相连的“''”号替换O'Reilly中的“'”号。完成这些工作的最好的方法是创建一个完成替换操作的helper方法,然后在连接字符串心服用公式表达一个SQL命令时,使用创建的helper方法。与此类似的是,我们可以让helper方法接受一个Date型的值,然后让它输出基于Oracle的to_date()函数的字符串表达式。
5、利用PreparedStatement对象提高数据库的总体效率
在使用PreparedStatement对象执行SQL命令时,命令被数据库进行解析和编译,然后被放到命令缓冲区。然后,每当执行同一个PreparedStatement对象时,它就会被再解析一次,但不会被再次编译。在缓冲区中可以发现预编译的命令,并且可以重新使用。在有大量用户的企业级应用软件中,经常会重复执行相同的SQL命令,使用PreparedStatement对象带来的编译次数的减少能够提高数据库的总体性能。如果不是在客户端创建、预备、执行PreparedStatement任务需要的时间长于Statement任务,我会建议在除动态SQL命令之外的所有情况下使用PreparedStatement对象。
6、在成批处理重复的插入或更新操作中使用PreparedStatement对象
如果成批地处理插入和更新操作,就能够显著地减少它们所需要的时间。Oracle提供的Statement和 CallableStatement并不真正地支持批处理,只有PreparedStatement对象才真正地支持批处理。我们可以使用addBatch()和executeBatch()方法选择标准的JDBC批处理,或者通过利用PreparedStatement对象的setExecuteBatch()方法和标准的executeUpdate()方法选择速度更快的Oracle专有的方法。要使用Oracle专有的批处理机制,可以以如下所示的方式调用setExecuteBatch():
PreparedStatement pstmt3D null;
try {
((OraclePreparedStatement)
pstmt).setExecuteBatch(30);
...
pstmt.executeUpdate();
}
调用setExecuteBatch()时指定的值是一个上限,当达到该值时,就会自动地引发SQL命令执行,标准的executeUpdate()方法就会被作为批处理送到数据库中。我们可以通过调用PreparedStatement类的sendBatch()方法随时传输批处理任务。
7、使用Oracle locator方法插入、更新大对象(LOB)
Oracle的PreparedStatement类不完全支持BLOB和CLOB等大对象的处理,尤其是Thin驱动程序不支持利用PreparedStatement对象的setObject()和setBinaryStream()方法设置BLOB的值,也不支持利用setCharacterStream()方法设置CLOB的值。只有locator本身中的方法才能够从数据库中获取LOB类型的值。可以使用PreparedStatement对象插入或更新LOB,但需要使用locator才能获取LOB的值。由于存在这二个问题,因此,我建议使用locator的方法来插入、更新或获取LOB的值。
8、使用SQL92语法调用存储过程
在调用存储过程时,我们可以使用SQL92或Oracle PL/SQL,由于使用Oracle PL/SQL并没有什么实际的好处,而且会给以后维护你的应用程序的开发人员带来麻烦,因此,我建议在调用存储过程时使用SQL92。
9、使用Object SQL将对象模式转移到数据库中
既然可以将Oracle的数据库作为一种面向对象的数据库来使用,就可以考虑将应用程序中的面向对象模式转到数据库中。目前的方法是创建Java bean作为伪装的数据库对象,将它们的属性映射到关系表中,然后在这些bean中添加方法。尽管这样作在Java中没有什么问题,但由于操作都是在数据库之外进行的,因此其他访问数据库的应用软件无法利用对象模式。如果利用Oracle的面向对象的技术,可以通过创建一个新的数据库对象类型在数据库中模仿其数据和操作,然后使用JPublisher等工具生成自己的Java bean类。如果使用这种方式,不但Java应用程序可以使用应用软件的对象模式,其他需要共享你的应用中的数据和操作的应用软件也可以使用应用软件中的对象模式。
10、利用SQL完成数据库内的操作
我要向大家介绍的最重要的经验是充分利用SQL的面向集合的方法来解决数据库处理需求,而不是使用Java等过程化的编程语言。
如果编程人员要在一个表中查找许多行,结果中的每个行都会查找其他表中的数据,最后,编程人员创建了独立的UPDATE命令来成批地更新第一个表中的数据。与此类似的任务可以通过在set子句中使用多列子查询而在一个UPDATE命令中完成。当能够在单一的SQL命令中完成任务,何必要让数据在网上流来流去的?我建议用户认真学习如何最大限度地发挥SQL的功能。
转帖:
最近做的一个项目中运用到了连接池技术,可能我们大家比较熟悉的开源连接池有dbcp,c3p0,proxool。对这三种连接池来说,从性能和出错率来说,proxool稍微比前两种好些。今天我主要简单的讲述一下,我在项目中成功的配置和源码。
第一步:首先去http://proxool.sourceforge.net/下载一个proxool.jar文件了,我用的是proxool-0.8.3.jar,现在最新版本是proxool-0.9.3.jar.除了他们的查看监控台的页面有变化,其他的变化不是太大。
第二步:就是写一个单独的proxool.xml文件放到WEB-INF文件夹下。我用的数据库是MySQL.
peoxool.xml的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<proxool-config>
<proxool>
<alias>db</alias>
<driver-url>jdbc:mysql://×××.×××.××.×××:3303/mydb<driver-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<driver-properties>
<property name="user" value="root" />
<property name="password" value="*******" />
</driver-properties>
<house-keeping-sleep-time>90000</house-keeping-sleep-time>
<maximum-new-connections>20</maximum-new-connections>
<prototype-count>5</prototype-count>
<maximum-connection-count>1000</maximum-connection-count>
<minimum-connection-count>10</minimum-connection-count>
</proxool>
</proxool-config>
对以上配置简单的解释:
1.<alias> :为该连接池起一个别名,在其他文件中引用。引用是:(proxool.db);
2. <driver-class>com.mysql.jdbc.Driver</driver-class>
<driver-properties>
<property name="user" value="root" />
<property name="password" value="root" />
</driver-properties>
这些配置大家应该比较熟悉吧。配置数据库的驱动和连接。
3.<house-keeping-sleep-time> :proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁。
4.<maximum-new-connections>: 指因未有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受。
5.<prototype-count>:最少保持的空闲连接数。
6.<maximum-connection-count>: 允许最大连接数,超过了这个连接,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定
7.<minimum-connection-count>:最小连接数
第三步:加载并初始化proxool.xml文件。因为它是连接数据库的,其他很多模块都用到数据,所以你必须首先加载它,在web.xml中进行如下配置:如果你以前加载applicationContext.xml用的是:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
这时你必须换成如下配置:
<servlet>
<servlet-name>contextConfigLocation</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
要不然你就会遇见这样的错误:
Problem
org.logicalcobwebs.proxool.ProxoolException: Attempt to refer to a unregistered pool by its
alias 'db'
如果用过proxool与spring整合时,不少就遇到过这样的问题,其实这个问题很明显就是你的proxool.xml没有被先加载初始化,我们应该让它先加载,应该这样配置:
<servlet>
<servlet-name>ServletConfigurator</servlet-name>
<servlet-class>
org.logicalcobwebs.proxool.configuration.ServletConfigurator
</servlet-class>
<init-param>
<param-name>xmlFile</param-name>
<param-value>WEB-INF/proxool.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
把<load-on-startup>的值设为1,值越小级别就越高,就先被加载初始化。一定要先于applicationContext.xml的加载。
这一步很关键,一定要注意,不然你就会遇到上面的问题。网上有很大人都遇见过这样的问题,只要你用了你才会体会到那样的错误。如果是第一次,你会很迷茫的,我第一次配置就出现了上面的问题,让我调试了好处时间才找出问题所在。希望你们不要再犯这样的错误。
如果你想监控数据库连接池的连接情况,可以简单的配置一下就可以了,因为大部分功能源码中都已写好,我们用是只需简单的配置。
<servlet>
<servlet-name>Admin</servlet-name>
<servlet-class>
org.logicalcobwebs.proxool.admin.servlet.AdminServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Admin</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
如果访问的话,可能有点问题,会报ISO-8859-1的问题。我们一般用的是utf-8,gbk2312.最好的解决办法就是重写源码中的AdminServlet
.java。我就是重写了这个源码。才解决了这个乱码问题。可能还有其他办法:只需简单的该一个方法就可以了。
private void printDefinitionEntry(ServletOutputStream out, String name, String value) throws IOException {
out.println(" <tr>");
out.print(" <td width=\"200\" valign=\"top\" style=\"" + STYLE_CAPTION + "\">");
out.print(name);
out.println("</td>");
if (value != null) {
out.print(" <td style=\"" + STYLE_DATA + "\">");
out.print(new String(value.getBytes("ISO-8859-1"),"utf-8"));
} else {
out.print(" <td style=\"" + STYLE_NO_DATA + "\">off");
}
out.print("</td>");
out.println(" </tr>");
}
上面红色的部分就是我改的部分,然后把web.xml中的
<servlet-class>
com.jack.servlet.AdminServlet
</servlet-class>
中<servlet-class>换成你改写的那个类。
最后一步:整合spring和proxool。在applicationContext.xml文件中把原来数据源的配置成这样:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>org.logicalcobwebs.proxool.ProxoolDriver</value>
</property>
<property name="url">
<value>proxool.db</value>
</property>
</bean>
这个 <property name="url">要配置成proxool.xml中的别名。其他地方不用该了。也可以与hibernate整合。与spring整合比较简单。我采用的就是上面的配置方式。
这样就配置完了,很清晰,很简单。如果查看监控情况的话:
http://www.××××.com/admin 就可以查看了,如果你是本地测试:改一下路径就可以了。
上面所讲述的是一个成功的配置,并在项目中成功的运用了。希望对连接池有爱好的朋友有所帮助。
Static变量的总结
1.不可从一个static方法内部发出对非static方法的调用,尽管反过来说是可以的。如果要在static方法中访问所在类的成员变量或方法,就必须首先创建相应的实例变量。
2.static变量可以通过类名直接访问,
3.static方法不能被覆盖,但是在子类中可以声明与父类惊天方法相同的方法,从而将父类的静态方法隐藏,另外自乐不能把父类的非静态方法重写为静态的:并且static方法也不能够重载(因为他们是前期绑定的,所以不能重载;不能重载的方的还有final、private)
而普通方法能被覆盖,覆盖的结果是产生多态;
例子:
package test;
class Test {
public static void main(String[] args) {
A a = new B();
a.f();
a.m();
}
}
class A {
public static void f() {
System.out.println("hello,A");
}
public void m() {
System.out.println("hello,A");
}
}
class B extends A {
public static void f() {
System.out.println("hello,B");
}
public void m() {
System.out.println("hello,B");
}
}
结果是:
hello,A
hello,B
1.根据Java Language Specification (Version 3) 8.4.8 的描述,子类在继承父类时,对于方法而言,存在两种关系:
A. override 即覆盖,这是对实例方法(instance method)而言的;子类与父类中形构相同的方法(原文中是 subsignature,它的范围比“形构相同”要大,请参考原文)会override 父类中的那个方法。
B. hide 即隐藏,这是对类方法(class method)即static 方法而言的。如果子类中定义了静态方法,则它会隐藏父类中形构相同的(原文中是 subsignature,它的范围比“形构相同要”大,请参考原文)所有方法,但如果隐藏了父类中的实例方法,则会编译报错。
2.根据上面的规范:
“override 覆盖”的前提是实例方法,只有实例方法在继承时才会出现override情况。
如果是static方法,在继承时出现的现象根本就不能用“override”这个词描述,如果static方法在父类和子类中形构一致,则被成为 hide(隐藏)。
3.因为static方法是类方法,实现时是静态绑定的(引用“JAVA 核心技术 卷1 第六版”中149页内容“private、static、final”修饰的方法是静态绑定的。其他的方法在运行时动态绑定。“interhanchi”所说的“static和final方法外都是后期绑定”并不精确),只与类相关,不会有多态性。 从编程的角度看,效果好像是“static方法不能被覆盖”;
4.从术语上看,“static方法能否被覆盖”这种说法本身就是错误的,因为“覆盖”定义的前提和基础是实例方法。
5.结论: 子类中的static方法会隐藏父类中形构相同的static方法。
final变量的总结:
Final不想做改变的理由是:设计和效率
在java中除了static方法、final方法、(private方法属于final方法)之外,其他所有的方法都是后期绑定
Final可以修饰基本类型,也可以修饰引用类型,但是当final修饰引用类型的时候,不能够改变引用指向另一个对象, 但这个对象本身的状态是可以改变的...
final String string=“final”;
是开辟了2个内存空间,在栈中的string引用在堆中的final,其中string是始终指向堆中的final这个地址的引用,不能改变。但是堆中的final却可以改变。
可以通过下面的例子来说明static final的作用:
public class Test0
{
private static final String string;
public Test0(String str)
{
string=str;
System.out.println(string);
}
public static void main(String[] args)
{
Test0 t=new Test0("hello world");
Test0 tt=new Test0("world hello");
}
}
解释说明:
1.首先正确的认识一下final, 一个final修饰的叫"终态", 而这种终态很特殊, 它指的是:"当这个变量被赋值之后成为终态". 那么,当一个被赋值之后的final修饰变量, 将不可再被赋新值. (先理解)
2.而static表示静态变量, 说穿了,你需要知道JAVA如何为一个类创建内存空间--我们知道类有空间,类产生的实例(对象)有空间,方法有空间,变量有空间, 当static修饰时, 这个变量会在类分配内存时就被分配内存了, 所以你知道,你可以不用产生对象就使用静态变量.
3.好了,有了以上两点,我们来看看, 你可以根据我的叙述试试. 首先,你只使用final修饰你的string, 你会发现不会报错, 因为这是一个"还没有被赋值的非静态的终态变量(在类分配内存时不会分配内存).好,接下来你改一下,写:private final String string = "sss"; 你会发现报错了,原因自己想.
接下来, 看你发出来的代码, 又被static修饰,又被final修饰,首先它是一个静态变量, 那么在类分配时就会分配内存, 实际上这个String就被初始化了,既然初始化了, 那么也就有值了, 而一个终态被赋值变量将不能再被赋值, 那么自然就报错了
学过Java基础的人都能很容易理解上面的代码和多态的原理,但是仍有一些关键的地方需要注意的,算是自己对多态的一个小结:
1. Java中除了static和final方法外,其他所有的方法都是运行时绑定的。private方法都被隐式指定为final的,因此final的方法不会在运行时绑定。当在派生类中重写基类中static、final、或private方法时,实质上是创建了一个新的方法。
2.在派生类中,对于基类中的private方法,最好采用不同的名字。
3.包含抽象方法的类叫做抽象类。注意定义里面包含这样的意思,只要类中包含一个抽象方法,该类就是抽象类。抽象类在派生中就是作为基类的角色,为不同的子类提供通用的接口。
4.对象清理的顺序和创建的顺序相反,当然前提是自己想手动清理对象,因为大家都知道Java垃圾回收器。
5.在基类的构造方法中小心调用基类中被重写的方法,这里涉及到对象初始化顺序。
6.构造方法是被隐式声明为static方法。
7.用继承表达行为间的差异,用字段表达状态上的变化。