本文对Oracle数据的导入导?imp ,exp 两个命oq行了介l? q对其相应的参数q行了说?然后通过一些示例进行演l?加深理解.
文章最后对q用q两个命令可能出现的问题(如权限不?不同oracle版本)q行了探?q提Z相应的解x?
本文部分内容摘录自网l?感谢|友的经验ȝ;
一.说明
oracle 的exp/imp命o用于实现Ҏ(gu)据库的导?导入操作;
exp命o用于把数据从q程数据库服务器导出x?生成dmp文g;
imp命o用于把本地的数据库dmp文g从本地导入到q程的Oracle数据库中?/p>
?语法
可以通过在命令行输入 imp help=y 获取imp的语法信?
=============================================================================
C:\Documents and Settings\auduser>imp help=y
Import: Release 9.0.1.1.1 - Production on 星期?5?20 18:21:57 2008
(c) Copyright 2001 Oracle Corporation. All rights reserved.
可以通过输入 IMP 命o和?zhn)的用户?口o
后接用户?口o的命?
例程: IMP SCOTT/TIGER
或? 可以通过输入 IMP 命o和各U参数来控制“导入”
按照不同参数。要指定参数Q?zhn)可以使用关键?
格式: IMP KEYWORD=value ?KEYWORD=(value1,value2,...,vlaueN)
例程: IMP SCOTT/TIGER IGNORE=Y TABLES=(EMP,DEPT) FULL=N
?TABLES=(T1: P1,T1: P2)Q如?T1 是分
USERID 必须是命令行中的W一个参数?/p>
关键?nbsp; 说明Q默认) 关键?nbsp; 说明Q默认)
--------------------------------------------------------------------------
USERID 用户?口o FULL 导入整个文g (N)
BUFFER 数据~冲区大?nbsp; FROMUSER 所有h用户名列?br /> FILE 输入文g (EXPDAT.DMP) TOUSER 用户名列?br /> SHOW 只列出文件内?(N) TABLES 表名列表
IGNORE 忽略创徏错误 (N) RECORDLENGTH IO 记录的长?br /> GRANTS 导入权限 (Y) INCTYPE 增量导入cd
INDEXES 导入索引 (Y) COMMIT 提交数组插入 (N)
ROWS 导入数据?(Y) PARFILE 参数文g?br /> LOG 屏幕输出的日志文?nbsp; CONSTRAINTS 导入限制 (Y)
DESTROY 覆盖表空间数据文?(N)
INDEXFILE 表/索引信息写入指定的文?br /> SKIP_UNUSABLE_INDEXES 跌不可用烦引的l护 (N)
FEEDBACK ?x 行显C?(0)
TOID_NOVALIDATE 跌指定cd ID 的验?br /> FILESIZE 每个转储文g的最大大?br /> STATISTICS 始终导入预计的l计信息
RESUMABLE 遇到与空格有关的错误时挂?(N)
RESUMABLE_NAME 用来标识可恢复语句的文本字符?br /> RESUMABLE_TIMEOUT RESUMABLE 的等待时?br /> COMPILE ~译q程, E序包和函数 (Y)
下列关键字仅用于可传输的表空?br /> TRANSPORT_TABLESPACE 导入可传输的表空间元数据 (N)
TABLESPACES 要传输到数据库的表I间
DATAFILES 要传输到数据库的数据文?br /> TTS_OWNERS 拥有可传输表I间集中数据的用?/p>
==============================================
同样可以通过输入 exp help=y 获取exp的语法信?/p>
Microsoft Windows XP [版本 5.1.2600]
(C) 版权所?1985-2001 Microsoft Corp.
C:\Documents and Settings\auduser>exp help=y
Export: Release 9.0.1.1.1 - Production on 星期?5?20 18:26:34 2008
(c) Copyright 2001 Oracle Corporation. All rights reserved.
通过输入 EXP 命o和用户名/口oQ?zhn)可?br /> 后接用户?口o的命?
例程: EXP SCOTT/TIGER
或者,(zhn)也可以通过输入跟有各种参数?EXP 命o来控?#8220;导出”
按照不同参数。要指定参数Q?zhn)可以使用关键?
格式: EXP KEYWORD=value ?KEYWORD=(value1,value2,...,valueN)
例程: EXP SCOTT/TIGER GRANTS=Y TABLES=(EMP,DEPT,MGR)
?TABLES=(T1: P1,T1: P2)Q如?T1 是分
USERID 必须是命令行中的W一个参数?/p>
关键?nbsp; 说明(默认) 关键?nbsp; 说明(默认)
--------------------------------------------------------------------------
USERID 用户?口o FULL 导出整个文g (N)
BUFFER 数据~冲区大?nbsp; OWNER 所有者用户名列表
FILE 输出文g (EXPDAT.DMP) TABLES 表名U列?br /> COMPRESS 导入C个区 (Y) RECORDLENGTH IO 记录的长?br /> GRANTS 导出权限 (Y) INCTYPE 增量导出cd
INDEXES 导出索引 (Y) RECORD 跟踪增量导出 (Y)
DIRECT 直接路径 (N) TRIGGERS 导出触发?(Y)
LOG 屏幕输出的日志文?nbsp; STATISTICS 分析对象 (ESTIMATE)
ROWS 导出数据?(Y) PARFILE 参数文g?br /> CONSISTENT 交叉表一致?nbsp; CONSTRAINTS 导出U束条g (Y)
FEEDBACK ?x 行显C?(0)
FILESIZE 每个转储文g的最大大?br /> FLASHBACK_SCN 用于回调会话快照?SCN
FLASHBACK_TIME 用来获得最接近于指定时间的 SCN 的时?br /> QUERY 用来导出表的子集的选择子句
RESUMABLE 遇到与空格有关的错误时挂?(N)
RESUMABLE_NAME 用来标识可恢复语句的文本字符?br /> RESUMABLE_TIMEOUT RESUMABLE 的等待时?br /> TTS_FULL_CHECK ?TTS 执行完全或部分相x检?br /> TABLESPACES 要导出的表空间列?br /> TRANSPORT_TABLESPACE 导出可传输的表空间元数据 (N)
TEMPLATE 调用 iAS 模式导出的模板名U?/p>
?使用CZ
3.1 数据导出Q?/p>
1 数据库SampleDB完全导出,用户名system 密码manager 导出到E:\SampleDB.dmp?/p>
exp system/manager@TestDB file=E:\sampleDB.dmp full=y
2 数据库中system用户与sys用户的表导出
exp system/manager@TestDB file=E:\sampleDB.dmp owner=(system,sys)
3 数据库中的?TableA,TableB 导出
exp system/manager@TestDB file=E:\sampleDB.dmp tables=(TableA,TableB)
4 数据库中的表tableA中的字段filed1 gؓ "王五" 的数据导?/p>
exp system/manager@TestDB file=E:\sampleDB.dmp tables=(tableA) query=' where filed1='王五'
如果惛_dmp文gq行压羃,可以在上面命令后?加上 compress=y 来实现?/p>
3.2 数据的导?/p>
1 备份数据库文g中的数据导入指定的数据库SampleDB ?如果 SampleDB 已存在该?则不再导?
imp system/manager@TEST file=E:\sampleDB.dmp full=y ignore=y
2 d:\daochu.dmp中的表table1 导入
imp system/manager@TEST file=E:\sampleDB.dmp tables=(table1)
3. 导入一个完整数据库
imp system/manager file=bible_db log=dible_db full=y ignore=y
4. 导入一个或一l指定用h属的全部表、烦引和其他对象
imp system/manager file=seapark log=seapark fromuser=seapark imp
system/manager file=seapark log=seapark fromuser=(seapark,amy,amyc,harold)
5. 一个用h属的数据导入另一个用?/p>
imp system/manager file=tank log=tank fromuser=seapark touser=seapark_copy
imp system/manager file=tank log=tank fromuser=(seapark,amy)
touser=(seapark1, amy1)
6. 导入一个表
imp system/manager file=tank log=tank fromuser=seapark TABLES=(a,b)
7. 从多个文件导?/p>
imp system/manager file=(paycheck_1,paycheck_2,paycheck_3,paycheck_4)
log=paycheck, filesize=1G full=y
8. 使用参数文g
imp system/manager parfile=bible_tables.par
bible_tables.par参数文gQ?br /> #Import the sample tables used for the Oracle8i Database Administrator's
Bible. fromuser=seapark touser=seapark_copy file=seapark log=seapark_import
参数文gCZ见附?/p>
9. 增量导入
imp system./manager inctype= RECTORE FULL=Y FILE=A
不少情况下要先将表彻底删除,然后导入?br />
?参数说明
4.1?i EXP常用选项
1、FULLQ这个用于导出整个数据库Q在ROWS=N一起用时Q可以导出整个数据库的结构。例如:
exp sys file=./db_str.dmp log=./db_str.log full=y rows=n compress=y direct=y
2、BUFFER和FEEDBACKQ在导出比较多的数据Ӟ我会考虑讄q两个参数。例如:
exp new file=yw97_2003.dmp log=yw97_2003_3.log feedback=10000 buffer=100000000 tables=WO4,OK_YT
3、FILL和LOGQ这两个参数分别指定备䆾的DMP名称和LOG名称Q包括文件名和目录,例子见上面?
需要说明的是,EXP可以直接备䆾到磁带中Q即使用FILE=/dev/rmt0(带讑֤?Q但是一般我们都不这么做Q原因有二:一、这样做的速度会慢很多Q二、现在一般都是用磁带库的,不徏议直接对带q行操作。至于没有用磁带库的朋友可以考虑和UNIX的TARl合使用?
如果你真想用EXP直接到磁带,你可以参考Metalink文章“EXPORTING TO TAPE ON UNIX SYSTEMS”Q文档号Q?0428.1Q,该文中有详细解释?
4、COMPRESS参数在导出的同时合q碎块,量把数据压~到initial的EXTENT里,默认是NQ一般徏议用。DIRECT参数告诉EXP直接d数据Q而不像传l的EXP那样Q用SELECT来读取表中的数据Q这样就减少了SQL语句处理q程。一般也使用。不q有些情况下DIRECT参数是无法用的?
5、如何用SYSDBA执行EXP/IMPQ?
q是一个很现实的问题,有时候我们需要用SYSDBA来执行EXP/IMPQ如q行传输表空间的EXP/IMPQ以及在9i下用SYS用户来执行EXP/IMPӞ都需要用SYSDBA才可。我们可以用下面方式连入EXP/IMPQ?
exp "'sys/sys as sysdba'" file=1.dmp tables=gototop.t rows=n
6、QUERY参数后面跟的是where条gQ值得注意的是Q整个where子句需要?"括v来,where子句的写法和SELECT中相同,如果是UNIXq_所??都需要用\u26469屏蔽它们的特D含义:
exp gototop/gototop file=1.dmp log=1.log tables=cyx.t query="where c1=20 and c2=gototop"
如果是windowsq_Q则使用下面的格式:
exp c/c@ncn file=c.dmp log=c.log tables=t query="""where id=1 and name='gototop'"""
4.2?i IMP常用选项
1、FROMUSER和TOUSERQ用它们实现将数据从一个SCHEMA中导入到另外一个SCHEMA中?
2、IGNORE、GRANTS和INDEXESQ其中IGNORE参数忽略表的存在,l箋导入Q这个对于需要调整表的存储参数时很有用,我们可以先根据实际情는合理的存储参数徏好表Q然后直接导入数据。而GRANTS和INDEXES则表C是否导入授权和索引Q如果想使用新的存储参数重徏索引Q或者ؓ了加快到入速度Q我们可以考虑INDEXES设ؓNQ而GRANTS一般都是Y?
另外一个EXP/IMP都有的参数是PARFILEQ它是用来定义EXP/IMP的参数文Ӟ也就是说Q上面的参数都可以写在一个参数文件中Q但我们一般很用?
4.4、Oracle9i EXP功能描述
Oracle9i EXP在原有的基础上新增了部分新的参数Q按功能主要分ؓ以下几个部分Q?
1、OBJECT_CONSISTENT - 用于讄EXP对象为只M保持对象的一致性。默认是N?
2、FLASHBACK_SCN和FLASHBACK_TIME - 用于支持FLASHBACK功能而新增?
3、RESUMABLE、RESUMABLE_NAME和RESUMABLE_TIMEOUT - 用于支持RESUMABLEI间分配而新增?
4、TTS_FULL_CHECK - 用于在传输表I间时用依赖性检查?
5、TEMPLATE - 用于支持iAS?
6、TABLESPACES - 讄表空间导出模式。个得对于一般用戯言Q这个才是新增参C最实用的一个,可以让用户在原来的FULL、OWNER、TABLES的基上多了一U选择Q得EXP更加灉|?
五、不同版本的EXP/IMP问题Q?
一般来_从低版本导入到高版本问题不大Q麻烦的是将高版本的数据导入C版本中,在Oracle9i之前Q不同版本Oracle之间的EXP/IMP可以通过下面的方法来解决Q?
1、在高版本数据库上运行底版本的catexp.sqlQ?
2、用低版本的EXP来导出高版本的数据;
3、用低版本的IMP数据库导入到底版本数据库中Q?
4、在高版本数据库上重新运行高版本的catexp.sql脚本?
但在9i中,上面的方法ƈ不能解决问题。如果直接用底版本EXP/IMP会出现如下错误:
EXP-00008: ORACLE error %lu encountered
ORA-00904: invalid column name
q已l是一个公布的BUGQ需要等到Oracle10.0才能解决QBUG号ؓ2261Q你可以到METALINK上去查看有关此BUG的详l信息?
BUG归BUGQ我们的工作q是要做Q在没有Oracle的支持之前,我们pp冟뀂在Oracle9i中执行下面的SQL重徏exu81rls视图卛_?
CREATE OR REPLACE view exu81rls
(objown,objnam,policy,polown,polsch,polfun,stmts,chkopt,enabled,spolicy)
AS select u.name, o.name, r.pname, r.pfschma, r.ppname, r.pfname,
decode(bitand(r.stmt_type,1), 0,'', 'SELECT,')
|| decode(bitand(r.stmt_type,2), 0,'', 'INSERT,')
|| decode(bitand(r.stmt_type,4), 0,'', 'UPDATE,')
|| decode(bitand(r.stmt_type,8), 0,'', 'DELETE,'),
r.check_opt, r.enable_flag,
DECODE(BITAND(r.stmt_type, 16), 0, 0, 1)
from user$ u, obj$ o, rls$ r
where u.user# = o.owner#
and r.obj# = o.obj#
and (uid = 0 or
uid = o.owner# or
exists ( select * from session_roles where role='SELECT_CATALOG_ROLE')
)
/
grant select on sys.exu81rls to public;
/
六、其他问?
本文只讨ZOracle8i?i中的EXP/IMP的一些情况,对于之前的版本,?.0.X中,除了QUERY参数不能用外Q其它差别不大。针Ҏ(gu)有QUERY的情况,我们可以先在数据库中使用查询条g建立临时中间表,然后使用EXP导出q个中间表即可。至于Oracle7因ؓ目前使用的h较少Qgototop不打在此做详细解释了,如果读者朋友有需求,你可以参考Metalink文Q?#8220;Overview of Export and Import in Oracle7”Q文号Q?1949.1Q。关于EXP/IMP的详l参C息你可以通过EXP/IMP HELP=Y来获得?
另外关于传输表空间的更多信息可以参考下面的Metelink文Q本文不再详q?
[NOTE:77523.1] Transportable Tablespaces -- An Example to setup and use.
[NOTE:100698.1] Perform tablespace point-in-time recovery using Transportable Tablespace.
在进行ƈ行EXP/IMP的时候,如果IMPq程建烦引的话不同时q行5个以上的IMPQ如果你惛_快速度Q可以在IMP的时候不建烦引,q样只要内存允许Q可以多跑几个,然后是SQL脚本创徏需要的索引?nbsp;
注意Q?br /> 操作者要有够的权限Q权限不够它会提C?br /> 数据库是否可以连? 可以用tnsping TestDB 来获得数据库 TestDB 能否q上?/p>
附录一Q?br /> l用户增加导入数据权限的操作
W一, 启动sql*puls
W二Q以system/manager登陆
W三Qcreate user 用户?IDENTIFIED BY 密码 Q如果已l创用户Q这步可以省略)
W四QGRANT CREATE USER,DROP USER,ALTER USER ,CREATE ANY VIEW ,
DROP ANY VIEW,EXP_FULL_DATABASE,IMP_FULL_DATABASE,
DBA,CONNECT,RESOURCE,CREATE SESSION TO 用户名字
W五, q行-cmd-q入dmp文g所在的目录,
imp userid=system/manager full=y file=*.dmp
或?imp userid=system/manager full=y file=filename.dmp
附录二:
Oracle 不允许直接改变表的拥有? 利用Export/Import可以辑ֈq一目的.
先徏立import9.par,
然后Q用时命o如下Qimp parfile=/filepath/import9.par
?import9.par 内容如下Q?br /> FROMUSER=TGPMS
TOUSER=TGPMS2 Q注Q把表的拥有者由FROMUSER改ؓTOUSERQFROMUSER和TOUSER的用户可以不同)
ROWS=Y
INDEXES=Y
GRANTS=Y
CONSTRAINTS=Y
BUFFER=409600
file==/backup/ctgpc_20030623.dmp
log==/backup/import_20030623.log
转蝲自:http://www.cnblogs.com/furenjun/archive/2008/05/20/oracleImpExp.html
开?-q行--cmd q入命o提示W?输入netstat -ano 卛_看到所有连接的PID 之后在Q务管理器中找到这个PID所对应的程序如果Q务管理器中没有PIDq一?可以在Q务管理器中?查看"-"选择?
l常Q我们在启动应用的时候发现系l需要的端口被别的程序占用,如何知道谁占有了我们需要的端口Q很多h都比较头|下面׃l一U非常简单的Ҏ(gu)Q希望对大家有用
假如我们需要确定谁占用了我们的9050端口
1、Windowsq_
在windows命o行窗口下执行Q?/p>
C:\>netstat -aon|findstr "9050"
TCP 127.0.0.1:9050 0.0.0.0:0 LISTENING 2016
看到了吗Q端口被q程号ؓ2016的进E占用,l箋执行下面命oQ?/p>
C:\>tasklist|findstr "2016"
tor.exe 2016 Console 0 16,064 K
很清楚吧Qtor占用了你的端口?br />http://www.tkk7.com/rabbit/archive/2008/03/12/185559.htmlQ{载)
l色版的客户端可能会出现对于中文支持的问题,q主要是因ؓ服务器端指定的字W集和客L所默认的字W集是不相同的导致的Q只要找到服务器端的字符集设|,然后客L的字W集讄与服务器端保持一致就好了。修改客L字符集设|的Ҏ(gu)有好几种Q可以修Ҏ(gu)册表Q也可以用环境变量的Ҏ(gu)解决。不q我q里介绍的客L是绿色版的,只是解压到某一个\径而已Q所以注册表的方法在q里不是很适用Q所以我写了一个启动脚本,在启动PL/SQL之前Q先Z个时环境变量nls_langQƈl变量赋|再启动Y件。(我曾l做q实验,通过建立pȝ环境变量的方法在q里是行不通的Q具体的原因我说不清?gt;<Q?/p>
我的脚本plsql.bat的内容如下:
set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
cd "c:\Program Files\PLSQL Developer"
PLSQLDev.exe
其中W二行进入的路径是PL/SQL Developer安装到的路径?/p>
我这里的实际情况是服务器端的字符集设|ؓSIMPLIFIED CHINESE_CHINA.ZHS16GBKQ所以我这个Dlnls_lang。通过q行plsql.bat脚本可以正常的讉K服务器数据库了?br />
//创徏用户testQ密码test
create user test identified by "test";
//?/font>test用户创徏pȝҎ(gu)q且可以?/span>test为别的用h予权?/span>
Grant execute any procedure to test with admin option
2008-07-23 08:46:22| 分类Q?/span> My Utils | 标签Q?/span> |字号?/span>?/span>?/span> 订阅
package com.sun.util;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.sql.Timestamp;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 字符串操作通用c?br /> *
* @author sunjun
* @version v5.0
*/
public class StringUtil {
// 字符串常量枚?br /> public static enum REGEX_ENUM {
EMAIL("^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"), CHINESE_CHARACTER(
"[\\u4E00-\\u9FA5]+");
private String value;
private REGEX_ENUM(String value) {
this.value = value;
}
public String toString() {
return this.value;
}
};
/**
* 查字W串str是否匚w正则表达式regex
*
* @param regex
* @param str
* @return
*/
public static boolean matcherRegex(String regex, String str) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
return matcher.matches();
}
/**
* 是否为汉?br /> *
* @param ch
* @return
*/
public static boolean isChineseCharacter(char ch) {
return matcherRegex(REGEX_ENUM.CHINESE_CHARACTER.toString(), String
.valueOf(ch));
}
/**
* 按字节截取字W串
*
* @param str
* 要截取的字符?br /> * @param byteLength
* 长度
* @return l果字符?br /> */
public static String subString(String str, int byteLength) {
if (isBlank(str))
return "";
if (str.getBytes().length <= byteLength)
return str;
if (str.length() >= byteLength)
str = str.substring(0, byteLength);
int readLen = 0;
String c = null;
StringBuffer sb = new StringBuffer("");
for (int i = 0; i < str.length(); i++) {
c = String.valueOf(str.charAt(i));
readLen += c.getBytes().length;
if (readLen > byteLength)
return sb.toString();
sb.append(c);
}
return sb.toString();
}
/**
* 查字W串长度是否在指定长度范围内(minLength<=str.length<=maxLength)
*
* @param str
* 要检查的字符?br /> * @param minLength
* 最长?br /> * @param maxLength
* 最大长?br /> * @return boolean 字符串长度在指定长度范围内返回trueQ否则返回false
*/
public static boolean checkLength(String str, int minLength, int maxLength) {
if (isBlank(str))
return false;
int len = str.length();
if (minLength == 0)
return len <= maxLength;
else if (maxLength == 0)
return len >= minLength;
else
return (len >= minLength && len <= maxLength);
}
/**
* 按UTF-8~码来解码字W串
*
* @param str
* 要解码的字符?br /> * @return String 解码str后字W串
*/
public static String decodeString(String str) {
return decodeString(str, "UTF-8");
}
/**
* 按指定编码来解码字符?br /> *
* @param str
* @param encoding
* @return
*/
public static String decodeString(String str, String encoding) {
if (isBlank(str))
return "";
try {
return URLDecoder.decode(str.trim(), encoding);
} catch (UnsupportedEncodingException e) {
}
return "";
}
/**
* 按指定编码来解码字符?br /> *
* @param str
* @param encoding
* @return
*/
public static String decodeURI(String str) {
if (isBlank(str))
return "";
try {
return new String(str.getBytes("ISO8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
}
return "";
}
/**
* 按UTF-8~码来编码字W串
*
* @param str
* 要编码的字符?br /> * @return String ~码str后字W串
*/
public static String encodeString(String str) {
return encodeString(str, "UTF-8");
}
/**
* 按UTF-8~码来编码字W串
*
* @param str
* 要编码的字符?br /> * @return String ~码str后字W串
*/
public static String encodeString(String str, String encoding) {
if (isBlank(str))
return "";
try {
return URLEncoder.encode(str.trim(), encoding);
} catch (UnsupportedEncodingException e) {
}
return "";
}
/**
* Ҏ(gu)旉得到唯一字符?br /> *
* @return
*/
public static String getOnlyString() {
return String.valueOf(System.currentTimeMillis());
}
/**
* 查对象obj是否为空
*
* @param str
* 要检查的字符?br /> * @return boolean str为空q回trueQ否则返回false
*/
public static boolean isBlank(Object obj) {
if (obj == null)
return true;
if (obj instanceof String && obj.toString().trim().length() == 0)
return true;
return false;
}
/**
* 查字W串str是否为整?br /> *
* @param str
* 要检查的字符?br /> * @return boolean str为整型返回trueQ否则返回false
*/
public static boolean isInteger(String str) {
if (isBlank(str))
return false;
try {
Integer.parseInt(str.trim());
return true;
} catch (Exception e) {
}
return false;
}
/**
* 查字W串str是否为长整型
*
* @param str
* 要检查的字符?br /> * @return boolean str为长整型q回trueQ否则返回false
*/
public static boolean isLong(String str) {
if (isBlank(str))
return false;
try {
Long.parseLong(str.trim());
return true;
} catch (Exception e) {
}
return false;
}
/**
* 查字W串str是否为布?yu)?br /> *
* @param str
* 要检查的字符?br /> * @return boolean str为布?yu)型q回trueQ否则返回false
*/
public static boolean isBoolean(String str) {
if (isBlank(str))
return false;
try {
Boolean.parseBoolean(str.trim());
return true;
} catch (Exception e) {
}
return false;
}
/**
* 查字W串str是否为doublecd
*
* @param str
* @return
*/
public static boolean isDouble(String str) {
if (isBlank(str))
return false;
try {
Double.parseDouble(str.trim());
return true;
} catch (Exception e) {
}
return false;
}
/**
* 查字W串str是否为时间型
*
* @param str
* 要检查的字符?br /> * @return boolean str为时间型q回trueQ否则返回false
*/
public static boolean isDate(String str) {
if (isBlank(str))
return false;
try {
java.sql.Date sqlDate = java.sql.Date.valueOf(str.trim());
return true;
} catch (Exception e) {
}
return false;
}
/**
* 查对象数lstrings的每个元素是否ؓI?br /> *
* @param objs
* 要检查的对象数组
* @return boolean objs数组元素为空q回trueQ否则返回false
*/
public static boolean isBlanks(Object... objs) {
for (Object obj : objs) {
if (StringUtil.isBlank(obj))
return true;
}
return false;
}
/**
* 查字W串数组str是否为长整型数组
*
* @param str
* 要检查的字符?br /> * @return boolean str为长整型数组q回trueQ否则返回false
*/
public static boolean isLongs(String str[]) {
for (int i = 0; i < str.length; i++) {
if (!isLong(str[i]))
return false;
}
return true;
}
/**
* 查字W串数组str是否为整型数l?br /> *
* @param str
* 要检查的字符?br /> * @return boolean str为整型数l返回trueQ否则返回false
*/
public static boolean isIntegers(String str[]) {
for (int i = 0; i < str.length; i++)
if (!isInteger(str[i]))
return false;
return true;
}
/**
* 查字W串数组str是否为布?yu)型数?br /> *
* @param str
* 要检查的字符?br /> * @return boolean str为布?yu)型数组q回trueQ否则返回false
*/
public static boolean isBooleans(String str[]) {
for (int i = 0; i < str.length; i++)
if (!isBoolean(str[i]))
return false;
return true;
}
/**
* 查字W串str是否为时?br /> *
* @param str
* 要检查的字符?br /> * @return str为时间型q回trueQ否则返回false
*/
public static boolean isTimestamp(String str) {
if (isBlank(str))
return false;
try {
java.sql.Date d = java.sql.Date.valueOf(str.trim());
return true;
} catch (Exception ex) {
}
return false;
}
/**
* 查字W串str是否?yyyy-MM-dd HH:mm:ss)模式的时?br /> *
* @param str
* 要检查的字符?br /> * @return str为时间型q回trueQ否则返回false
*/
public static boolean isFullTimestamp(String str) {
if (isBlank(str))
return false;
try {
SimpleDateFormat format = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
Date date = format.parse(str.trim());
return date != null;
} catch (Exception e) {
}
return false;
}
/**
* 字W数l{换ؓ长整型数l?br /> *
* @param str
* 字符数组
* @return Long[] 长整型数l?br /> */
public static Long[] stringsToLongs(String str[]) {
Long lon[] = new Long[str.length];
for (int i = 0; i < lon.length; i++)
lon[i] = new Long(str[i]);
return lon;
}
/**
* 字W数l{换ؓ整型数组
*
* @param str
* 字符数组
* @return Integer[] 整型数组
*/
public static Integer[] stringsToIntegers(String str[]) {
Integer array[] = new Integer[str.length];
for (int i = 0; i < array.length; i++)
array[i] = new Integer(str[i]);
return array;
}
/**
* 字W数l{换ؓ布尔型数l?br /> *
* @param str
* 字符数组
* @return Boolean[] 布尔型数l?br /> */
public static Boolean[] stringsToBooleans(String str[]) {
Boolean array[] = new Boolean[str.length];
for (int i = 0; i < array.length; i++)
array[i] = new Boolean(str[i]);
return array;
}
/**
* 字W数l{换ؓ点型数l?br /> *
* @param str
* 字符数组
* @return double[] 点型数l?br /> */
public static double[] stringsToDoubles(String str[]) {
double array[] = new double[str.length];
for (int i = 0; i < array.length; i++)
array[i] = Double.parseDouble(str[i]);
return array;
}
/**
* Ҏ(gu)指定旉和格式字W串得到旉格式字符?br /> *
* @param d
* 旉
* @param pattern
* 格式字符?br /> * @return String 旉格式字符?br /> */
public static String formatDate(Date d, String pattern) {
if (isBlank(d))
return "";
SimpleDateFormat format = new SimpleDateFormat(
isBlank(pattern) ? "yyyy-MM-dd HH-mm-ss" : pattern);
return format.format(d);
}
/**
* Ҏ(gu)旉字符串得到时?yyyy-MM-dd)
*
* @param str
* 旉字符?br /> * @return Timestamp 旉
*/
public static Timestamp getTimestamp(String str) {
try {
Date d = java.sql.Date.valueOf(str.trim());
return new Timestamp(d.getTime());
} catch (Exception ex) {
}
return null;
}
/**
* Ҏ(gu)旉字符串得?yyyy-MM-dd HH-mm-ss)格式旉
*
* @param str
* 旉字符?br /> * @return Timestamp 旉
*/
public static Timestamp getFullTimestamp(String str) {
try {
SimpleDateFormat format = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
Date date = format.parse(str.trim());
return new Timestamp(date.getTime());
} catch (Exception ex) {
}
return null;
}
/**
* 得到数字格式化后的字W串
*
* @param number
* Numbercd
* @param minFractionDigits
* 数最位?br /> * @param maxFractionDigits
* 数最大位?br /> * @return String 格式化后的字W串
*/
public static String formatNumber(Number number, int minFractionDigits,
int maxFractionDigits) {
NumberFormat format = NumberFormat.getInstance();
format.setMinimumFractionDigits(minFractionDigits);
format.setMaximumFractionDigits(maxFractionDigits);
return format.format(number);
}
/**
* 字符串高?lt;br>
* 解决了高亮前~或高亮后~在要高亮昄的字W串数组在存在时的问题,Ҏ(gu)本算法可解决JS高亮昄时相同的问题
*
* @param text
* 内容
* @param replaceStrs
* 要高亮显C的字符串数l?br /> * @param beginStr
* 高亮前缀Q如<font color=red>
* @param endStr
* 高亮后缀Q如</font>
* @return
*/
public static String heightLight(String text, String[] replaceStrs,
String beginStr, String endStr) {
if (text.length() == 0)
return text;
StringBuilder str = new StringBuilder();
for (int i = 0; i < replaceStrs.length; i++) {
String replaceStr = replaceStrs[i];
int index = text.indexOf(replaceStr);
if (index >= 0) {
String afterStr = null;
if (index > 0) {
String beforeStr = text.substring(0, index);
afterStr = text.substring(index + replaceStr.length());
str.append(heightLight(beforeStr, replaceStrs, beginStr,
endStr));
} else
afterStr = text.substring(replaceStr.length());
str.append(beginStr).append(replaceStr).append(endStr);
str
.append(heightLight(afterStr, replaceStrs, beginStr,
endStr));
break;
}
}
if (str.length() == 0)
return text;
return str.toString();
}
/**
* 替换指定的字W串数组Z个字W串<br>
* 速度比String.replaceAll?倍左叻I比apache-common StringUtils.replace?倍左?br /> *
* @param text
* @param replaceStrs
* @param newStr
* @return
*/
public static String replaceAll(String text, String[] replaceStrs,
String newStr) {
if (text.length() == 0)
return text;
StringBuilder str = new StringBuilder();
for (int i = 0; i < replaceStrs.length; i++) {
String replaceStr = replaceStrs[i];
int index = text.indexOf(replaceStr);
if (index >= 0) {
String afterStr = null;
if (index > 0) {
String beforeStr = text.substring(0, index);
afterStr = text.substring(index + replaceStr.length());
str.append(replaceAll(beforeStr, replaceStrs, newStr));
} else
afterStr = text.substring(replaceStr.length());
str.append(newStr);
str.append(replaceAll(afterStr, replaceStrs, newStr));
break;
}
}
if (str.length() == 0)
return text;
return str.toString();
}
/**
* 替换指定的字W串Z个字W串<br>
* 速度比String.replaceAll?倍左叻I比apache-common StringUtils.replace?倍左?br /> *
* @param text
* @param replaceStr
* @param newStr
* @return
*/
public static String replaceAll(String text, String replaceStr,
String newStr) {
if (text.length() == 0)
return text;
StringBuilder str = new StringBuilder();
int index = text.indexOf(replaceStr);
if (index >= 0) {
String afterStr = null;
if (index > 0) {
String beforeStr = text.substring(0, index);
afterStr = text.substring(index + replaceStr.length());
str.append(replaceAll(beforeStr, replaceStr, newStr));
} else
afterStr = text.substring(replaceStr.length());
str.append(newStr);
str.append(replaceAll(afterStr, replaceStr, newStr));
}
if (str.length() == 0)
return text;
return str.toString();
}
/**
* 替换指定的字W串数组Z个字W串数组<br>
* 速度比String.replaceAll?倍左叻I比apache-common StringUtils.replace?倍左?br /> *
* @param text
* @param replaceStrs
* @param newStrs
* @return
*/
public static String replaceAllArray(String text, String[] replaceStrs,
String[] newStrs) {
if (text.length() == 0)
return text;
StringBuilder str = new StringBuilder();
for (int i = 0; i < replaceStrs.length; i++) {
String replaceStr = replaceStrs[i];
int index = text.indexOf(replaceStr);
if (index >= 0) {
String afterStr = null;
if (index > 0) {
String beforeStr = text.substring(0, index);
afterStr = text.substring(index + replaceStr.length());
str
.append(replaceAllArray(beforeStr, replaceStrs,
newStrs));
} else
afterStr = text.substring(replaceStr.length());
str.append(newStrs[i]);
str.append(replaceAllArray(afterStr, replaceStrs, newStrs));
break;
}
}
if (str.length() == 0)
return text;
return str.toString();
}
/**
* 解码HTML(?amp;gt;,<,",&转换?gt;,<,",& )
*
* @param html
* @return
*/
public static String decodeHTML(String html) {
if (isBlank(html))
return "";
String[] replaceStr = { "&", "<", ">", """ };
String[] newStr = { "&", "<", ">", "\"" };
return replaceAllArray(html, replaceStr, newStr);
}
/**
* ~码HTML(?gt;,<,",&
* 转换?amp;gt;,<,",&)(高效率,来自FreeMarker模板源码Q比replaceAll速度快很?
*
* @param html
* @return
*/
public static String encodeHTML(String html) {
if (isBlank(html))
return "";
int ln = html.length();
char c;
StringBuffer b;
for (int i = 0; i < ln; i++) {
c = html.charAt(i);
if (c == '<' || c == '>' || c == '&' || c == '"') {
b = new StringBuffer(html.substring(0, i));
switch (c) {
case '<':
b.append("<");
break;
case '>':
b.append(">");
break;
case '&':
b.append("&");
break;
case '"':
b.append(""");
break;
}
i++;
int next = i;
while (i < ln) {
c = html.charAt(i);
if (c == '<' || c == '>' || c == '&' || c == '"') {
b.append(html.substring(next, i));
switch (c) {
case '<':
b.append("<");
break;
case '>':
b.append(">");
break;
case '&':
b.append("&");
break;
case '"':
b.append(""");
break;
}
next = i + 1;
}
i++;
}
if (next < ln)
b.append(html.substring(next));
html = b.toString();
break;
}
}
return html;
}
/**
* MD5加密
*
* @param plainText
* 要加密的字符?br /> * @return 加密后的字符?br /> */
public static String Md5(String plainText) {
StringBuffer buf = new StringBuffer("");
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
int i = 0;
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
} catch (Exception e) {
e.printStackTrace();
}
return buf.toString();
}
/**
* MD5加密(32)
*
* @param plainText
* 要加密的字符?br /> * @return
*/
public final static String MD5(String plainText) {
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
try {
byte[] strTemp = plainText.getBytes();
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(strTemp);
byte[] md = mdTemp.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
}
return "";
}
}
我在Cernet做过拨号接入q_的搭建,而后在Yahoo3721负蝲搜烦引擎前端q_开发,又在猫扑处理q大型社区猫扑大杂烩的架构升U等工作Q同时自己接触和开发过不少大中型网站的模块Q因此在大型|站应对高负载和q发的解x案上有一些积累和l验Q可以和大家一h讨一下?/font>
大型|站Q比如门L站。在面对大量用户讉K、高q发h斚wQ基本的解决Ҏ(gu)集中在这样几个环节:使用高性能的服务器、高性能的数据库、高效率的编E语a、还有高性能的Web容器。但是除了这几个斚wQ还没法Ҏ(gu)解决大型|站面的高负蝲和高q发问题?/font> 上面提供的几个解x\在一定程度上也意味着更大的投入,q且q样的解x\具备瓉Q没有很好的扩展性,下面我从低成本、高性能和高扩张性的角度来说说我的一些经验?/font> 1、HTML静态化 除了门户和信息发布类型的|站Q对于交互性要求很高的Ccd|站来说Q尽可能的静态化也是提高性能的必要手D,社区内的帖子、文章进行实时的静态化Q有更新的时候再重新静态化也是大量使用的策略,像Mop的大杂烩是使用了这L{略Q网易社区等也是如此?/font> 同时Qhtml静态化也是某些~存{略使用的手D,对于pȝ中频J用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实玎ͼ比如论坛中论坛的公用讄信息Q这些信息目前的L论坛都可以进行后台管理ƈ且存储再数据库中Q这些信息其实大量被前台E序调用Q但是更新频率很,可以考虑这部分内容q行后台更新的时候进行静态化Q这样避免了大量的数据库讉Kh?/font> 2、图片服务器分离 3、数据库集群和库表散?br />
大型|站都有复杂的应用,q些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓉很快p昄出来Q这时一台数据库很快无法满_用,于是我们需要用数据库集群或者库表散列?/font> 在数据库集群斚wQ很多数据库都有自己的解x案,Oracle、Sybase{都有很好的Ҏ(gu)Q常用的MySQL提供的Master/Slave也是cM的方案,(zhn)用了什么样的DBQ就参考相应的解决Ҏ(gu)来实施即可?/font> 上面提到的数据库集群׃在架构、成本、扩张性方面都会受到所采用DBcd的限Ӟ于是我们需要从应用E序的角度来考虑改善pȝ架构Q库表散列是常用q且最有效的解x案。我们在应用E序中安装业务和应用或者功能模块将数据库进行分,不同的模块对应不同的数据库或者表Q再按照一定的{略Ҏ(gu)个页面或者功能进行更的数据库散列,比如用户表,按照用户IDq行表散列,q样p够低成本的提升系l的性能q且有很好的扩展性。sohu的论坛就是采用了q样的架构,论坛的用户、设|、帖子等信息q行数据库分,然后对帖子、用h照板块和IDq行散列数据库和表,最l可以在配置文g中进行简单的配置便能让系l随时增加一C成本的数据库q来补充pȝ性能?/font> 4、缓?br />
~存一词搞技术的都接触过Q很多地方用到缓存。网站架构和|站开发中的缓存也是非帔R要。这里先讲述最基本的两U缓存。高U和分布式的~存在后面讲q?br />
架构斚w的缓存,对Apache比较熟?zhn)的h都能知道Apache提供了自q~存模块Q也可以使用外加的Squid模块q行~存Q这两种方式均可以有效的提高Apache的访问响应能力?br />
|站E序开发方面的~存Q?a onclick="javascript:tagshow(event, 'Linux');" href="javascript:;" target="_self">Linux上提供的Memory Cache是常用的~存接口Q可以在web开发中使用Q比如用Java开发的时候就可以调用MemoryCache对一些数据进行缓存和通讯׃nQ一些大型社Z用了q样的架构。另外,在用web语言开发的时候,各种语言基本都有自己的缓存模块和Ҏ(gu)Q?a onclick="javascript:tagshow(event, 'PHP');" href="javascript:;" target="_self">PHP有Pear的Cache模块QJava更多了Q?net不是很熟(zhn),怿也肯定有?/font> 5、镜?br />
镜像是大型网站常采用的提高性能和数据安全性的方式Q镜像的技术可以解决不同网l接入商和地域带来的用户讉K速度差异Q比如ChinaNet和EduNet之间的差异就促了很多网站在教育|内搭徏镜像站点Q数据进行定时更新或者实时更新。在镜像的细节技术方面,q里不阐q太深,有很多专业的现成的解x构和产品可选。也有廉L通过软g实现的思\Q比如Linux上的rsync{工兗?/font> 6、负载均?br />
负蝲均衡是大型|站解决高负药问和大量q发h采用的终极解军_法?br />
负蝲均衡技术发展了多年Q有很多专业的服务提供商和品可以选择Q我个h接触q一些解x法,其中有两个架构可以给大家做参考?br />
g四层交换 软g四层交换 一个典型的使用负蝲均衡的策略就是,在Y件或者硬件四层交换的基础上搭建squid集群Q这U思\在很多大型网站包括搜索引擎上被采用,q样的架构低成本、高性能q有很强的扩张性,随时往架构里面增减节点都非常容易。这L架构我准备空了专门详l整理一下和大家探讨?/font> 对于大型|站来说Q前面提到的每个Ҏ(gu)可能都会被同时用到Q我q里介绍得比较浅显,具体实现q程中很多细节还需要大家慢慢熟(zhn)和体会Q有时一个很的squid参数或者apache参数讄Q对于系l性能的媄响就会很大,希望大家一赯论,辑ֈ抛砖引玉之效?/font>
一个小型的|站Q比如个人网站,可以使用最单的html静态页面就实现了,配合一些图片达到美化效果,所有的面均存攑֜一个目录下Q这L|站对系l架构、性能的要求都很简单,随着互联|业务的不断丰富Q网站相关的技?/strong>l过q些q的发展Q已l细分到很细的方斚w面,其对于大型|站来说Q所采用的技术更是涉及面非常q,从硬件到软g、编E语a?a onclick="javascript:tagshow(event, '%CA%FD%BE%DD%BF%E2');" href="javascript:;" target="_self">数据?/strong>、WebServer、防火墙{各个领域都有了很高的要求,已经不是原来单的html静态网站所能比拟的?/font>
其实大家都知道,效率最高、消耗最的是U静态化的html面Q所以我们尽可能使我们的|站上的面采用静态页面来实现Q这个最单的Ҏ(gu)其实也是最有效的方法。但是对于大量内容ƈ且频J更新的|站Q我们无法全部手动去挨个实现Q于是出C我们常见的信息发布系lCMSQ像我们常访问的各个门户站点的新闻频道,甚至他们的其他频道,都是通过信息发布pȝ来管理和实现的,信息发布pȝ可以实现最单的信息录入自动生成静态页面,q能具备频道理、权限管理、自动抓取等功能Q对于一个大型网站来_拥有一套高效、可理的CMS是必不可的?/font>
大家知道Q对于Web服务器来_不管?a onclick="javascript:tagshow(event, 'Apache');" href="javascript:;" target="_self">Apache、IISq是其他容器Q图片是最消耗资源的Q于是我们有必要图片与面q行分离Q这是基本上大型|站都会采用的策略,他们都有独立的图片服务器Q甚臛_多台囄服务器。这L架构可以降低提供面讉Kh的服务器pȝ压力Qƈ且可以保证系l不会因为图片问题而崩溃,在应用服务器和图片服务器上,可以q行不同的配|优化,比如apache在配|ContentType的时候可以尽量少支持Q尽可能的LoadModuleQ保证更高的pȝ消耗和执行效率?/font>
W四层交换用第三层和第四层信息包的报头信息Q根据应用区间识别业务流Q将整个区间D늚业务分配到合适的应用服务器进行处理。 W四层交换功能就象是虚IPQ指向物理服务器。它传输的业务服从的协议多种多样Q有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基上,需要复杂的载量q法。在IP世界Q业务类型由l端TCP或UDP端口地址来决定,在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同军_?br />
在硬件四层交换品领域,有一些知名的产品可以选择Q比如Alteon、F5{,q些产品很昂贵,但是物有所|能够提供非常优秀的性能和很灉|的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon搞定了?/font>
大家知道了硬件四层交换机的原理后Q基于OSI模型来实现的软g四层交换也就应运而生Q这L解决Ҏ(gu)实现的原理一_不过性能E差。但是满一定量的压力还是游刃有余的Q有软g实现方式其实更灵z,处理能力完全看你配置的熟(zhn)能力?br />
软g四层交换我们可以使用Linux上常用的LVS来解冻ILVS是Linux Virtual ServerQ他提供了基于心跳线heartbeat的实时灾隑ֺ对解x案,提高pȝ的鲁性,同时可供了灵zȝ虚拟VIP配置和管理功能,可以同时满多种应用需求,q对于分布式的系l来说必不可?/font>