Wednesday, October 14, 2009

小自行车购买

小自行车购买:

小自行车品牌:
1. 好孩子
2. 新中华

我儿子现在2岁半,身高1米,骑12寸的车子正好,应该再骑1年没问题.
本来想直接买14寸的,但是当时他骑着够不着就还是选12寸的了.

不买12寸主要是发现12寸的轮子和14寸的不一样,12寸的轮子是塑料、实心的,质量一般般,车子也是塑料的,14寸以上的就是电喷的了,轮子是充气的,和大人的车子一样。

不过最好到二岁后再买,因为现在就算买了,他也不会骑. 过了二岁后他的小腿肌肉就有力道踩下去了啊. 

我家是12寸的,2岁左右骑差不多,现在骑小了,但我觉得从长远来看,还是14寸好点,因为宝宝会骑车的时候14寸也够的着了  

2岁小孩可以买12寸的自行车,最长可以用到4岁多

我们20个月的时候就买的14寸的,一开始不能骑满轮,但很快,过两个月就可以了。
建议买14寸的,我们骑到现在,但是当时买12寸的现在都换第二辆了,12村用不了多久  


我家去年买的14寸的,当时骑有点大,只踩半圈,现在骑刚好了,宝宝长起来很快的,估计还能玩个两年。

以前听说过最好3岁以后让宝宝骑自行车,太早对他的腿发育不好 

儿童自行车尺寸参照(只供参考):
12寸----适合1.5-4岁儿童
14寸----适合3-6岁儿童
16寸----适合4-8岁儿童


Thursday, May 14, 2009

Oracle中的异常处理

异常与Oracle错误的关联可通过EXCEPTION_INIT编译器指令实现。语法:

  PRAGMA EXCEPTION_INIT(exception_name , oracle_error_number);

(在PL/SQL中使用编译器指令的语法都是以pragma打头,且只能在代码的声明部分使用。可参照自治事务的用法)

1>被关联的异常只能是用户自定义的异常,不能是预定义的异常名。当然用户可定义一个与预定义同名的异常(但不提倡这样做);

2>一个错误可以关联多个异常,关联同一个错误的异常不能在异常处理部分同时出现;

5、SQLCODE返回的是当前的错误号。

  SQLERRM返回的是当前的错误信息文本。

  如果错误(异常)是通过RAISE显式引发的用户自定义异常,且该异常没有通过EXCEPTION_INIT语句与错误代号进行关联,则SQLCODE返回值为1,而SQLERRM返回的信息是:ORA-06510: PL/SQL: unhandled user-defined exception。

  也可以这样理解:用户自定义的异常默认与错误代号为1的错误进行关联,而错误代号为1的错误信息文本是:ORA-06510: PL/SQL: unhandled user-defined exception。

  两个相关例子:

SQL> DECLARE

2  e_test EXCEPTION;

3 BEGIN

4   RAISE e_test;

5 EXCEPTION WHEN OTHERS THEN

6   DBMS_OUTPUT.PUT_LINE(SQLCODE);

7  DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK);

8 END;

9 /

1

ORA-06510: PL/SQL: unhandled user-defined exception

PL/SQL过程已成功完成。

SQL> DECLARE

2  e_test EXCEPTION;

3  PRAGMA EXCEPTION_INIT(e_test ,-20001);

4 BEGIN

5   RAISE_APPLICATION_ERROR(-20001,'This is a test.');

6 EXCEPTION

7   WHEN e_test THEN

8     DBMS_OUTPUT.PUT_LINE(SQLCODE);

9  DBMS_OUTPUT.PUT_LINE(SQLERRM);

10   WHEN OTHERS THEN

11     NULL;

12 END;

13 /

-20001

ORA-20001: This is a test.

PL/SQL过程已成功完成。

6、使用RAISE_APPLICATION_ERROR方法引发异常并创建错误代号与错误消息。语法:

  RAISE_APPLICATION_ERROR(error_number,error_message[,keep_errors]);

  其中,error_number是在-20000到-20999之间的一个值。error_message是与该错误关联的文本.keep_errors的值为TRUE或FALSE,如为TRUE,新产生的错误就会追加到已引发错误的列表中(如果已经有错误的话)。如为FALSE(FALSE也是默认值),新发生的错误就会替换当前的错误列表。

SQL> BEGIN

2   BEGIN

3     BEGIN

4    RAISE_APPLICATION_ERROR(-20001,'This is a test.',TRUE);

5     EXCEPTION WHEN OTHERS THEN

6    RAISE_APPLICATION_ERROR(-20002,'I raised by 20001.',TRUE);

7     END;

8   EXCEPTION  WHEN OTHERS THEN

9     RAISE_APPLICATION_ERROR(-20003,'I raised by 20002.',TRUE);

10   END;

11 EXCEPTION WHEN OTHERS THEN

12     DBMS_OUTPUT.PUT_LINE(SQLCODE);

13  DBMS_OUTPUT.PUT_LINE(SQLERRM);

14 END;

15 /

-20003

ORA-20003: I raised by 20002.

ORA-20002: I raised by 20001.

ORA-20001: This is a test.

PL/SQL过程已成功完成。

7、异常的传播

  1、声明部分和异常部分引发的异常都会立即传播到该封装块。

  2、使用不带任何参数的RAISE语句,再次引发当前异常。该语句只能在异常处理部分出现,通常是为了异常能从已被捕获的处理块中再次传出。

8、异常与事务

  引发异常不会结束某个事务,就像终止某个代码块不会终止一个事务一样。

  但是如果顶层的代码块以一个未处理异常而终止,该异常就会传播到调用环境,代码中产生的相应事务就会立即由服务器进行回滚。

9、异常可当作控制语句使用(如跳过某段程序的执行、终止整个程序的执行等)。

Tuesday, May 12, 2009

PL/SQL debug – 1

Error Message while executing the script:

Error code:-932Script error message:ORA-00932: inconsistent datatypes: expected - got -

possible solution:

1. check the parmaters type match the column type in select clause

2. check the result table type definition match the source table column type

3. copy part of the script to another editor window, try to run to get more determined error messages

Monday, May 11, 2009

select into

case 1. select into 语法
 
现在有表
tablea 
 cola int ,
 colb varchar(20)
)
 
要把tablea中满足条件(cola <100)的记录生成新的表tableb。
 
在ms sqlserver 可以直接用select into语法:
select * into tableb 
where cola <>
 
在oracle中语法如下:
create table tableb 
as 
  select * from tablea 
    where cola <100)

Rank()使用

找出column1对应多个column_2的查询:
---------------------------------------------
select * from (select rank() over(partition by order by    desc) rk, table_name.* 
from table_name) T 
where T.rk>=2;

Tuesday, April 28, 2009

ways to invoke procedure in Oracle

/*
Sample procedure:
create or replace procedure runbyparmeters (isal in emp.sal%type,
sname out varchar,sjob in out varchar)
2 as icount number;
3 begin
4 select count(*) into icount from emp where sal>isal and job=sjob;
5 if icount=1 then
6 ....
9 else
10 ....
12 end if;
13 exception
14 when too_many_rows then
15 DBMS_OUTPUT.PUT_LINE('返回值多于1行');
16 when others then
17 DBMS_OUTPUT.PUT_LINE('在RUNBYPARMETERS过程中出错!');
18 end;
*/
--call procedure in oracle
--1. first way
declare
realsal emp.sal%type;
realname varchar(40);
realjob varchar(40);
begin
realsal:=1100;
realname:='';
realjob:='CLERK';
runbyparmeters(realsal,realname,realjob); --必须按顺序
DBMS_OUTPUT.PUT_LINE(REALNAME||' '||REALJOB);
END;
--2. second way
declare
realsal emp.sal%type;
realname varchar(40);
realjob varchar(40);
begin
realsal:=1100;
realname:='';
realjob:='CLERK';
runbyparmeters(sname=>realname,isal=>realsal,sjob=>realjob); --指定值对应变量顺序可变
DBMS_OUTPUT.PUT_LINE(REALNAME||' '||REALJOB);
END;

Oracle数据字典表-1

权限安全的数据字典表有:

ALL_TAB_PRIVS

ALL_TAB_PRIVS_MADE

ALL_TAB_PRIVS_RECD

DBA_SYS_PRIVS

DBA_ROLES

DBA_ROLE_PRIVS

ROLE_ROLE_PRIVS

ROLE_SYS_PRIVS

ROLE_TAB_PRIVS

SESSION_PRIVS

SESSION_ROLES

USER_SYS_PRIVS

USER_TAB_PRIV

--check the number of index and type
select index_name,index_type,table_name from user_indexes where table_name=upper('&table_name');

--check the indexed column
select * from user_ind_columns where index_name=upper('&index_name');

-check the size of index
select sum(bytes)/(1024*1024) as "size(M)" from user_segments
where segment_name=upper('&index_name');

Wednesday, April 22, 2009

[oracle] to_date() 与 to_char() 日期和字符串转换

to_date("要转换的字符串","转换的格式") 两个参数的格式必须匹配,否则会报错。

即按照第二个参数的格式解释第一个参数。

to_char(日期,"转换格式" ) 即把给定的日期按照“转换格式”转换。

转换的格式:

表示year的:y 表示年的最后一位 yy 表示年的最后2位 yyy 表示年的最后3位 yyyy 用4位数表示年

表示month的:mm 用2位数字表示月;mon 用简写形式 比如11月或者nov ;month 用全称 比如11月或者november

表示day的:dd 表示当月第几天;ddd表示当年第几天;dy 当周第几天 简写 比如星期五或者fri;day当周第几天 全写

比如星期五或者friday。

表示hour的:hh 2位数表示小时 12进制; hh24 2位数表示小时 24小时

表示minute的:mi 2位数表示分钟

表示second的:ss 2位数表示秒 60进制

表示季度的:q 一位数 表示季度 (1-4)

另外还有ww 用来表示当年第几周 w用来表示当月第几周。

24小时制下的时间范围:00:00:00-23:59:59

12小时制下的时间范围:1:00:00-12:59:59

比如:

select to_char(sysdate,'yy-mm-dd hh24:mi:ss') from dual //显示:08-11-07 13:22:42

select to_date('2005-12-25,13:25:59','yyyy-mm-dd,hh24:mi:ss') from dual //显示:2005-12-25 13:25:59

而如果把上式写作:select to_date('2005-12-25,13:25:59','yyyy-mm-dd,hh:mi:ss') from dual,则会报错,因为小时hh是12进制,13为非法输入,不能匹配。

补充:

当前时间减去7分钟的时间
select sysdate,sysdate - interval '7' MINUTE from dual
当前时间减去7小时的时间
select sysdate - interval '7' hour from dual
当前时间减去7天的时间
select sysdate - interval ’7’ day from dual
当前时间减去7月的时间
select sysdate,sysdate - interval '7' month from dual
当前时间减去7年的时间
select sysdate,sysdate - interval '7' year from dual
时间间隔乘以一个数字
select sysdate,sysdate - 8*interval '7' hour from dual

Dual伪列

含义解释:

Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的select语句块中。

比如,我要获得系统时间,则用“select sysdate from dual” 则返回系统当前的时间:2008-11-07 9:32:49,不同系统可能返回日期的格式不一样。"select user from dual"则返回当前连接的用户。如果是"select 1+2 from dual",则返回结果:3

Wednesday, April 15, 2009

some oracle sql

1. select (case when s_mark <> 80 then '优异'
when s_mark <= 80 and s_mark >= 60 then '优秀'
when s_mark <= 59 and s_mark >= 40 then '良好'
when s_mark <>= 20 then '一般'
when s_mark <= 19 and s_mark > 0 then '较差' from student_scores
----------------------------------------
2. case和decode (P61)语句有什么区别?分别在什么场合使用?
SELECT CASE SIGN(5 - 5) WHEN 1 THEN 'Is Positive' WHEN -1 THEN 'Is Negative' ELSE 'Is Zero' END FROM DUAL;
select decode (条件,结果1,输出1,结果2,输出2)
SELECT DECODE(SIGN(5-9), 1, 'Is Positive', -1, 'Is Negative', 'Is Zero')FROM DUAL
--------------------------------------

Tuesday, April 14, 2009

link for Oracle

1. Oracle FAQ

使用Oracle游标

游标分为:静态游标和引用游标(动态游标)
静态游标:由用户定义(隐式游标、显示游标)结果集不变
引用游标游标:结果集变化
----------------
%NOTFOUND -- 执行行没有找到。

%FOUND --执行行找到

%ROWCOUNT --游标影响行数

%ISOPEN -- 当前游标是否打开
----------------------------------
例如:

DECLARE

v_FirstName students.first_name%TYPE;


通过使用%TYPE,v_FirstName变量将同students表的first_name列的类型相同(可以理解为将两者邦定起来)。

每次匿名块或命名块运行该语句块以及编译存储对象(过程、函数、包、对象类和触发器)时,就会确定该类型。

使用%TYPE是非常好的编程风格,因为它使得PL/SQL更加灵活,更加适应于对数据库定义的更新。
-------------------------
在PL/SQL中将一个记录声明为具有相同类型的数据库行的作法是很常见的。PL/SQL提供了%ROWTYPE运算符,使得这样的操作更为方便。

例如:

DECLARE

v_RoomRecord rooms%ROWTYPE;

将定义一个记录,该记录中的字段将与rooms表中的列相对应。

Monday, April 13, 2009

Oracle 临时表

oracle 的TEMPORARY TABLE有两种,一种是基Session的,即表中的数据在Session结束前数据都存在。另一种是基于transaction的数据在transaction Commit或Rollback后消失。默认值是基于transaction的。所以你"提交后被告知没有行可以选择"。

当会话退出或者用户提交commit和回滚rollback事务的时候,临时表的数据自动清空(truncate),但是临时表的结构以及元数据还存储在用户的数据字典中。你可以索引临时表和在临时表基础上建立视图.同样,建立在临时表上的索引也是临时的,也是只对当前会话或者事务有效. 临时表可以拥有触发器。

Temp Table 并非存放在用户的表空间中,而是存放在 Schema 所指定的临时表空间中, 你可以用下面的语句来检测:
SQL> Select Table_Name, Tablespace_Name
From User_Tables
Where Table_Name Like 'temp_%';

用户 SQLTRAINER 的临时表空间是 TEMP , 用户创建的临时表是存放在TEMP表空间中的。下面来证明

SQL> SELECT UserName, Default_Tablespace def_ts, Temporary_Tablespace temp_ts
FROM User_Users;

尽管对临时表的DML操作速度比较快,但同样也是要产生 Redo Log 的,只是同样的DML语句,比对 PERMANENT 的DML 产生的Redo Log 少。

如果你想数据在Session结束前数据都存在参考下面的例子,或看Oracle的帮助
/*******************************************************************************/
CREATE GLOBAL TEMPORARY TABLE flight_schedule (
startdate DATE,
enddate DATE,
cost NUMBER)
ON COMMIT PRESERVE ROWS;
/*******************************************************************************/

create global temporary table temp_table_name (....) on commit delete rows;
此为事务级临时表,你向里边插入的数据,在commit后就消失,当然rollback后也回滚即消失。
注意事务级临时表在同一会话的嵌套事务中跟一般表一样也可能发生阻塞。

create global temporary table temp_table_name (....) on commit preserve rows;
此为会话级临时表,你向里边插入的数据,在commit后保留不消失,而在整个会话结束后消失,当然rollback也会回滚。

Oracle tips

执行sql脚本
SQL >@a.sql

执行外部shell脚本
SQL>host test.sh
or
SQL>! cd ..
-----------------------
注释
1. --
2. /* 与*/
3. REM
------------------------
1. (+) --> left join
2. LEFT OUTER JOIN
3. RIGHT OUTER JOIN
------------------------
查询索引
SQL> select index_name,table_name from user_indexes;
-----------------------
查询当前所有的表
SQL> select * from tab;
SQL> select * from cat;
------------------------------
显示当前连接用户(库)
SQL> show user
----------------------------
改变连接用户(库)
SQL> conn 用户名/密码@主机字符串
-------------------------
查找一个连接
Sql>Select * from v$session;
-----------------------------
杀掉一个连接
Sql>alter system kill session ‘SID,SERIAL#’;
----------------------------
useful link:
2.

Oracle Select的默认排序规则

一般而言,表是堆表,所以是无序的
他是按照也即物理存放顺序来读取的
rowid 是自动随行生成的
---------------------
实际上oracle没有进行任何排序操作,rowid表示的是数据存放的数据块内部地址,如果没有要求排序,oracle会顺序的从数据块中读取符合条件的数据返回到客户端
--------------------
因为oracle是按块进行读取数据的
如果数据按顺序存储,则可能使读取出来的数据是按顺序的

Wednesday, April 8, 2009

Oracle中创建数组【转】

在Oracle中很容易构造数组:

SQL> SET SERVEROUT ON SIZE 100000
SQL> DECLARE
2 TYPE T_VARRAY IS VARRAY(5) OF NUMBER;
3 V_VAR T_VARRAY := T_VARRAY(1,2,3,4,5);
4 BEGIN
5 FOR I IN 1..V_VAR.COUNT LOOP
6 DBMS_OUTPUT.PUT_LINE(V_VAR(I));
7 END LOOP;
8 END;
9 /

PL/SQL 过程已成功完成。

对于二维数组也是很容易实现的:

SQL> DECLARE
2 TYPE T_VARRAY IS VARRAY(5) OF NUMBER;
3 TYPE T_VARRAY_VARRAY IS VARRAY(4) OF T_VARRAY;
4 V_VAR T_VARRAY_VARRAY := T_VARRAY_VARRAY
5 (
6 T_VARRAY(1,2,3,4,5),
7 T_VARRAY(1,2,3,4,5),
8 T_VARRAY(1,2,3,4,5),
9 T_VARRAY(1,2,3,4,5)
10 );
11 BEGIN
12 FOR I IN 1..V_VAR.COUNT LOOP
13 FOR J IN 1..V_VAR(I).COUNT LOOP
14 DBMS_OUTPUT.PUT_LINE(V_VAR(I)(J));
15 END LOOP;
16 END LOOP;
17 END;
18 /

PL/SQL 过程已成功完成。

Oracle除了数组类型VARRAY之外,还有嵌套表和索引表也都可以实现类似数组的功能,其中索引表的使用更加灵活,方便。

SQL> DECLARE
2 TYPE T_TAB IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
3 V_VAR T_TAB;
4 BEGIN
5 SELECT ROWNUM BULK COLLECT INTO V_VAR FROM USER_OBJECTS
6 WHERE ROWNUM <= 5;
7 FOR I IN 1..V_VAR.COUNT LOOP
8 DBMS_OUTPUT.PUT_LINE(V_VAR(I));
9 END LOOP;
10 END;
11 /

PL/SQL 过程已成功完成。

使用索引表定义数组,不需要指定数组的上限,数组的大小只与内存限制有关。

而且索引组织表定义是指定的索引项并一定要是数值,举个简单的例子:

SQL> DECLARE
2 TYPE T_TAB IS TABLE OF NUMBER INDEX BY VARCHAR2(30);
3 V_VAR T_TAB;
4 V_STR VARCHAR2(30);
5 BEGIN
6 FOR I IN (SELECT OWNER, COUNT(*) CN FROM DBA_TABLES GROUP BY OWNER) LOOP
7 V_VAR(I.OWNER) := I.CN;
8 END LOOP;
9 V_STR := V_VAR.FIRST;
10 WHILE (V_VAR.EXISTS(V_STR)) LOOP
11 DBMS_OUTPUT.PUT_LINE(RPAD(V_STR, 20, ' ') || ':' || V_VAR(V_STR));
12 V_STR := V_VAR.NEXT(V_STR);
13 END LOOP;
14 END;
15 /
CATA_LOG :37
CTXSYS :37
DBSNMP :21
DMSYS :2
EXFSYS :44
HR :7
IX :15
MDSYS :49
OE :12
OLAPSYS :126
ORDSYS :4
OUTLN :3
PM :2
SCOTT :4
SH :17
SYS :706
SYSMAN :337
SYSTEM :141
TSMSYS :1
WMSYS :40
XDB :11
YANGTK :6

PL/SQL 过程已成功完成。

如果构造二维以上的数组,且维度不全是数值,那么就需要注意了:

SQL> DECLARE
2 TYPE T_NUM_TAB IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
3 TYPE T_VAR_TAB IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
4 TYPE T_NUM_VAR IS TABLE OF T_NUM_TAB INDEX BY VARCHAR2(10);
5 TYPE T_VAR_NUM IS TABLE OF T_VAR_TAB INDEX BY BINARY_INTEGER;
6 V_NUM_VAR T_NUM_VAR;
7 V_VAR_NUM T_VAR_NUM;
8 BEGIN
9 V_NUM_VAR(5)('A') := 1;
10 V_VAR_NUM('A')(5) := 1;
11 END;
12 /
DECLARE
*第 1 行出现错误:
ORA-06502: PL/SQL: 数字或值错误 : 字符到数值的转换错误
ORA-06512: 在 line 9


SQL> DECLARE
2 TYPE T_NUM_TAB IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
3 TYPE T_VAR_TAB IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
4 TYPE T_NUM_VAR IS TABLE OF T_NUM_TAB INDEX BY VARCHAR2(10);
5 TYPE T_VAR_NUM IS TABLE OF T_VAR_TAB INDEX BY BINARY_INTEGER;
6 V_NUM_VAR T_NUM_VAR;
7 V_VAR_NUM T_VAR_NUM;
8 BEGIN
9 V_NUM_VAR('A')(5) := 1;
10 V_VAR_NUM('A')(5) := 1;
11 END;
12 /
DECLARE
*第 1 行出现错误:
ORA-06502: PL/SQL: 数字或值错误 : 字符到数值的转换错误
ORA-06512: 在 line 10


SQL> DECLARE
2 TYPE T_NUM_TAB IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
3 TYPE T_VAR_TAB IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
4 TYPE T_NUM_VAR IS TABLE OF T_NUM_TAB INDEX BY VARCHAR2(10);
5 TYPE T_VAR_NUM IS TABLE OF T_VAR_TAB INDEX BY BINARY_INTEGER;
6 V_NUM_VAR T_NUM_VAR;
7 V_VAR_NUM T_VAR_NUM;
8 BEGIN
9 V_NUM_VAR('A')(5) := 1;
10 V_VAR_NUM(5)('A') := 1;
11 END;
12 /

PL/SQL 过程已成功完成。

从这个例子可以看出,用索引表构造的数组和C语言中的数组是有区别的。

Tuesday, April 7, 2009

Oracle DB Link introduction [REF]

1。基本概念:
数据库连接串主要用于建立对远程数据库的访问方法,可以直接读取远程Oracle的数据,或者直接修改。数据库连接串可以是公用连接PUBLIC或者私有连接PRIVATE。这一点和同义词很相像。 其实dblink和数据库中的view差不多,建dblink的时候需要知道待读取数据库的ip地址,ssid以及数据库用户名和密码
1。创建语法:
CREATE DATABASE LINK TEST CONNECT TO USERNAME IDENTIFIED BY PASSWORD
USING 'CONNECT_STRING';
解释:TEST是数据库连接串的名字。以后就通过这个名字来进行调用远程数据库的内容。
USERNAME是用来连接到远程数据库的合法Oracle用户名。PASSWORD为该用户连接到Oracle时候的合法密码。
CONNECT_STRING为该Oracle数据库所在的主机上的tnsnames.ora文件里边定义的数据库连接串。
1) 已经配置本地服务
create public database link fwq12 connect to fzept identified by neu using 'fjept'
 CREATE DATABASE LINK数据库链接名CONNECT TO 用户名 IDENTIFIED BY 密码 USING ‘本地配置的数据的实例名’;
2) 未配置本地服务
create database link linkfwq
   connect to fzept identified by neu
   using '(DESCRIPTION =
   (ADDRESS_LIST =
   (ADDRESS = (PROTOCOL = TCP)(HOST = 10.142.202.12)(PORT = 1521))
   )
   (CONNECT_DATA =
   (SERVICE_NAME = fjept)
   )
   )';

  host=数据库的ip地址,service_name=数据库的ssid。
  其实两种方法配置dblink是差不多的,感觉还是第二种方法比较好,这样不受本地服务的影响。数据库连接字符串可以用NET8 EASY CONFIG或者直接修改TNSNAMES.ORA里定义.

  数据库参数global_name=true时要求数据库链接名称跟远端数据库名称一样
  数据库全局名称可以用以下命令查出
  SELECT * FROM GLOBAL_NAME;
  查询远端数据库里的表
  SELECT …… FROM 表名@数据库链接名;

  查询、删除和插入数据和操作本地的数据库是一样的,只不过表名需要写成“表名@dblink服务器”而已。

  附带说下同义词创建:
  CREATE SYNONYM同义词名FOR 表名;
  CREATE SYNONYM同义词名FOR 表名@数据库链接名;
  删除dblink:DROP PUBLIC DATABASE LINK linkfwq。
  如果创建全局dblink,必须使用systm或sys用户,在database前加public。
2。使用方法:
SELECT COUNT(*) FROM TABLE_NAME@DB_LINK WHERE WHERE_CLAUSE;//查阅远程数据库的内容。

UPDATE TEST.TEST@DB_LINK SET SO_NBR=NEW_SO_NBR
WHERE WHERE_CLAUSE;//修改远程数据库的内容。
在实际使用过程中,还可以通过为这个远程表建立一个同义词来进一步增加透明性,使该数据库连接串对于程序和开发人员来讲完全透明。
CREATE SYNONYM TABLE_NAME FOR TABLE_NAME@DB_LINK;
3。数据库连接的管理:
1) 如何知道当前用户、当前系统中有哪些数据库连接串?
SELECT * FROM USER_DB_LINKS;
这个查询会给出当前用户的数据库联接的名字、联接用户名、联接密码、要连接的主机以及创建时期。
2) SELECT * FROM DBA_DB_LINKS;
这个查询会给出当前系统中所有的数据库联接的创建用户、联接用户名、要连接的主机以及创建时期。
3) SELECT * FROM V$DBLINK;
这个查询会给出当前打开的数据库联接。
4) 删除数据库连接
先从第2)步中查看数据库连接,取得其db_link的名称
sql>drop public database link TEST.US.ORACLE.COM
数据库连接巳丢弃

Thursday, April 2, 2009

使用集合 - Oracle

使用集合

  象记录一样,集合可以在两个层面上使用:

   . 操作整个集合

   . 访问集合中的单个元素

  第一种情况使用集合名,第二种情况使用下标:

   collection(subscript)

  index_by表的下标是两为的整数,可以为正也可以为负,范围是:-2147483647--2147483647。嵌套表和VARRAY表示元素在集合中的位置,用户很难灵活设计下标,这是因为:

   . 嵌套表开始是紧密的(相对于疏松)

   . VARRAY始终保持紧密

   . 这两种集合的下标都由1开始

  初始化、删除、引用集合

  使用集合之前必须要初始化,对于Index_by表初始化是自动进行的,但是对于嵌套表和VARRAY就必须使用内建的构造函数。如果重新调用,嵌套表和VARRAY自动置NULL,这不只是元素置NULL,而是整个集合置NULL。给集合内的元素赋值需要使用下标符号。将一个集合的值赋给另一个集合,只需要简单的使用赋值操作符。

  Index_by集合初始化是最简单的,只要涉及其中的一个元素集合就被初始化了。

  例: 


DECLARE

TYPE symbol_tab_typ IS TABLE OF VARCHAR2(5) INDEX BY BINARY_INTEGER;
TYPE account_tab_typ IS TABLE OF account%ROWTYPE INDEX BY BINARY_INTEGER;
symbol_tab symbol_tab_typ;
account_tab account_tab_typ;
new_acct_tab account_tab_typ;

BEGIN
--初始化集合元素147和-3
SELECT * INTO account_tab(147)
FROM accounts WHERE account_nbr=147;

SELECT * INTO account_tab(-3)
FROM accounts WHERE account_nbr=3003;

IF account_tab(147).balance<500 THEN
chang_maintenance_fee(147);
END IF

new_acct_tab:=account_tab;
symbol_tab(1):="ORCL";
symbol_tab(2):="CSCO";
symbol_tab(3):="SUNM";

publish_portfolio(symbol_tab);

  嵌套表和VARRAY由构造函数初始化,构造函数和集合的名字相同,同时有一组参数,每个参数对应一个元素,如果参数为NULL,那么对应的元素就被初始化为NULL,如果创建了元素,但没有填充数据,那么元素将保持null值,可以被引用,但不能保持数据。如果元素没有初始化,那么就不能引用该元素。

  例:


DECLARE

TYPE stock_list IS TABLE OF stock.symbol%TYPE;
TYPE top10_list IS VARRAY (10) OF stocks.symbol%TYPE;
biotech_stocks stock_list;
tech_10 top10_list;

BEGIN
--非法,集合未初始化。
biotech_stocks(1):='AMGN';
IF biotech_stocks IS NULL THEN
--初始化集合
biotech_stocks:=('AMGN','BGEN',IMCL','GERN',CRA');
END IF;
tech_10:=top10_list('ORCL',CSCO','MSFT','INTC','SUNW','IBM',NULL,NULL);
IF tech_10(7) IS NULL THEN
tech_10(7):='CPQ';
END
tech_10(8):='DELL';


  在这个例子中,嵌套表BIOTECH_STOCKS初始化有5个元素,VARRAY tech_10集合最多能有10 个元素,但构造函数只创建了8个元素,其中还有两个元素是NULL值,并程序中给他们赋值。

  初始化基于记录的集合,就必须将记录传递给构造函数,注意不能只是简单的将记录的域传递给构造函数。

  例:


DECLARE

TYPE stock_quote_rec IS RECORD
(symbol stock.symbol%TYPE
,bid NUMBER(10,4)
,ask NUMBER(10,4)
,volume NUMBER NOT NULL:=0
);
TYPE stock_tab_typ IS TABLE OF stock_quote_rec;
quote_list stock_tab_typ;
single_quote stock_quote_rec;

BEGIN
single_quote.symbol:='OPCL';
single_quote.bid:=100;
single_quote.ask:=101;
single_quote.volume:=25000;
--合法
quote_list:=stock_tab_typ(single_quote);
--不合法
quote_list:=stock_tab_typ('CSCO',75,76,3210000);
DBMS_OUTPUT.LINE(quote_list(1).bid);

Thursday, March 26, 2009

Oracle String Functions

1.ASCII 
返回与指定的字符对应的十进制数; 
SQL> select ascii(’A’) A,ascii(’a’) a,ascii(’0’) zero,ascii(’ ’) space from dual; 
A A ZERO SPACE 
--------- --------- --------- --------- 
65 97 48 32 

2.CHR 
给出整数,返回对应的字符; 
SQL> select chr(54740) zhao,chr(65) chr65 from dual; 
ZH C 
-- - 
赵 A 
3.CONCAT 
连接两个字符串; 
SQL> select concat(’010-’,’88888888’)||’转23’ 高乾竞电话 from dual; 
高乾竞电话 
---------------- 
010-88888888转23 
4.INITCAP 
返回字符串并将字符串的第一个字母变为大写; 
SQL> select initcap(’smith’) upp from dual; 
UPP 
----- 
Smith 

5.INSTR(C1,C2,I,J) 
在一个字符串中搜索指定的字符,返回发现指定的字符的位置; 
C1 被搜索的字符串 
C2 希望搜索的字符串 
I 搜索的开始位置,默认为1 
J 出现的位置,默认为1 
SQL> select instr(’oracle traning’,’ra’,1,2) instring from dual; 
INSTRING 
--------- 

6.LENGTH 
返回字符串的长度; 
SQL> select name,length(name),addr,length(addr),sal,length(to_char(sal)) from gao.nchar_tst; 
NAME LENGTH(NAME) ADDR LENGTH(ADDR) SAL LENGTH(TO_CHAR(SAL)) 
------ ------------ ---------------- ------------ --------- -------------------- 
高乾竞 3 北京市海锭区 6 9999.99 7 

7.LOWER 
返回字符串,并将所有的字符小写 
SQL> select lower(’AaBbCcDd’)AaBbCcDd from dual; 
AABBCCDD 
-------- 
aabbccdd 

8.UPPER 
返回字符串,并将所有的字符大写 
SQL> select upper(’AaBbCcDd’) upper from dual; 
UPPER 
-------- 
AABBCCDD 

9.RPAD和LPAD(粘贴字符) 
RPAD 在列的右边粘贴字符 
LPAD 在列的左边粘贴字符 
SQL> select lpad(rpad(’gao’,10,’*’),17,’*’)from dual; 
LPAD(RPAD(’GAO’,1 
----------------- 
*******gao******* 
不够字符则用*来填满 

10.LTRIM和RTRIM 
LTRIM 删除左边出现的字符串 
RTRIM 删除右边出现的字符串 
SQL> select ltrim(rtrim(’ gao qian jing ’,’ ’),’ ’) from dual; 
LTRIM(RTRIM(’ 
------------- 
gao qian jing 

11.SUBSTR(string,start,count) 
取子字符串,从start开始,取count个 
SQL> select substr(’13088888888’,3,8) from dual; 
SUBSTR(’ 
-------- 
08888888 

12.REPLACE(’string’,’s1’,’s2’) 
string 希望被替换的字符或变量 
s1 被替换的字符串 
s2 要替换的字符串 
SQL> select replace(’he love you’,’he’,’i’) from dual; 
REPLACE(’H 
---------- 
i love you 

13.SOUNDEX 
返回一个与给定的字符串读音相同的字符串 
SQL> create table table1(xm varchar(8)); 
SQL> insert into table1 values(’weather’); 
SQL> insert into table1 values(’wether’); 
SQL> insert into table1 values(’gao’); 
SQL> select xm from table1 where soundex(xm)=soundex(’weather’); 
XM 
-------- 
weather 
wether 

14.TRIM(’s’ from ’string’) 
LEADING 剪掉前面的字符 
TRAILING 剪掉后面的字符 
如果不指定,默认为空格符

How to open *.bin file in Linux

Ensure you trust the source of the file. The following procedure will allow the bin file to make any changes it wants to make to your system.

- Save the bin file to your home folder.
- Click Applications, Accessories, Terminal.
- Press ENTER after each command below.
- To make the BIN file executable: In the terminal, type the command:
chmod 755 NameOfBinFile.bin
- To run the file and install RealPlayer type the command:
sudo ./NameOfBinFile.bin
- Follow the on screen prompts.Press space to page down if any.

Wednesday, March 25, 2009

Python、Lua和Ruby [转]

译者按:Python、lua和ruby在C/C++是日渐式微的情况下,在java/.net的围歼中努力抗争的三个当红小生。在Tom Gutschmidt的著作《Game Programmng with Python, Lua and Ruby》一书中,介绍了三种语言在游戏中的应用,其中尤为了不起的是在书中最后一章中比较了三种脚本,作者没有说孰优孰劣,但是读者你认为呢?欢迎留言讨论。
 
So which of the three languages is the best to use on your project? That depends a great deal on what you want to accomplish. To wrap up the book, I've outlined some of the pros and cons of each language in this section.
这三种语言中的哪一种更合适你的项目?很大程度取决于你想达到什么样的目标。作为一书的结尾,在这一节里,我会描述一下它们各自的优点和不足。
Python Pros and Cons
Python的优点和不足
The pros of Python are as follows:
Python的优点如下:
·         Python has more extension modules than the other languages.
·         Python比其它语言有更多扩展模块。
·         Many online Python tutorials exist. There are also plenty of English books and reference materials, many sample scripts exist online, and there is a wealth of introductory material. The Python.org Website is a good place to start looking for these because it has sections for beginners, tutorials, guides organized by topic, and lists of links and references.
·         在网上可以找到很多Python教程。不仅如此,还有大量的英文书籍和资料。Python.org有很多为初学者准备的依主题组织的资料、教程和编程指南,此外还有很多链接和参考。
·         Most folks really enjoy the syntax of the Python language because it appears clean and is easy to read.
·         很多人都喜欢Python语言的语法,因为它清晰易读。
·         Python has an edge where libraries are concerned. There are many libraries, and, for the most part, they are well documented.
·         Python在支持库上大占优势,因为它有很多库,而且大部分都有完善的文档支持。
·         Lots of tools that tie into Python are available, and they are often easier to find than the tools for Lua and Ruby.
·         很多工具可以用于Python,但难以找到适用于Lua和Ruby的。
The cons of Python are as follows:
Python的不足:
·         Existing Python debuggers are considered quirky and slow. Debugging support on Macintosh and consoles is even weaker.
·         现有的Python调试器诡异而且效率低下。在Macintosh(苹果计算机)和控制台下进行调试是一个梦魇。
·         It can be difficult to bundle Python with other languages. There are lots of binary DLLs, and Python has (compared to the other languages) a large standard distribution.
·         Python难以与其它语言集成,它有太多的二进制DLL,而且Python带了巨大的标准发布包。
·         Lots of folks really dislike the white space sensitivity of Python syntax.
·         同样的,也有很多人不喜欢Python对空白符敏感的语法。
·         Python can be quite slow at times, as everything is an object on the heap.
·         因为栈上的任何东西都是对象,所以Python有时候会慢得难以忍受。
Lua Pros and Cons
Lua的优点和不足
The pros of Lua are as follows:
Lua的优点:
·         Lua is probably the fastest of the three languages and usually uses the least amount of runtime memory.
·         Lua在这三种语言中是运行时速度最快而且占内在最少的。
·         Lau has the smallest memory footprint for bundling.
·         集成Lua只会增加极少的内存占用率。
·         The Lau C API is very well documented and has good examples for integrating with C.
·         Lua的C API有着完备着文档和很好的例子,可以容易地通过C集成在软件里。
The cons of Lua are as follows:
Lua的不足:
·         The documentation has improved but is still a bit sketchy overall. Of the three languages, Lua it is probably the least documented (the API being the exception), with the least amount of code comments. This makes for the largest ramp-up time to learn, and there isn't much in the way of introductory Lua material.
·         尽管Lua的文档已经增进不少,但仍然有所不足。三种语言中,Lua可能是文档最少的(API方面是个例外),因为代码中极少注释,这也增加了学习的难度。另外,对Lua的本质也没有什么介绍。
·         There isn't a lot of built-in functionality for Lua. There is little support if you need to create a large, complex application.
·         Lua内建的功能很少,并没有对创建大型的复杂应用程序提供足够支持。
·         Lua could use a better garbage collectorthe current development is moving towards that now. Right now, Lua GC uses a very simple and traditional simple mark and sweep.
·         Lua应该使用更好的垃圾收集机制,Lua现在的GC仍然使用非常简单而且传统的“标记和清除”方式。
Pros and Cons of Ruby
Ruby的优点和不足
The pros of Ruby are as follows:
Ruby的优点:
·         Ruby possesses fairly good advanced debuggers.
·         Ruby有极好的高级调试器。
·         Ruby is object oriented from the ground up, and programmers who are OOP enthusiasts or who are used to the OOP paradigm will find the language extremely comfortable.
·         Ruby是最彻底的面向对象语言,对于OOP狂热者和惯于使用OOP范式的程序员,他们将会发现Ruby是最适合他们的语言。
·         Ruby has arguably the simplest syntax, with no real rules exceptions. Especially true for OOP enthusiasts. 
·         Ruby的语法极为简单,没有让人出乎意料规则,特别适合OOP行家的习惯。
The cons of Ruby are as follows:
Ruby的不足:
·         Lack of English documentation.
·         英文文档极度缺乏。
·         Fewer existing works and samples for games than with the other languages.
·         与其它语言相比,在游戏方面所作的工作和实例都少得多。

Tuesday, March 24, 2009

查询数据库版本信息

查询Oracle数据库版本信息
select * from v$instance
select * from product_component_version

查询SqlServer版本信息
select @@version version

Monday, March 23, 2009

JDK中Jconsole的使用[REF]

JAVA应用程序打成jar包的部署方式: 

一、Local方式 
1、cmd进入dos下,进入到应用程序所在目录,执行语句如下: 
java -Dcom.sun.management.jmxremote -jar 程序名.jar 
(java -Dcom.sun.management.jmxremote -jar Java2Demo.jar)(测试例子Java2Demo.jar在C:\Program Files\Java\jdk1.6.0_02\demo\jfc\Java2D\) 

还出不来的话 直接 在dos里 jconsole 进程号 

2、启动jdk_home\bin目录下的Jconsole.exe就可以看到有一个 

本地的连接在里面。点击连接就可以进入相应的监视界面了。 

二、JMX方式(远程连接): 
1、cmd进入dos下,进入到应用程序所在目录,执行语句如下: 
java -Dcom.sun.management.jmxremote.port=8903 - 

Dcom.sun.management.jmxremote.ssl=false - 

Dcom.sun.management.jmxremote.authenticate=false 
-Djava.rmi.server.hostname=192.168.***.*** 

2、启动jdk_home\bin目录下的Jconsole.exe点高级。在JMX 

URL:中输入语句如下: 

service:jmx:rmi:///jndi/rmi://192.168.***.***:8903/jmxr 

mi 
点连接就可以进行远程监控了 



web应用程序在tomcat中部署JMX(示例:tomcat-6.0.14) 
1、启动tomcat\bin目录下的tomcat6w.exe,在JAVA_OPTS里设 

置如下: 
-Dcom.sun.management.jmxremote.port=8903 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Djava.rmi.server.hostname=192.168.***.*** 

注意:不能有空格,不然tomcat不能启动。 

2、tomcat启动成功后,就可以在另一台机器上启动 

jdk_home\bin目录下的Jconsole.exe点高级。在JMX URL:中输 

入语句如下: 

service:jmx:rmi:///jndi/rmi://192.168.***.***:8903/jmxr 

mi 
点连接就可以进行远程监控了 

以上是JMX基本部署,没有涉及到验证方面,如果使用的话,可 

能会有漏洞,因为SSL和authenticate设置为false的话,那么 

8903端口就有可能有暴露的危险。 

如果想进行密码验证话,可以在网上找资料,自己进行调试。 


我自己的应用: 
1.修改Linux下tomcat的bin目录下的catalina.sh文件 
添加 
JAVA_OPTS=-Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.port=7080  
-Dcom.sun.management.jmxremote 
2.修改/etc/hosts文件下的localhost对应的IP(127.0.0.1)地址,改为linux自身的IP如10.0.0.157. 
3.打开jconsole远程输入 10.0.0.157:7080 

三 

Eden Space (heap): 内存最初从这个线程池分配给大部分对象。 
Survivor Space (heap):用于保存在eden space内存池中经过垃圾回收后没有被回收的对象。 
Tenured Generation (heap):用于保持已经在 survivor space内存池中存在了一段时间的对象。 
Permanent Generation (non-heap): 保存虚拟机自己的静态(refective)数据,例如类(class)和方法(method)对象。Java虚拟机共享这些类数据。这个区域被分割为只读的和只写的, 
Code Cache (non-heap):HotSpot Java虚拟机包括一个用于编译和保存本地代码(native code)的内存,叫做“代码缓存区”(code cache)

Thursday, March 19, 2009

实体化试图(Materialized View)介绍

实体化视图or物化视图概述 

A materialized view provides indirect access to table data by storing the results of a query in a separate schema object. Unlike an ordinary view, which does not take up any storage space or contain any data.

Oracle的实体化视图提供了强大的功能,可以用在不同的环境中。在不同的环境中,实体化视图的作用也不相同。数据仓库中的实体化视图主要用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,而从快速的得到结果。在数据仓库中,还经常使用查询重写(query rewrite)机制,这样不需要修改原有的查询语句,Oracle会自动选择合适的实体化视图进行查询,完全对应用透明。实体化视图和表一样可以直接进行查询。实体化视图可以基于分区表,实体化视图本身也可以分区。除了在数据仓库中使用,实体化视图还用于复制、移动计算等方面。实体化视图有很多方面和索引很相似:使用实体化视图的目的是为了提高查询性能;实体化视图对应用透明,增加和删除实体化视图不会影响应用程序中SQL语句的正确性和有效性;实体化视图需要占用存储空间;当基表发生变化时,实体化视图也应当刷新。

物化视图是包括一个查询结果的数据库对像,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表。物化视图存储基于远程表的数据,也可以称为快照。

物化视图可以查询表,视图和其它的物化视图。

通常情况下,物化视图被称为主表(在复制期间)或明细表(在数据仓库中)。

对于复制,物化视图允许你在本地维护远程数据的副本,这些副本是只读的。如果你想修改本地副本,必须用高级复制的功能。当你想从一个表或视图中抽取数据时,你可以用从物化视图中抽取。

需要注意的地方,物化视图是数据仓库的技术,如果想要做到时时的数据更新,必然会对oltp类型的数据库造成影响,那么在作物化视图的时候需要衡量,权衡是否需要这样的视图,如果需要,那么就有不要牺牲时时更新数据,可以在oltp系统不繁忙的时候来让系统自动刷新统计值。而且在建立的时候,最好不要在业务繁忙的时候建立。

Monday, March 16, 2009

在ORACLE中创建自增字段

通过创建序列来实现 
ORACLE SEQUENCE的简单介绍 


在oracle中sequence就是所谓的序列号,每次取的时候它会自动增加,一般用在需要按序列号排序的地方。 
1、Create Sequence 
你首先要有CREATE SEQUENCE或者CREATE ANY SEQUENCE权限, 
CREATE SEQUENCE emp_sequence 
INCREMENT BY 1 -- 每次加几个 
START WITH 1 -- 从1开始计数 
NOMAXVALUE -- 不设置最大值 
NOCYCLE -- 一直累加,不循环 
CACHE 10; 

一旦定义了emp_sequence,你就可以用CURRVAL,NEXTVAL 
CURRVAL=返回 sequence的当前值 
NEXTVAL=增加sequence的值,然后返回 sequence 值 
比如: 
emp_sequence.CURRVAL 
emp_sequence.NEXTVAL 

可以使用sequence的地方: 
- 不包含子查询、snapshot、VIEW的 SELECT 语句 
- INSERT语句的子查询中 
- NSERT语句的VALUES中 
- UPDATE 的 SET中 

可以看如下例子: 
INSERT INTO emp VALUES 
(empseq.nextval, 'LEWIS', 'CLERK',7902, SYSDATE, 1200, NULL, 20); 

SELECT empseq.currval FROM DUAL; 

但是要注意的是: 
- 第一次NEXTVAL返回的是初始值;随后的NEXTVAL会自动增加你定义的INCREMENT BY值,然后返回增加后的值。CURRVAL 总是返回当前SEQUENCE的值,但是在第一次NEXTVAL初始化之后才能使用CURRVAL,否则会出错。一次NEXTVAL会增加一次SEQUENCE的值,所以如果你在同一个语句里面使用多个NEXTVAL,其值就是不一样的。明白? 

- 如果指定CACHE值,ORACLE就可以预先在内存里面放置一些sequence,这样存取的快些。cache里面的取完后,oracle自动再取一组到cache。 使用cache或许会跳号, 比如数据库突然不正常down掉(shutdown abort),cache中的sequence就会丢失. 所以可以在create sequence的时候用nocache防止这种情况。 

2、Alter Sequence 
你或者是该sequence的owner,或者有ALTER ANY SEQUENCE 权限才能改动sequence. 可以alter除start至以外的所有sequence参数.如果想要改变start值,必须 drop sequence 再 re-create . 
Alter sequence 的例子 
ALTER SEQUENCE emp_sequence 
INCREMENT BY 10 
MAXVALUE 10000 
CYCLE -- 到10000后从头开始 
NOCACHE ; 


影响Sequence的初始化参数: 
SEQUENCE_CACHE_ENTRIES =设置能同时被cache的sequence数目。 

可以很简单的Drop Sequence 
DROP SEQUENCE order_seq;

Monday, March 9, 2009

linux下如何运行shell脚本

和   window   的bat编写方法基本一样,无非是把命令用linux中的shell中的命令代理就可以了,   
  最重要的是,文件保存以后要把属性设置正确一定要   +x     这样才可以执行。
可以使用WinScp来设置或者linux命令   
    
这样就行了。 

运行时使用sh **.sh即可执行,或者./*.sh 来运行

Thursday, March 5, 2009

database tip

数据库连接对象调用close方法后,还把连接对象置为null;

个人决论:数据库连接对象调用close()方法关闭后,并没有马上关闭,但同时把连接对象置为null,有助于gc来回收连接对象从而加快数据库连接对象的回收吧。

Java Class

对象的创建有四种方式: 
1、用new语句创建对象 
2、用反射机制 java.lang.Class或者java.lang.reflect.Constructor类newInstance()方法 
3、调用clone()方法 
4、运用序列化方式,java.io.ObjectInputStream对象的readObject()方法

Sunday, March 1, 2009

【转】log4j xml配置详解

熟读一个典型的log4j配置文件:

一、概述

 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
  
  此外,通过Log4j其他语言接口,您可以在C、C++、.Net、PL/SQL程序中使用Log4j,其语法和用法与在Java程序中一样,使得多语言分布式系统得到一个统一一致的日志组件模块。而且,通过使用各种第三方扩展,您可以很方便地将Log4j集成到J2EE、JINI甚至是SNMP应用中。

二,使用前的准备。
 1、下载log4j 地址为:http://jakarta.apache.org/log4j/docs/download.html.
 2、你可能要用到的jar文件有:  如果需要将日志发送到邮箱,则需要javamail API,JAF API (the JavaBeans Activation Framework)
下载地址:  http://java.sun.com/products/javamail/
 http://java.sun.com/beans/glasgow/jaf.html
  如果需要jms的支持,则需要jms API 下载地址为:http://java.sun.com/products/jms/vendors.html
三, Log4j介绍
 Log4j由三个重要的组件构成:日志信息的优先级 priority,日志信息的输出目的地Appender,日志信息的输出格式(布局)layout。
日志的优先级,
 从低到高,依次有:DEBUG,INFO,WARN,ERROR,分别用来指定这条日志信息的重要程度;如果定义了了输入的级别为INFO,则只有等于及高于这个级别的才进行处理,此时将输入INFO,WARN,ERROR。值得注意的是,级别中还有两个关键字,
 ALL:打印所有的日志,
 OFF:关闭所有的日志输出。

1、 Loggers  

Loggers组件在此系统中被分为五个级别:DEBUG、INFO、WARN、ERROR和FATAL。这五个级别是有顺序的,
DEBUG 小于 INFO 小于 WARN 小于 ERROR 小于 FATAL,分别用来指定这条日志信息的重要程度,明白这一点很重要,
这里Log4j有一个规则:假设Loggers级别为P,如果在Loggers中发生了一个级别Q比P高,则可以启动,否则屏蔽掉。
假设你定义的级别是info,那么error和warn的日志可以显示而比他低的debug信息就不显示了。
  
  Java程序举例来说:
  
  //建立Logger的一个实例,命名为“com.foo”
  Logger logger = Logger.getLogger("com.foo"); //"com.foo"是实例进行命名,也可以任意

  //设置logger的级别。通常不在程序中设置logger的级别。一般在配置文件中设置。
  logger.setLevel(Level.INFO);
  Logger barlogger = Logger.getLogger("com.foo.Bar");

  //下面这个请求可用,因为WARN 大于等于 INFO
  logger.warn("Low fuel level.");

  //下面这个请求不可用,因为DEBUG 小于 INFO
  logger.debug("Starting search for nearest gas station.");

  //命名为“com.foo.bar”的实例barlogger会继承实例“com.foo”的级别。
    //因此,下面这个请求可用,因为INFO 大于等于 INFO
  barlogger.info("Located nearest gas station.");

  //下面这个请求不可用,因为DEBUG 小于 INFO
  barlogger.debug("Exiting gas station search");

  这里“是否可用”的意思是能否输出Logger信息。
  在对Logger实例进行命名时,没有限制,可以取任意自己感兴趣的名字。
    一般情况下建议以类的所在位置来命名Logger实例,这是目前来讲比较有效的Logger命名方式。
    这样可以使得每个类建立自己的日志信息,便于管理。比如:  
  static Logger logger = Logger.getLogger(ClientWithLog4j.class.getName());
 2、输出端 Appender  log4j提供了以下几种常用的输出目的地:
 org.apache.log4j.ConsoleAppender,将日志信息输出到控制台
 org.apache.log4j.FileAppender,将日志信息输出到一个文件

 org.apache.log4j.DailyRollingFileAppender,将日志信息输出到一个,并且每天输出到一个新的日志文件,按照不同的配置可以定义每月一个日志文件,或者每周,每天,每小时,每分钟等输出一个新的日志文件。
 org.apache.log4j.RollingFileAppender,将日志信息输出到一个文件,通过指定文件的的尺寸,当文件大小到达指定尺寸的时候会自动把文件改名,如名为example.log的文件会改名为example.log.1,同时产生一个新的example.log文件。如果新的文件再次达到指定尺寸,又会自动把文件改名为example.log.2,同时产生一个example.log文件。依此类推,直到example.log. MaxBackupIndex,MaxBackupIndex的值可在配置文件中定义。
 org.apache.log4j.WriterAppender,将日志信息以流格式发送到任意指定的地方。
 org.apache.log4j.jdbc.JDBCAppender,通过JDBC把日志信息输出到数据库中。
 org.apache.log4j.net.SMTPAppender,将日志信息以邮件的方式发送到指定的邮箱。

 3、输出格式(布局)layout
 通过appender可以控制输出的目的地,而如果要控制输出的格式,就可通过log4j的layout组件来实现。通过配置文件定义一个appender的输出格式,Log4j提供的布局模式有以下几种:
 org.apache.log4j.ConsoleAppender,输出到控制台
 org.apache.log4j.HTMLLayout,以HTML表格形式布局
 org.apache.log4j.PatternLayout,可以灵活地指定布局模式
 org.apache.log4j.SimpleLayout,包含日志信息的级别和信息字符串

1.HTMLLayout 选项

LocationInfo=true:默认值是false,输出java文件名称和行号

    Title=my app file: 默认值是 Log4J Log Messages.

2.PatternLayout 选项

  ConversionPattern=%m%n :指定怎样格式化指定的消息。

3.XMLLayout  选项

  LocationInfo=true:默认值是false,输出java文件和行号

实际应用:

  log4j.appender.A1.layout=org.apache.log4j.PatternLayout 

 值得一提的是org.apache.log4j.PatternLayout 以Pattern方式的布局,使用Pattern的方式来指定布局。

pattern 的参数如下:ConversionPattern参数的格式含义
 格式名 含义
 %c 输出日志信息所属的类的全名
 %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy-MM-dd HH:mm:ss },输出类似:2002-10-18- 22:10:28 ;比如 %d{HH:mm:ss,SSS} 或 %d{dd MMM yyyy HH:mm:ss,SSS}.
格式可以参考 java类 SimpleDateFormat,不过 按照此类的设置会影响速度。你可以选择更快的方式 %d{ISO8601},%d{ABSOLUTE}, %d{RELATIVE}.或者使用log4j的ISO8601DateFormat, AbsoluteTimeDateFormat,RelativeTimeDateFormat 和 DateTimeDateFormat 方式.
 %f 输出日志信息所属的类的类名
 %l 输出日志事件的发生位置,即输出日志信息的语句处于它所在的类的第几行
 %m 输出代码中指定的信息,如log(message)中的message
 %M 输出日志信息中所发生的方法名。
 %n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
 %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL。如果是调用debug()输出的,则为DEBUG,依此类推
 %r 输出自应用启动到输出该日志信息所耗费的毫秒数
 %t 输出产生该日志事件的线程名

-------------------------------------------------------------------

(1). 输出方式appender一般有5种:

             org.apache.log4j.RollingFileAppender(滚动文件,自动记录最新日志)
             org.apache.
log4j.ConsoleAppender (控制台)  
             org.apache.
log4j.FileAppender (文件)
             org.apache.
log4j.DailyRollingFileAppender (每天产生一个日志文件)
             org.apache.
log4j.WriterAppender (将日志信息以流格式发送到任意指定的地方) 

(2). 日记记录的优先级priority,优先级由高到低分为
            OFF ,FATAL ,ERROR ,WARN ,INFO ,DEBUG ,ALL。
           
Log4j建议只使用FATAL ,ERROR ,WARN ,INFO ,DEBUG这五个级别。 

(3). 格式说明layout中的参数都以%开始,后面不同的参数代表不同的格式化信息(参数按字母表顺序列出):
                %c        输出所属类的全名,可在修改为 %d{Num} ,Num类名输出的维(如:"org.apache.elathen.ClassName",%C{2}将输出elathen.ClassName)
                %d       输出日志时间其格式为 %d{yyyy-MM-dd HH:mm:ss,SSS},可指定格式 如 %d{HH:mm:ss}
                %l        输出日志事件发生位置,包括类目名、发生线程,在代码中的行数
                %n       换行符
                %m      输出代码指定信息,如info(“message”),输出message
                %p       输出优先级,即 FATAL ,ERROR 等
                %r        输出从启动到显示该log信息所耗费的毫秒数
                %t        输出产生该日志事件的线程名

参考资料
 1.http://www.vipan.com/htdocs/log4jhelp.html
         Don't Use System.out.println! Use Log4j - Vipan Singla
 2.http://jakarta.apache.org/log4j/docs/manual.html
  Short introduction to log4j - Ceki Gülcü - March 2002
 3.http://www-128.ibm.com/developerworks/cn/java/jw-log4j/
 log4j提供了对日志记录的控制
 4.http://logging.apache.org/log4j/docs/documentation.html
 log4j提供的文档。

5. http://wc-stone.javaeye.com/blog/134854

6. http://www.blogjava.net/hua/archive/2006/08/29/66420.html

7. http://zhangxiang390.javaeye.com/blog/258455

-----------------------------------------------------

 Log4j比较全面的配置 <<<<

 LOG4J的配置之简单使它遍及于越来越多的应用中了:Log4J配置文件实现了输出到控制台、文件、回滚文件、发送日志邮件、输出到数据库日志表、自定义标签等全套功能。择其一二使用就够用了,

 log4j.rootLogger=DEBUG,CONSOLE,A1,im
 log4j.addivity.org.apache=true

 # 应用于控制台

 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
 log4j.appender.Threshold=DEBUG
 log4j.appender.CONSOLE.Target=System.out
 log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
 log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
 #log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n

 #应用于文件

 log4j.appender.FILE=org.apache.log4j.FileAppender
 log4j.appender.FILE.File=file.log
 log4j.appender.FILE.Append=false
 log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
 log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
 # Use this layout for LogFactor 5 analysis

 # 应用于文件回滚

 log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
 log4j.appender.ROLLING_FILE.Threshold=ERROR
 log4j.appender.ROLLING_FILE.File=rolling.log  //文件位置,也可以用变量${java.home}、rolling.log
 log4j.appender.ROLLING_FILE.Append=true       //true:添加  false:覆盖
 log4j.appender.ROLLING_FILE.MaxFileSize=10KB   //文件最大尺寸
 log4j.appender.ROLLING_FILE.MaxBackupIndex=1  //备份数
 log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
 log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n


 #应用于socket
 log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
 log4j.appender.SOCKET.RemoteHost=localhost
 log4j.appender.SOCKET.Port=5001
 log4j.appender.SOCKET.LocationInfo=true
 # Set up for Log Facter 5
 log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
 log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n


 # Log Factor 5 Appender
 log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
 log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000

 # 发送日志给邮件

 log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
 log4j.appender.MAIL.Threshold=FATAL
 log4j.appender.MAIL.BufferSize=10
 
log4j.appender.MAIL.From=web@www.wuset.com
 log4j.appender.MAIL.SMTPHost=www.wusetu.com
 log4j.appender.MAIL.Subject=Log4J Message
 
log4j.appender.MAIL.To=web@www.wusetu.com
 log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
 log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

 # 用于数据库
 log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
 log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
 log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
 log4j.appender.DATABASE.user=root
 log4j.appender.DATABASE.password=
 log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
 log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
 log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n


 log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
 log4j.appender.A1.File=SampleMessages.log4j
 log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
 log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout

 #自定义Appender

 log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender

 log4j.appender.im.host = mail.cybercorlin.net
 log4j.appender.im.username = username
 log4j.appender.im.password = password
 log4j.appender.im.recipient =
corlin@cybercorlin.net

 log4j.appender.im.layout=org.apache.log4j.PatternLayout
 log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

Thursday, February 19, 2009

JUnit4 TestRunner

1. org.junit.runners.AllTests
Runner for use with JUnit 3.8.x-style AllTests classes (those that only implement a static suite() method). For example:

@RunWith(AllTests.class)
public class ProductTests {
public static junit.framework.Test suite() {
...
}
}
2. org.junit.runners.Enclosed
Enclosed runner (which runs all static inner classes)
import org.junit.runners.*;
import org.junit.runner.*;
import org.junit.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

@RunWith(value=Enclosed.class) //Iam using Enclosed runner
public class J41Innerclass{

public static class publicstaticInnerclass //Inner class
{
@Test
public void tstasserttht() //Test method in inner class
{
int i=3;
System.out.println("Inside test assertThat method");
assertThat(i,is(4));
}
}
@Test
public void outermethod()
{
assertEquals(1,1);
}
}
3. org.junit.runners.Parameterized
The custom runner Parameterized implements parameterized tests. When running a parameterized test class, instances are created for the cross-product of the test methods and the test data elements.

For example, to test a Fibonacci function, write:
@RunWith(Parameterized.class)
public class FibonacciTest {
@Parameters
public static Collection data() {
return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 },
{ 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } });
}

private int fInput;
private int fExpected;

public FibonacciTest(int input, int expected) {
fInput= input;
fExpected= expected;
}

@Test public void test() {
assertEquals(fExpected, Fibonacci.compute(fInput));
}
}

Each instance of FibonacciTest will be constructed using the two-argument constructor and the data values in the @Parameters method.

4. org.junit.runners.Suite
Using Suite as a runner allows you to manually build a suite containing tests from many classes. It is the JUnit 4 equivalent of the JUnit 3.8.x static Test suite() method. To use it, annotate a class with @RunWith(Suite.class) and @SuiteClasses(TestClass1.class, ...). When you run this class, it will run all the tests in all the suite classes.

Tuesday, February 17, 2009

JUnit4 introduction

junit-4-in-60-second

JUnit 4 使用 Java 5 中的注解(annotation),以下是JUnit 4 常用的几个 annotation 介绍
@Before:初始化方法
@After:释放资源
@Test:测试方法,在这里可以测试期望异常和超时时间
@Ignore:忽略的测试方法
@BeforeClass:针对所有测试,只执行一次,且必须为static void
@AfterClass:针对所有测试,只执行一次,且必须为static void

一个JUnit 4 的单元测试用例执行顺序为:
@BeforeClass –> @Before –> @Test –> @After –> @AfterClass

每一个测试方法的调用顺序为:
@Before –> @Test –> @After

写个例子测试一下,测试一下
import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

public class JUnit4Test {
@Before
public void before() {
System.out.println("@Before");
}

@Test
public void test() {
System.out.println("@Test");
assertEquals(5 + 5, 10);
}

@Ignore
@Test
public void testIgnore() {
System.out.println("@Ignore");
}

@Test(timeout = 50)
public void testTimeout() {
System.out.println("@Test(timeout = 50)");
assertEquals(5 + 5, 10);
}

@Test(expected = ArithmeticException.class)
public void testExpected() {
System.out.println("@Test(expected = Exception.class)");
throw new ArithmeticException();
}

@After
public void after() {
System.out.println("@After");
}

@BeforeClass
public static void beforeClass() {
System.out.println("@BeforeClass");
};

@AfterClass
public static void afterClass() {
System.out.println("@AfterClass");
};
};

输出结果
@BeforeClass
@Before
@Test(timeout = 50)
@After
@Before
@Test(expected = Exception.class)
@After
@Before
@Test
@After
@AfterClass

Monday, February 16, 2009

jQuery入门【转】

1、关于页面元素的引用
  通过jquery的$()引用元素包括通过id、class、元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用dom定义的方法。

2、jQuery对象与dom对象的转换
  只有jquery对象才能使用jquery定义的方法。注意dom对象和jquery对象是有区别的,调用方法时要注意操作的是dom对象还是jquery对象。
  普通的dom对象一般可以通过$()转换成jquery对象。
  如:$(document.getElementById("msg"))则为jquery对象,可以使用jquery的方法。
由于jquery对象本身是一个集合。所以如果jquery对象要转换为dom对象则必须取出其中的某一项,一般可通过索引取出。
如:$("#msg")[0],$("div").eq(1)[0],$("div").get()[1],$("td")[5]这些都是dom对象,可以使用dom中的方法,但不能再使用Jquery的方法。
以下几种写法都是正确的:
 程序代码
$("#msg").html();
$("#msg")[0].innerHTML;
$("#msg").eq(0)[0].innerHTML;
$("#msg").get(0).innerHTML;


3、如何获取jQuery集合的某一项
  对于获取的元素集合,获取其中的某一项(通过索引指定)可以使用eq或get(n)方法或者索引号获取,要注意,eq返回的是jquery对象,而get(n)和索引返回的是dom元素对象。对于jquery对象只能使用jquery的方法,而dom对象只能使用dom的方法,如要获取第三个
元素的内容。有如下两种方法:
 程序代码
$("div").eq(2).html();               //调用jquery对象的方法
$("div").get(2).innerHTML;       //调用dom的方法属性


4、同一函数实现set和get
Jquery中的很多方法都是如此,主要包括如下几个:
$("#msg").html();               //返回id为msg的元素节点的html内容。
$("#msg").html("new content");       
//将“new content” 作为html串写入id为msg的元素节点内容中,页面显示粗体的new content

$("#msg").text();               //返回id为msg的元素节点的文本内容。
$("#msg").text("new content");       
//将“new content” 作为普通文本串写入id为msg的元素节点内容中,页面显示new content

$("#msg").height();               //返回id为msg的元素的高度
$("#msg").height("300");       //将id为msg的元素的高度设为300
$("#msg").width();               //返回id为msg的元素的宽度
$("#msg").width("300");       //将id为msg的元素的宽度设为300

$("input").val(");       //返回表单输入框的value值
$("input").val("test");       //将表单输入框的value值设为test

$("#msg").click();       //触发id为msg的元素的单击事件
$("#msg").click(fn);       //为id为msg的元素单击事件添加函数
同样blur,focus,select,submit事件都可以有着两种调用方法

5、集合处理功能
  对于jquery返回的集合内容无需我们自己循环遍历并对每个对象分别做处理,jquery已经为我们提供的很方便的方法进行集合的处理。
包括两种形式:
 程序代码
$("p").each(function(i){this.style.color=['#f00','#0f0','#00f'][i]})       
//为索引分别为0,1,2的p元素分别设定不同的字体颜色。

$("tr").each(function(i){this.style.backgroundColor=['#ccc','#fff'][i%2]})       
//实现表格的隔行换色效果

$("p").click(function(){alert($(this).html())})              
//为每个p元素增加了click事件,单击某个p元素则弹出其内容


6、扩展我们需要的功能
 程序代码
$.extend({
       min: function(a, b){return a <>
       max: function(a, b){return a > b?a:b; } 
});       //为jquery扩展了min,max两个方法

使用扩展的方法(通过“$.方法名”调用):
alert("a=10,b=20,max="+$.max(10,20)+",min="+$.min(10,20));

7、支持方法的连写
所谓连写,即可以对一个jquery对象连续调用各种不同的方法。
例如:
$("p").click(function(){alert($(this).html())})
.mouseover(function(){alert('mouse over event')})
.each(function(i){this.style.color=['#f00','#0f0','#00f'][i]});

8、操作元素的样式
主要包括以下几种方式:
$("#msg").css("background");               //返回元素的背景颜色
$("#msg").css("background","#ccc")       //设定元素背景为灰色
$("#msg").height(300); $("#msg").width("200");       //设定宽高
$("#msg").css({ color: "red", background: "blue" });//以名值对的形式设定样式
$("#msg").addClass("select");       //为元素增加名称为select的class
$("#msg").removeClass("select");       //删除元素名称为select的class
$("#msg").toggleClass("select");       //如果存在(不存在)就删除(添加)名称为select的class

9、完善的事件处理功能
Jquery已经为我们提供了各种事件处理方法,我们无需在html元素上直接写事件,而可以直接为通过jquery获取的对象添加事件。
如:
$("#msg").click(function(){alert("good")})       //为元素添加了单击事件
$("p").click(function(i){this.style.color=['#f00','#0f0','#00f'][i]})
//为三个不同的p元素单击事件分别设定不同的处理
jQuery中几个自定义的事件:
(1)hover(fn1,fn2):一个模仿悬停事件(鼠标移动到一个对象上面及移出这个对象)的方法。当鼠标移动到一个匹配的元素上面时,会触发指定的第一个函数。当鼠标移出这个元素时,会触发指定的第二个函数。
//当鼠标放在表格的某行上时将class置为over,离开时置为out。
$("tr").hover(function(){
$(this).addClass("over");
},
       function(){
       $(this).addClass("out"); 
});
(2)ready(fn):当DOM载入就绪可以查询及操纵时绑定一个要执行的函数。
$(document).ready(function(){alert("Load Success")})
//页面加载完毕提示“Load Success”,相当于onload事件。与$(fn)等价
(3)toggle(evenFn,oddFn): 每次点击时切换要调用的函数。如果点击了一个匹配的元素,则触发指定的第一个函数,当再次点击同一元素时,则触发指定的第二个函数。随后的每次点击都重复对这两个函数的轮番调用。
       //每次点击时轮换添加和删除名为selected的class。
       $("p").toggle(function(){
               $(this).addClass("selected");   
       },function(){
               $(this).removeClass("selected"); 
       });
(4)trigger(eventtype): 在每一个匹配的元素上触发某类事件。
例如:
       $("p").trigger("click");               //触发所有p元素的click事件
(5)bind(eventtype,fn),unbind(eventtype): 事件的绑定与反绑定
从每一个匹配的元素中(添加)删除绑定的事件。
例如:
$("p").bind("click", function(){alert($(this).text());});       //为每个p元素添加单击事件
$("p").unbind();       //删除所有p元素上的所有事件
$("p").unbind("click")       //删除所有p元素上的单击事件

10、几个实用特效功能
其中toggle()和slidetoggle()方法提供了状态切换功能。
如toggle()方法包括了hide()和show()方法。
slideToggle()方法包括了slideDown()和slideUp方法。

11、几个有用的jQuery方法
$.browser.浏览器类型:检测浏览器类型。有效参数:safari, opera, msie, mozilla。如检测是否ie:$.browser.isie,是ie浏览器则返回true。
$.each(obj, fn):通用的迭代函数。可用于近似地迭代对象和数组(代替循环)。
$.each( [0,1,2], function(i, n){ alert( "Item #" + i + ": " + n ); }); 
等价于:
var tempArr=[0,1,2];
for(var i=0;i
       alert("Item #"+i+": "+tempArr[i]);
}
也可以处理json数据,如
$.each( { name: "John", lang: "JS" }, function(i, n){ alert( "Name: " + i + ", Value: " + n ); });
结果为:
Name:name, Value:John
Name:lang, Value:JS
$.extend(target,prop1,propN):用一个或多个其他对象来扩展一个对象,返回这个被扩展的对象。这是jquery实现的继承方式。
如:
$.extend(settings, options);       
//合并settings和options,并将合并结果返回settings中,相当于options继承setting并将继承结果保存在setting中。
var settings = $.extend({}, defaults, options);
//合并defaults和options,并将合并结果返回到setting中而不覆盖default内容。
可以有多个参数(合并多项并返回)
$.map(array, fn):数组映射。把一个数组中的项目(处理转换后)保存到到另一个新数组中,并返回生成的新数组。
如:
var tempArr=$.map( [0,1,2], function(i){ return i + 4; });
tempArr内容为:[4,5,6]
var tempArr=$.map( [0,1,2], function(i){ return i > 0 ? i + 1 : null; });
tempArr内容为:[2,3]
$.merge(arr1,arr2):合并两个数组并删除其中重复的项目。
如:$.merge( [0,1,2], [2,3,4] )       //返回[0,1,2,3,4]
$.trim(str):删除字符串两端的空白字符。 
如:$.trim("   hello, how are you?   ");         //返回"hello,how are you? "

12、解决自定义方法或其他类库与jQuery的冲突
  很多时候我们自己定义了$(id)方法来获取一个元素,或者其他的一些js类库如prototype也都定义了$方法,如果同时把这些内容放在一起就会引起变量方法定义冲突,Jquery对此专门提供了方法用于解决此问题。
  使用jquery中的jQuery.noConflict();方法即可把变量$的控制权让渡给第一个实现它的那个库或之前自定义的$方法。之后应用Jquery的时候只要将所有的$换成jQuery即可,如原来引用对象方法$("#msg")改为jQuery("#msg")。
如:
jQuery.noConflict(); 
// 开始使用jQuery
jQuery("div   p").hide();
// 使用其他库的 $() 
$("content").style.display = 'none';

Sunday, February 8, 2009

small issue when creating Java project from existing source


we should use the target folder name as the project name when creating a Java project from existing source, see picture on the left:

Wednesday, January 7, 2009

SQL SELECT TOP N equivalent in ORACLE and MySQL

SQL Server:
SELECT TOP 10 product, descr, email
FROM products

ORACLE:
SELECT product, descr, email
FROM products
WHERE ROWNUM <= 10

MySQL:
SELECT product, descr, email
FROM products
LIMIT 10

Tuesday, January 6, 2009

cvs资源列表的head、branches、version、dates

其中的HEAD表示主分支(主干)、Branches是分支的集合、Versions是标签的集合、Dates是用时间做标签的集合。 

CVS 只能对文件进行版本控制,不能对目录进行版本控制,因此CVS 没有任何关于文件“移动”(move) 操作的概念
支持分支(branch)和基线(tag),通过分支与合并,可以有效支持大项目的并行开发模式;通过基线管理,可以准确标识一组文件的版本,有效进行软件发布管理和必要时的历史回溯

当你第一次增加一个文件到 repository 的时 候,它会有一个初始 revision 是 1.1,以后每次提交,就会增加到 1.2,1.3... Branch : Branch 是一棵正常生长的代码树中的枝杈。开始的时候,任何一个 module 都有一 个主枝。一个 branch 最终要么被合并到主干中去,要么被结束。branch 通常用来debug,如果这个 bug 被 fix 了,修改 bug 的代码应该被合并到主枝上去。一个 branch 也可能经历多次与主枝的合并。 Tag 标签: Tag 用来进行标识必要的信息,在一个开发的特定期对一个文件集给定的符号名。 当您进行一次公开发布之前,您有必要对主枝标示"release 1.0"。 这样您以后就可 以随时回到这个版本

补充:项目一般都是在head里,用于版本控制,branches里有无都不是很重要,我做过的项目CVS内容都是在HEAD里,其他关联到的不大!

Monday, January 5, 2009

WSDL starter

一个WSDL中,definition是整个文档的根元素,一个文档中可能存在多个Service元素,service是服务的入口点。 Service 中可能有多个port,每个port对应一个PortType,PortType可能对应一组operation

总体来说,WSDL有两部分功能,客户端Stub(存根)和服务器端Skeleton()的生成。
其中客户端Stub负责根据用户参数打包成SOAP消息;服务器端Skeleton的生成是可选的,负责具体的类调用的外包
先说第一部分,WSDL2JAVA处理WSDL生成前端Stub的过程。


通常WSDL文件包含:
1、类型:定义复合数据类型
2、消息:由类型组合成消息(可以作为下面操作的参数)(疑问?:分为类型和消息,直接放在一个组为啥不行)
3、操作:其中定义可以调用的操作,每个操作的参数。操作的集合对外呈现一个接口
4、绑定:定义每个操作具体的调用方式,数据的编码方式()
5、服务:对外呈现服务,可以包含多个绑定
6、端口:远程地址
其中,1,2,3被称为逻辑的描述; 4,5,6用来描述具体的服务地址和参数编码方式

1、类型定义的转换
把WSDL中类型的定义部分,转化成对应JAVA类。
public class Phone implements java.io.Serializable {...}
WSDL2JAVA生成了一个新的类和WSDL中定义的类型对应,并且为每个成员定义get和set函数,还把每个字段的首字母大写。

2、接口
生成一个接口,对外呈现描述的各个接口。message代表输入输出参数,生成的代码将把message的各个部分罗列在参数表中。
public interface AddressBook extends java.rmi.Remote {
public void addEntry(String name, Address address) throws java.rmi.RemoteException;
}

3、绑定
从其父类可以看出,他继承自org.apache.axis.client.Stub和具体实现类。
在stub中将把方法调用转化为SOAP调用,另一面它也继承了具体类的所有接口。
public class AddressBookSOAPBindingStub extends org.apache.axis.client.Stub
implements AddressBook {
public AddressBookSOAPBindingStub() throws org.apache.axis.AxisFault
{...}

4、服务
将形成一个接口:
public interface AddressBookService extends javax.xml.rpc.Service {
public String getAddressBookAddress();
public AddressBook getAddressBook() throws javax.xml.rpc.ServiceException;
public AddressBook getAddressBook(URL portAddress) throws 

javax.xml.rpc.ServiceException;
}
还会产生一个Locator实现上面的接口:
public class AddressBookServiceLocator extends org.apache.axis.client.Service
implements AddressBookService {
...
}

下面是一个具体的调用过程:

public static void main(String [] args) throws Exception {
// 生成一个locator
AddressBookService service = new AddressBookServiceLocator();

// 生成一个具体的生成Service的类
AddressBook port = service.getAddressBook();

// 现在可以调用了
Address address = new Address(...);
port.addEntry("Russell Butek", address);
}

使用Eclipse的wsdl2java工具

一、用Eclipse调用Axis的wsdl2java
1.在eclipse里面新建一个项目或已有的项目;
2.导入
    activation.jar
    axis.jar
    commons-discovery.jar
    commons-logging-1.0.3.jar
    jaxrpc.jar
    saaj.jar
    wsdl4j-1.5.2.jar
   包

3右击你的工程-Run As-Run...-右击New,新建 new configuration ,将Include libraries when searching for a main class勾上,再点search,输入wsdl2java,再Arguments里把要生成的web service URI或wsdl文件写进去,最后点run。

二、利用myeclipse建立WebServiceClient
1.在Web工程上右键-->new-->Other-->MyEclipse下的WebService下的Web Service Client
2.在打开窗口上的Project处选择要放入哪个工程,然后选择WSDL URL,把WebService地址填上.也可以选择本地wsdl文件

axis的WSDL2java工具初识

1. 先下载axis, 下载地址http://ws.apache.org/axis/, 其中包含一个叫WSDL2java的工具,这个工具就用于将wsdl生成java程序.
3. Download JavaMail API 1.4.1
D:\download\Java\Axis\axis-bin-1_4>java -cp .;.\lib\axis.jar;.\lib\jaxrpc.jar;.\lib\saaj.jar;.\lib\commons-logging-1.0.4.jar;.\lib\commons-discovery-0.2.jar;.\lib\wsdl4j-1.5.1.jar;.\lib\activation.jar;.\lib\mail.jar org.apache.axis.wsdl.WSDL2Java http://21.23.229.11:8000/webService/hello.asmx?wsdl

------------------------
Axis2是常用的一种SOAP engine,但是它提供的wsdl2java的命令行工具的说明比较简单,没有具体的例子。下面举出几个例子:

从最简单的开始 ,-uri 指定wsdl文件
> WSDL2Java -uri currencyConvert.wsdl

-d 使用不同的data binding方法
> WSDL2Java -uri currencyConvert.wsdl -d xmlbeans

-a 生成异步的方法
> WSDL2Java -uri currencyConvert.wsdl -a

-t 生成测试case
> WSDL2Java -uri currencyConvert.wsdl -t ...

稍微复杂一些的,-p可以指定生成的package,-o指定生成的路径,-ss生成服务端代码
wsdl2java -uri ../wsdl/currencyConvert.wsdl -o ../gen_src  -ss -sd -g -p foo.bat

再复杂一些,-ns2p 将namespace进行替换,多个中间用逗号隔开
wsdl2java -uri ../wsdl/currencyConvert.wsdl -o ../wsdl/gen_src  -ss -sd -g -p com.foo.bar -ns2p "http://www.xxx.yyy.com/zzz/v1.0"=com.foo.bar,"http://www.xxx.yyy.com/ddd/v1.1"=com.foo.bar.goo