??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
]]>
]]>
]]>
主键由外部程序负责生成,无需Hibernate参与?br />
2) hilo
通过hi/lo 法实现的主键生成机Ӟ需要额外的数据库表保存?br />
键生成历史状态?br />
3) seqhilo
与hilo cMQ通过hi/lo 法实现的主键生成机Ӟ只是主键历史
状态保存在Sequence中,适用于支持Sequence的数据库Q如Oracle?br />
4) increment
主键按数值顺序递增。此方式的实现机制ؓ在当前应用实例中l持
一个变量,以保存着当前的最大|之后每次需要生成主键的时?br />
此值加1作ؓ主键?br />
q种方式可能产生的问题是Q如果当前有多个实例讉K同一个数?br />
库,那么׃各个实例各自l护主键状态,不同实例可能生成同样
的主键,从而造成主键重复异常。因此,如果同一数据库有多个?br />
例访问,此方式必避免用?br />
5) identity
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL
中的主键生成机制?br />
6) sequence
采用数据库提供的sequence 机制生成主键。如Oralce 中的
Sequence?br />
7) native
?span class="hilite1">HibernateҎ底层数据库自行判断采用identity、hilo、sequence
其中一U作?span class="hilite2">主键生成方式?br />
8) uuid.hex
?span class="hilite1">HibernateZ128 位唯一g生算法生?6 q制数|~码?br />
以长?2 的字W串表示Q作Z键?br />
9) uuid.string
与uuid.hex cMQ只是生成的主键未进行编码(长度16Q。在某些
数据库中可能出现问题Q如PostgreSQLQ?br />
10) foreign
使用外部表的字段作ؓ主键?br />
一般而言Q利用uuid.hex方式生成主键提供最好的性能和数据库q_?br />
应性?br />
另外׃常用的数据库Q如Oracle、DB2、SQLServer、MySql {,都提
供了易用的主键生成机ӞAuto-Increase 字段或者SequenceQ。我们可以在?br />
据库提供的主键生成机制上Q采用generator-class=native?span class="hilite2">主键生成方式?br />
不过值得注意的是Q一些数据库提供的主键生成机制在效率上未必最佻I
大量q发insert数据时可能会引v表之间的互锁?br />
数据库提供的主键生成机制Q往往是通过在一个内部表中保存当前主键状
态(如对于自增型主键而言Q此内部表中q护着当前的最大值和递增量)Q?br />
之后每次插入数据会读取这个最大|然后加上递增量作为新记录的主键,?br />
后再把这个新的最大值更新回内部表中Q这P一ơInsert操作可能D数据
库内部多ơ表d操作Q同时伴随的q有数据的加锁解锁操作,q对性能产生
了较大媄响?br />
因此Q对于ƈ发Insert要求较高的系l,推荐采用uuid.hex 作ؓ主键生成
机制?
]]>
曄有许多h问vQ?#8220;怎样才能‘用’览器的后退按钮Q?#8221;Q或?#8220;怎样才能防止用户点击后退按钮q回以前览q的面Q?#8221;我访问了许多|站Q参考了q些|站所介绍的各U实现方法。如果你l常讉KASP~程|站Q本文所介绍的部分内容你可能已经见到q。本文的d是把各种可能的方法都介绍l大Ӟ然后扑և最好的ҎQ?nbsp;
二、禁止缓?nbsp;
在我扑ֈ的许多方案中Q其中有一U徏议禁止页面缓存。具体是使用服务器端脚本Q如下所C:
<%
Response.Buffer = True
Response.ExpiresAbsolute = Now() - 1
Response.Expires = 0
Response.CacheControl = "no-cache"
%>
q种Ҏ非常有效Q它强制览器重新访问服务器下蝲面Q而不是从~存d面。用这U方法时Q编E者的主要d是创Z个会话的变量,通过q个变量定用户是否仍旧可以查看那个不适合通过后退按钮讉K的页面。由于浏览器不再~存q个面Q当用户点击后退按钮时浏览器重C载该面Q此时程序就可以查那个会话变量,看看是否应该允许用户打开q个面?nbsp;
例如Q假设我们有如下表单Q?nbsp;
<%
Response.Buffer = True
Response.ExpiresAbsolute = Now() - 1
Response.Expires = 0
Response.CacheControl = "no-cache"
If Len(Session("FirstTimeToPage")) > 0 then
"用户已经讉Kq当前页面,现在是再ơ返回访问?nbsp;
"清除会话变量Q将用户重定向到d面?nbsp;
Session("FirstTimeToPage") = ""
Response.Redirect "/Bar.asp"
Response.End
End If
"如果E序q行到这里,说明用户能够查看当前面
"以下开始创?nbsp;
%>
<form method=post action="SomePage.asp">
<input type=submit>
</form>
我们借助会话变量FirstTimeToPage查用h否是W一ơ访问当前页面。如果不是第一ơ(即Session ("FirstTimeToPage")包含某个|Q那么我们就清除会话变量的|然后把用户重新定向到一个开始页面。这P当表单提交时Q此?SompePage.asp被打开Q,我们必须赋予FirstTimeToPage一个倹{即Q在SomePage.asp中我们需要加上下面的代码Q?
Session("FirstTimeToPage") = "NO"
q样Q已l打开SomePage.asp的用户如果点d退按钮Q浏览器重新请求服务器下蝲面Q服务器查到Session ("FirstTimeToPage")包含了一个|于是清除Session("FirstTimeToPage")Qƈ把用户重定向到其他页面。当Ӟ所有这一切都需要用户启用了CookieQ否则会话变量将是无效的?nbsp;
另外Q我们也可以用客L代码使浏览器不再~存Web面Q?nbsp;
<html>
<head>
<meta http-equiv="Expires" CONTENT="0">
<meta http-equiv="Cache-Control" CONTENT="no-cache">
<meta http-equiv="Pragma" CONTENT="no-cache">
</head>
如果使用上面的方法强制浏览器不再~存Web面Q必L意以下几点:
只有在用安全连接时“Pragma: no-cache”才防止浏览器~存面。对于不受安全保护的面Q?#8220;Pragma: no-cache”被视Z“Expires: -1”相同Q此时浏览器仍旧~存面Q但把页面标Cؓ立即q期?nbsp;
在IE 4?中,“Cache-Control”META HTTP-EQUIV标记被忽略Q不起作用?nbsp;
在实际应用中我们可以加上所有这些代码。然而,׃q种Ҏ不能适用于所有的览器,所以是不推荐用的。但如果是在Intranet环境下,理员可以控制用户用哪U浏览器Q我惌是有Z使用q种Ҏ?
三、其他方?nbsp;
接下来我们要讨论的方法以后退按钮本nZ心,而不是浏览器~存。这儿有一文章Rewiring the Back Button很值得参考。不q我注意刎ͼ如果使用q种ҎQ虽然用LM下后退按钮时他不会看到以前输入数据的页面,但只要点Mơ就可以Q这可不是我们希望的
效果Q因为很多时候,固执的用hL能够扑ֈl过预防措施的办法?nbsp;
另外一U禁用后退按钮的办法是用客LJavaScript打开一个没有工h的窗口,q得用户很难返回前一面Q但不是不可能。一U更安全但相当恼人的Ҏ是,当表单提交时打开一个新的窗口,与此同时关闭表单所在的H口。但我觉得这U方法不值得认真考虑Q因为我
们M能让用户每提交一个表单就打开一个新H口?nbsp;
那么Q在那个我们不想让用戯回的面是否也可以加入JavaScript代码呢?在这个页面中加入的JavaScript代码可用来生点dq按钮的效果Q这样也抵消了用户点击后退按钮所产生的动作。用于实现该功能的JavaScript代码如下所C:
<script language="JavaScript">
<!--
javascript:window.history.forward(1);
//-->
</script>
同样圎ͼq种Ҏ虽然有效Q但距离“最好的Ҏ”q差得很q。后来我又看到有人徏议用location.replace从一个页面{到另一个页面。这U方法的原理是,用新面的URL替换当前的历史纪录,q样览历史记录中就只有一个页面,后退按钮永远不会变ؓ可用。我惌可能正是许多人所L的方法,但这U方法仍旧不是Q何情况下的最好方法。用这U方法的实例如下所C:
<A HREF="PageName.htm" onclick="javascript:location.replace(this.href); event.returnValue=false; ">
止后退到本面的链?nbsp;
试试下面q个链接Q?nbsp;
止后退到本面的链接!
q种Ҏ的缺点在于:单地q用Response.Redirect不再有效,q是因ؓ每次用户从一个页面{到另一个页面,我们都必ȝ客户端代码清?location.history。另外还要注意,q种Ҏ清除的是最后一个访问历史记录,而不是全部的讉K记录?nbsp;
点击上面的链接,你将打开一个简单的HTML面。再点击后退按钮Q你可以看到q时打开的不是本面Q而是本页面之前的面Q(当然Q你必须在浏览器中启用了客户端JavaScript代码。)
l过一番仔l的d觅觅之后Q我发现仍旧无法扑և真正能够完全用览器后退按钮的办法。所有这里介l的Ҏ都能够在不同E度上、以不同的方式禁止用戯回前一面Q但它们都有各自的局限。由于不存在能够完全用后退按钮的方法,所以最好的Ҏ应该是:混合q用客户端脚本和服务器端脚本?
]]>
]]>
]]>
]]>
zip压羃文gl构:一个zip文g由多个entryl成,每个entry有一个唯一的名U?entry的数据项存储压羃数据?
与zip文g有关的几个Javac?
·cZipEntry
public ZipEntry(String name);
name为指定的数据名?
·cZipOutputStream
ZipOutputStream实现了zip压羃文g的写输出?支持压羃和非
public ZipOutputStream(OutputStream out);
∥利用输出流out构造一个ZIP输出?
public void setMethod(int method);
∥设|entry压羃Ҏ,~省gؓDEFLATED?
public void putNextEntry(ZipEntry newe);
∥如果当前的entry存在且处于激zȝ态时,关闭?在zip文g
中写入新的entry-newe
q将数据定位于entry数据的起始位置,压羃Ҏ为setMethod?br>定的Ҏ?
·cZipInputStream
ZipInputStream实现了zip压羃文g的读输入?支持压羃和非
压羃entry。下面是它的
几个函数:
public ZipInputStream(InputStream in);
∥利用输入流in构造一个ZIP输出?
public ZipEntry getNextEntry();
∥返回ZIP文g中的下一个entry,q将输出定位在此entry数据的起始位置?
public void closeEntry();
∥关闭当前的zip entry,q将数据定位于下一个entry的v始位|?
E序代码及其注释
下列的程序实C数据文gzip方式的压~和解压~方法。randomData()函数随机生成50个double数据,q放在doc字符串变量中;openFile()函数dZIP压羃文g;saveFile()函数随机生成的数据存到ZIP格式的压~文件中?
import java.util.zip.*;
import java.awt.event.*;
import java.awt.*;
import java.lang.Math;
import java.io.*;
public class TestZip extends Frame implements
ActionListener {
TextArea textarea; ∥显C数据文件的多行文本昄?
TextField infotip; ∥显C数据文件未压羃大小及压~大单
行文本显C域
String doc; ∥存储随机生成的数据
long doczipsize = 0;∥压~数据文件的大小
public TestZip(){
∥生成菜?
MenuBar menubar = new MenuBar();
setMenuBar(menubar);
Menu file = new Menu("File",true);
menubar.add(file);
MenuItem neww= new MenuItem("New");
neww.addActionListener(this);
file.add(neww);
MenuItem open=new MenuItem("Open");
open.addActionListener(this);
file.add(open);
MenuItem save=new MenuItem("Save");
save.addActionListener(this);
file.add(save);
MenuItem exit=new MenuItem("Exit");
exit.addActionListener(this);
file.add(exit);
∥随机生成的数据文g的多行文本显C域
add("Center",textarea = new TextArea());
∥提C文本原始大、压~大的单行文本昄?
add("South",infotip = new TextField());
}
public static void main(String args[]){
TestZip ok=new TestZip();
ok.setTitle("zip sample");
ok.setSize(600,300);
ok.show();
}
private void randomData(){
∥随机生?0个double数据,q放在doc字符串变量中?
doc="";
for(int i=1;i<51;i++){
double rdm=Math.random()*10;
doc=doc+new Double(rdm).toString();
if(i%5 == 0) doc=doc+"\n";
else doc=doc+" ";
}
doczipsize = 0;
showTextandInfo();
}
private void openFile(){
∥打开zip文g,文件内容读入doc字符串变量中?
FileDialog dlg=new
FileDialog(this,"Open",FileDialog.LOA D);
dlg.show();
String filename=dlg.getDirectory()+dlg.getFile();
try{
∥创Z个文件实?
File f=new File(filename);
if(!f.exists()) return; ∥文件不存在,则返?
∥用文g输入构建ZIP压羃输入?
ZipInputStream zipis=new ZipInputStream(new
FileInputStream(f));
zipis.getNextEntry();
∥将输入定位在当前entry数据位|?
DataInputStream dis=new DataInputStream(zipis);
∥用ZIP输入构建DataInputStream
doc=dis.readUTF();∥读取文件内?
dis.close();∥关闭文?
doczipsize = f.length();∥获取ZIP文g长度
showTextandInfo();∥显C数?
}
catch(IOException ioe){
System.out.println(ioe);
}
}
private void saveFile(){
∥打开zip文g,doc字符串变量写入zip文g中?
FileDialog dlg=new
FileDialog(this,"Save",FileDialog.SAVE);
dlg.show();
String filename=dlg.getDirectory()+dlg.getFile();
try{
∥创Z个文件实?
File f=new File(filename);
if(!f.exists()) return; ∥文件不存在,则返?
∥用文g输出构建ZIP压羃输出?
ZipOutputStream zipos=new ZipOutputStream(new
FileOutputStream(f));
zipos.setMethod(ZipOutputStream.DEFLATED); ∥设|压~方
?
zipos.putNextEntry(new ZipEntry("zip"));
∥生成一个ZIP entry,写入文g输出中,q将输出定位于
entry起始处?
DataOutputStream os=new DataOutputStream(zipos);
∥用ZIP输出构建DataOutputStream;
os.writeUTF(doc);∥将随机生成的数据写入文件中
os.close();∥关闭数据流
doczipsize = f.length();
∥获取压~文件的长度
showTextandInfo();∥显C数?
}
catch(IOException ioe){
System.out.println(ioe);
}
}
private void showTextandInfo(){
∥显C数据文件和压羃信息
textarea.replaceRange(doc,0,textarea.getText().length());
infotip.setText("uncompressed size:
"+doc.length()+"compressed size: "+dc zipsize);
}
public void actionPerformed(ActionEvent e){
String arg = e.getActionCommand();
if ("New".equals(arg)) randomData();
else if ("Open".equals(arg)) openFile();
else if ("Save".equals(arg)) saveFile();
else if ("Exit".equals(arg)){
dispose();∥关闭窗?
System.exit(0);∥关闭程?
}
else {
System.out.println("no this command!");
}
}
}