甜咖啡

我的IT空间

2010年6月29日

Java遍历Map
public static void main(String[] args) {

  Map<String, String> map = new HashMap<String, String>();
  map.put("1", "value1");
  map.put("2", "value2");
  map.put("3", "value3");
  
  //第一种:普遍使用,二次取值
  System.out.println("通过Map.keySet遍历key和value:");
  for (String key : map.keySet()) {
   System.out.println("key= "+ key + " and value= " + map.get(key));
  }
  
  //第二种
  System.out.println("通过Map.entrySet使用iterator遍历key和value:");
  Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
  while (it.hasNext()) {
   Map.Entry<String, String> entry = it.next();
   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
  }
  
  //第三种:推荐,尤其是容量大时
  System.out.println("通过Map.entrySet遍历key和value");
  for (Map.Entry<String, String> entry : map.entrySet()) {
   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
  }

  //第四种
  System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
  for (String v : map.values()) {
   System.out.println("value= " + v);
  }
 }

Java遍历Set

对 set 的遍历  
1.迭代遍历:  
Set<String> set = new HashSet<String>();  
Iterator<String> it = set.iterator();  
while (it.hasNext()) {  
  String str = it.next();  
  System.out.println(str);  
}  
  
2.for循环遍历:  
for (String str : set) {  
      System.out.println(str);  
}  
  
  
优点还体现在泛型 假如 set中存放的是Object  
  
Set<Object> set = new HashSet<Object>();  
for循环遍历:  
for (Object obj: set) {  
      if(obj instanceof Integer){  
                int aa= (Integer)obj;  
             }else if(obj instanceof String){  
               String aa = (String)obj  
             }  
              ........  
}  

当一个人找不到出路的时候,最好的办法就是将当前能做好的事情做到极致,做到无人能及。
posted @ 2013-04-03 12:12 甜咖啡 阅读(17185) | 评论 (0)编辑 收藏

今天在研究了一下关于ORACLE的导入导出的功能,周五快要下班的时候给同事新建一个表空间,将同一个数据库中的某个用户下的表导入新的表空间上,建好表空间和用户后,直接用 exp ,imp 来导入数据到新的表空间,查是发现后来导入的数据还在原来的表空间上,(周五那天的我是用工具编辑DMP文件,修改里的表空间名后导入的),后来想起来了eygle的书上写了关于这个的问题,于是今天就来试验了一下。

第一种:修改用户的一些权限。

首先使用sytem帐户登陆

--创建新表空间的用户

SQL> create user pangzi identified by pangzi default tablespace pangzi temporary tablespace temp;

用户已创建。

--授给新用户一般的权限

SQL> grant export full database to pangzi;

授权成功。

SQL> grant import full database to pangzi;

授权成功。

SQL> grant connect,resource to pangzi;

授权成功。

SQL> grant create procedure to pangzi;

授权成功。

SQL> grant create job to pangzi;

授权成功。

SQL> grant create view to pangzi;

授权成功。

SQL> grant create synonym to pangzi;

授权成功。

--从这里开始将是增加的,为了使导入的数据,不放在原来的表空间上

SQL> grant dba to pangzi;

--收回用户的umlimited tablespace权限

SQL> revoke unlimited tablespace from pangzi;

--设置新创建的用户可使用syb表空间的大小0(原数据所在的表空间为syb)

SQL> alter user pangzi quota 0 on syb;

--设置新创建的用户可使用pangzi表空间的大小不限制

 

SQL> alter user pangzi quota unlimited on pangzi;

--收回DBA权限

SQL> revoke dba from pangzi;

执行导入数据

C:\Users\dyspangzi>imp pangzi/pangzi@testdev file=syb.dmp full=y

 

Import: Release 10.2.0.3.0 - Production on 星期六 4月 21 17:48:54 2012

 

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

 

 

连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production

With the Partitioning, OLAP and Data Mining options

 

经由常规路径由 EXPORT:V10.02.01 创建的导出文件

 

警告: 这些对象由 SYB 导出, 而不是当前用户

 

已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入

. 正在将 SYB 的对象导入到 PANGZI

. . 正在导入表                     "ALL_SALES"导入了         360 行

. . 正在导入表                       "COUPONS"导入了           6 行

. . 正在导入表                     "CUSTOMERS"导入了           5 行

. .中间部分内容省略,都是导入的信息

 

 

. . 正在导入表                      "REG_EXPS"导入了           1 行

. . 正在导入表                 "SALARY_GRADES"导入了           4 行

即将启用约束条件...

成功终止导入, 没有出现警告。

导入成功,我们看导的表已经在新的表空间中了

SQL> show user
USER 为 "PANGZI"
SQL> select table_name,tablespace_name from user_tables;

TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
DYSPANGZI                      PANGZI
CUSTOMERS                      PANGZI
PRODUCT_TYPES                  PANGZI
PRODUCTS                       PANGZI
PURCHASES                      PANGZI
EMPLOYEES                      PANGZI
SALARY_GRADES                  PANGZI
PURCHASES_WITH_TIMESTAMP       PANGZI
PURCHASES_TIMESTAMP_WITH_TZ    PANGZI
PURCHASES_WITH_LOCAL_TZ        PANGZI
COUPONS                        PANGZI

TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
PROMOTIONS                     PANGZI
ORDER_STATUS                   PANGZI
PRODUCT_CHANGES                PANGZI
MORE_PRODUCTS                  PANGZI
MORE_EMPLOYEES                 PANGZI
DIVISIONS                      PANGZI
JOBS                           PANGZI
EMPLOYEES2                     PANGZI
ALL_SALES                      PANGZI
PRODUCT_PRICE_AUDIT            PANGZI
REG_EXPS                       PANGZI

已选择22行。                      

第二种:使用EXPDP和IMPDP来导入和导出

       使用expdp来导出,首先要为一个参数来指定一个路径——directory,expdp是在服务器端工作,导出的文件需要放在本地目录,这个参数就是保存导出文件的位置。这个可以自己创建,也可以是默认的,我自己创建了一个,名字是expdir

SQL> CREATE OR REPLACE DIRECTORY expdir AS '/var/backup';

 

目录已创建。

 

SQL> select * from dba_directories;

 

OWNER        DIRECTORY_NAME      DIRECTORY_PATH

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

SYS             ADMIN_DIR            /ade/aime_10.2_lnx_push/oracle/md/admin

 

SYS             DATA_PUMP_DIR       /usr/app/oracle/product/10.2.0/db_1/rdbms/log/

 

SYS             WORK_DIR             /ade/aime_10.2_lnx_push/oracle/work

 

SYS             EXPDIR                /var/backup

--给用户授予读写权限

 

 

SQL> grant read,write on directory expdir to syb;

开始导出数据

[oracle@dyspangzi ~]$ expdp dumpfile=syb.dmp directory=expdir;

Export: Release 10.2.0.1.0 - Production on Saturday, 21 April, 2012 18:06:46

Copyright (c) 2003, 2005, Oracle.  All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
Starting "SYB"."SYS_EXPORT_SCHEMA_01":  dumpfile=syb.dmp directory=expdir
Estimate in progress using BLOCKS method...
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 1.375 MB
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/PACKAGE/PACKAGE_SPEC
Processing object type SCHEMA_EXPORT/FUNCTION/FUNCTION
Processing object type SCHEMA_EXPORT/PROCEDURE/PROCEDURE
Processing object type SCHEMA_EXPORT/PACKAGE/COMPILE_PACKAGE/PACKAGE_SPEC/ALTER_PACKAGE_SPEC
Processing object type SCHEMA_EXPORT/FUNCTION/ALTER_FUNCTION
Processing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDURE
Processing object type SCHEMA_EXPORT/PACKAGE/PACKAGE_BODY
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/TRIGGER
. . exported "SYB"."DYSPANGZI"                           48.50 KB     659 rows
. . exported "SYB"."ALL_SALES"                           13.68 KB     360 rows
       中间导出信息省略

.  . exported "SYB"."REG_EXPS"                            5.437 KB       1 rows
. . exported "SYB"."SALARY_GRADES"                       5.710 KB       4 rows
. . exported "SYB"."PRODUCT_PRICE_AUDIT"                     0 KB       0 rows
Master table "SYB"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYB.SYS_EXPORT_SCHEMA_01 is:
  /var/backup/syb.dmp
Job "SYB"."SYS_EXPORT_SCHEMA_01" successfully completed at 18:07:11

 

导出成功后查看一下刚才创建目录里边的内容

[root@dyspangzi var]# cd backup
[root@dyspangzi backup]# ls -l
总计 720
-rw-r--r-- 1 oracle oinstall   3472 04-21 18:07 export.log
-rw-r----- 1 oracle oinstall 729088 04-21 18:07 syb.dmp

多了两个文件,一个是日志文件一个是导出的数据文件,在导入的时候需要这两个文件。下面开始导入。

===================================================================================

出现了第一个错误

[oracle@dyspangzi ~]$ impdp pangzi/pangzi dumpfile=syb.dmp directory=expdir remap_tablespace=syb:pangzi

Import: Release 10.2.0.1.0 - Production on Saturday, 21 April, 2012 18:45:35

Copyright (c) 2003, 2005, Oracle.  All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
ORA-39002: invalid operation
ORA-39070: Unable to open the log file.
ORA-39087: directory name EXPDIR is invalid

出现了错误,后来发现这个是因为新用户pangzi没有对目录的读写权限造成的,于是加上权限

SQL> grant read,write on directory expdir to pangzi;

授权成功。

==================================================================================

出现了第二个错误

[oracle@dyspangzi ~]$ impdp pangzi/pangzi dumpfile=syb.dmp directory=expdir remap_tablespace=syb:pangzi

Import: Release 10.2.0.1.0 - Production on Saturday, 21 April, 2012 18:47:38

Copyright (c) 2003, 2005, Oracle.  All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
ORA-31655: no data or metadata objects selected for job
ORA-39154: Objects from foreign schemas have been removed from import
Master table "PANGZI"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "PANGZI"."SYS_IMPORT_FULL_01":  pangzi/******** dumpfile=syb.dmp directory=expdir remap_tablespace=syb:pangzi
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Job "PANGZI"."SYS_IMPORT_FULL_01" successfully completed at 18:47:41

这个是由于原来的用户和现在的不一样了,加上这个参数就好了  remap_schema=syb:pangzi

=====================================================================================================

下面是没有任何错误的导入了

[oracle@dyspangzi ~]$ impdp pangzi/pangzi dumpfile=syb.dmp directory=expdir remap_schema=syb:pangzi remap_tablespace=syb:pangzi

Import: Release 10.2.0.1.0 - Production on Saturday, 21 April, 2012 18:49:24

Copyright (c) 2003, 2005, Oracle.  All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
Master table "PANGZI"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "PANGZI"."SYS_IMPORT_FULL_01":  pangzi/******** dumpfile=syb.dmp directory=expdir remap_schema=syb:pangzi remap_tablespace=syb:pangzi
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "PANGZI"."DYSPANGZI"                        48.50 KB     659 rows
. . imported "PANGZI"."ALL_SALES"                        13.68 KB     360 rows
     中间部分导入信息省略

. . imported "PANGZI"."PURCHASES_WITH_TIMESTAMP"         5.609 KB       1 rows
. . imported "PANGZI"."REG_EXPS"                         5.437 KB       1 rows
. . imported "PANGZI"."SALARY_GRADES"                    5.710 KB       4 rows
. . imported "PANGZI"."PRODUCT_PRICE_AUDIT"                  0 KB       0 rows
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/PACKAGE/PACKAGE_SPEC
Processing object type SCHEMA_EXPORT/FUNCTION/FUNCTION
Processing object type SCHEMA_EXPORT/PROCEDURE/PROCEDURE
Processing object type SCHEMA_EXPORT/PACKAGE/COMPILE_PACKAGE/PACKAGE_SPEC/ALTER_PACKAGE_SPEC
Processing object type SCHEMA_EXPORT/FUNCTION/ALTER_FUNCTION
Processing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDURE
Processing object type SCHEMA_EXPORT/PACKAGE/PACKAGE_BODY
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/TRIGGER
Job "PANGZI"."SYS_IMPORT_FULL_01" successfully completed at 18:49:37

成功导入!!!!

查看默认的表空间

SQL> select table_name,tablespace_name from user_tables;

TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
DYSPANGZI                      PANGZI
CUSTOMERS                      PANGZI
PRODUCT_TYPES                  PANGZI
PRODUCTS                       PANGZI
PURCHASES                      PANGZI
EMPLOYEES                      PANGZI
SALARY_GRADES                  PANGZI
PURCHASES_WITH_TIMESTAMP       PANGZI
PURCHASES_TIMESTAMP_WITH_TZ    PANGZI
PURCHASES_WITH_LOCAL_TZ        PANGZI
COUPONS                        PANGZI

TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
PROMOTIONS                     PANGZI
ORDER_STATUS                   PANGZI
PRODUCT_CHANGES                PANGZI
MORE_PRODUCTS                  PANGZI
MORE_EMPLOYEES                 PANGZI
DIVISIONS                      PANGZI
JOBS                           PANGZI
EMPLOYEES2                     PANGZI
ALL_SALES                      PANGZI
PRODUCT_PRICE_AUDIT            PANGZI
REG_EXPS                       PANGZI

已选择22行。

此表空间中没有索引,所以第一种方法也没有报错,如果出现有索引的第一种方法还得增加几步,等我明天找到周五那个数据再来再着做试验。

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

今天特意去公司找来了那天导的数据库,回来做实验。采用第一种方法不可行,虽然说可以使用IMP  加indexs参数来导出一些索引,但是导入的时候总有莫名其妙的错误,估计还是我没弄好,所以为了省事还是直接用第二种吧,方便,无错。

posted @ 2013-04-03 12:07 甜咖啡 阅读(963) | 评论 (0)编辑 收藏

1.在Oracle中可以用下面两种:

01: 
     create table newtable   as select * from oldtable;//用于复制前未创建新表newtable不存在的情况 
02: 
      insert into newtable   select * from oldtable;//已经创建了新表newtable 的情况

注意:第一种方式只是复制了表结构,但是主键什么的并没有复制进去,所以用的时候要小心在意。

2.如果想简单快速的复制表结构,而不需要oldtable里面的数据,可以用下面的语句:

    create table newtable   as  select * from oldtable where 1=2;(把数据过滤掉)

3.如过newtable 和oldtable的表结构不同,可以使用下面的方式:

 create table newtable  as select  s.c1,s.c2  from oldtable s;

 

4.如果想重新命名newtable的列名:

在oracle中:

 create table  newtable(id,name1) as select  s.c1,s.c2  from oldtable s;

或者

 create table  newtable as select  s.c1 ,s.c2  from oldtable s;

在mysql中恐怕只能用第二种方式了。

5.如果是只需要把一部分的oldtable中的数据添加到newtable中。可以这样:

 create table newtable   as (select * from oldtable where ...);//加where过滤条件

6.最常见的情况是id列新表中要用,并且和旧表中的不同,使用下面的语句就可以了(我们可以重新建一个sequence)

create table yang(id,name) as select hibernate_sequence.nextval,t.ename from emp t;

7.要注意,导出表的时候不能用select...into语句。

posted @ 2013-04-03 12:05 甜咖啡 阅读(390) | 评论 (0)编辑 收藏
方法1:
在shell中执行LANG=en 将语言设为英语就可以了.SSH下很多中文都不支持.
方法2:
在使用ssh远程控制redhat服务器时,中文显示为乱码。这个问题困扰了好久,后来发现修改i18n这个文件能够修正乱码。
 
方法如下:修改/etc/sysconfig/i18n文件,将其改成以下内容:
LANG="zh_CN.GB18030"
LANGUAGE="zh_CN.GB18030:zh_CN.GB2312:zh_CN"
SUPPORTED="zh_CN.UTF-8:zh_CN:zh:en_US.UTF-8:en_US:en"
SYSFONT="lat0-sun16"
重启机器,问题应该解决了。
方法3:
如果你用的是putty ,你只要在字符编码里选择utf-8就正常了
 
补充:这样做的后果是,在linux启动时,那些提示文字中文都变成了“?”符号。如果不习惯的话将ssh显示端改成英文吧。如下:
LANG=en_US  
posted @ 2013-04-03 12:05 甜咖啡 阅读(612) | 评论 (0)编辑 收藏
一、java实现DES加密算法
为了实现一对密钥对整个项目所有加密解密文件都适用的方法,采用先生成一对密钥.保存到xml文件中,以后获得私匙和公钥只需要从xml文件中取得就可以了.
/**
* 把成生的一对密钥保存到DesKey.xml文件中
*/
public static void saveDesKey(){     
    try {
        SecureRandom sr = new SecureRandom();
        //为我们选择的DES算法生成一个KeyGenerator对象
        KeyGenerator kg = KeyGenerator.getInstance ("DES" );
        kg.init (sr);
        FileOutputStream fos = new FileOutputStream("C:/DesKey.xml");
      ObjectOutputStream oos = new ObjectOutputStream(fos);
        //生成密钥
        Key key = kg.generateKey();
      oos.writeObject(key);
      oos.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
}




获取密钥方法如下:

/**

* 获得DES加密的密钥。在交易处理的过程中应该定时更
* 换密钥。需要JCE的支持,如果jdk版本低于1.4,则需要
* 安装jce-1_2_2才能正常使用。
* @return   Key 返回对称密钥
*/
    public static Key getKey() {
        Key kp = null;
        try {
              String fileName = "conf/DesKey.xml";
              InputStream is = DesUtil.class.getClassLoader()
                      .getResourceAsStream(fileName);
              ObjectInputStream oos = new ObjectInputStream(is);
              kp = (Key) oos.readObject();
              oos.close();
        } catch (Exception e) {
              e.printStackTrace();
        }
        return kp;
    }


文件采用DES算法加密文件

/**
* 文件file进行加密并保存目标文件destFile中

* @param file
*         
要加密的文件 如c:/test/srcFile.txt
* @param destFile
*         加密后存放的文件名 如c:/加密后文件
.txt
*/

public static void encrypt(String file, String destFile) throws Exception {

        Cipher cipher = Cipher.getInstance("DES");

        cipher.init(Cipher.ENCRYPT_MODE, getKey());

        InputStream is = new FileInputStream(file);

        OutputStream out = new FileOutputStream(dest);

        CipherInputStream cis = new CipherInputStream(is, cipher);

        byte[] buffer = new byte[1024];

        int r;

        while ((r = cis.read(buffer)) > 0) {

              out.write(buffer, 0, r);

        }

        cis.close();

        is.close();

        out.close();

    }


文件采用DES算法解密文件


/**
文件file进行加密并保存目标文件destFile中

* @param file
*         
已加密的文件 如c:/加密后文件.txt
* @param destFile
*         解密后存放的文件名 如c:/ test/解密后文件
.txt
*/

public static void decrypt(String file, String dest) throws Exception {
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, getKey());
        InputStream is = new FileInputStream(file);
        OutputStream out = new FileOutputStream(dest);
        CipherOutputStream cos = new CipherOutputStream(out, cipher);
        byte[] buffer = new byte[1024];
        int r;
        while ((r = is.read(buffer)) >= 0) {
              cos.write(buffer, 0, r);
        }
        cos.close();
        out.close();
        is.close();
    } 
posted @ 2013-03-29 15:58 甜咖啡 阅读(426) | 评论 (0)编辑 收藏
1、查看操作系统版本和内核版本

#uname –a

#more /etc/redhat-release


2、创建相关目录

/usr/src/redhat/SOURCES //存放源代码,补丁,图标等文件。


/usr/src/redhat/SPECS //存放用于管理rpm制作进程的spec文件。


/usr/src/redhat/BUILD //解压后的文件存放在这里。


/usr/src/redhat/RPMS //存放由rpmbuild制作好的二进制包。


/usr/src/redhat/SRPMS //存放由rpmbuild制作好的源码包。


#mkdir -p /usr/src/redhat/

#cd /usr/src/redhat/

#mkdir SOURCES SPECS BUILD RPMS SRPMS


3、下载Nginx源码包

下载源码包到SOURCES目录,不需要解压


#wget http://nginx.org/download/nginx-1.3.9.tar.gz


4、手工创建SPEC文件

由于spec文件是由spec语言编写的,请注意spec语言的语法。

#cd /usr/src/redhat/SPECS/

#cat < nginx.spec > EOC

  

Summary:  High Performance Web Server

  

Name:  nginx

  

Version:  1.3.9

  

Release:  el5

  

License:  GPL

  

Group:  Applications/Server

  

Source:  http://nginx.org/download/nginx-1.3.9.tar.gz

  

URL:  http://nginx.org/

  

Distribution:  Linux

  

Packager:  JingSheng <jingsheng1@staff.sina.com.cn>

  
  

%description

  

nginx  [engine x] is a HTTP and reverse proxy server

  

%prep

  

useradd  nginx -s /sbin/nologin

  

rm -rf  $RPM_BUILD_DIR/nginx-1.3.9

  

zcat  $RPM_SOURCE_DIR/nginx-1.3.9.tar.gz | tar -xvf -

  

%build

  

cd  $RPM_BUILD_DIR/nginx-1.3.9

  

./configure  --user=nginx --group=nginx --prefix=/usr/local/nginx/ --with-http_stub_status_module  --with-http_ssl_module

  

make

  

%install

  

cd  $RPM_BUILD_DIR/nginx-1.3.9

  

make  install

  

%preun

  

if [ -z  "`ps aux | grep nginx | grep -v grep`" ];then

  

killall  nginx >/dev/null

  

exit 0

  

fi

  

%files

  

/usr/local/nginx

  

#:以#开头是注释,rpm会忽略它。
Summary:简单描述软件。
Name :定义rpm的名称。
Version: 定义软件版本
Release: 发行版本
License: 定义许可证
Group: 软件分类
Source: 源码下载地址
URL: 源码相关网站
Distribution: 发行版系列
Packager: 打包人的信息

scription:软件详细描述,可多行
%prep :软件编译之前的处理,如解压。
%build :开始编译软件,如make
%install :开始安装软件,如make install
%files :指定哪些文件需要被打包,如/usr/local/nginx
%preun :定义卸载之前的动作,如杀掉进程。


5、开始RPM制作

在制作RPM包之前,需要安装必要的编译工具

#yum install -y gcc rpm-build pcre-devel

开始编译生成rpm包

# rpmbuild-bb nginx.spec


注意:如果安装生成报错,请将安装过的东东全部去除,再重新打包


# rpm –qpl *.rpm 查看rpm包含哪些

posted @ 2013-03-22 09:59 甜咖啡 阅读(604) | 评论 (0)编辑 收藏

最近一直在折腾linux,centos、redhat装了又装,到最后还是装了redhat。

以前多少接触过linux,但是都不深入(这次虽然也是皮毛,但是稍微知道了一些东东,现在就卖了),这次从零开始自己折腾linux,确实是被linux折腾了。linux跟windows确实有很多不同,有机会再继续介绍,这次先说一下使用Xmanager远程连接Redhat的经历。

Xmanager不多说了,是一款非常不错的管理工具。但是,如果要让Xmanager远程连接redhat,其实远程连接,主要还是想要做成跟windows的远程桌面一样的东西,图形界面方便啦!

只是这次配置Xmanager相当痛苦,按照网上各种资料对redhat进行配置,然后不停的reboot,但是,xmanager总是连不上。

这其中,修改的文件包括:

/usr/share/gdm/defaults.conf这个gdm的配置文件,主要是以下内容:

Enable=true

DisplaysPerHost=10

Port=177

还有/etc/inittab文件,主要是首先默认级别为5,这个文件貌似在安装的时候就已经默认为5了。id:5:initdefault:

然后最后一行的“x:5:respawn:/etc/X11/prefdm -nodaemon”调整为:

x:5:respawn:/usr/sbin/gdm

当然,还得改!

依然是/usr/share/gdm/defaults.conf,在[security]中调整以下的值:

AllowRoot=true

AllowRemoteRoot=true

AllowRemoteAutoLogin=true

如果开着防火墙,那还是要放开177端口,我暂时把防火墙关了。

reboot!reboot总是很重要的!

如果上述调整完成之后,依然无法连接,我就是这样的情况,连接不上啊!!!!

又随便找了几篇文章,也许跟hosts文件有关系哦!

打开/etc/hosts文件一看,空的!!!

在其中加上127.0.0.1 localhost,reboot,我总是喜欢reboot,这样比较干净!比较彻底!

在Xstart中配置好相应的参数,一定要在Commond中选择“GNOME”,这样再Run,Xbrowser将久违的redhat桌面打开了!

posted @ 2013-02-28 20:06 甜咖啡 阅读(331) | 评论 (0)编辑 收藏

今天开发的同事,和我说

SecureCRT连接到IDC服务器,老超时断开,影响工作了

研究了下。

因为客户端与服务器之间存在路由器,防火墙以及为了本身的安全性,在超过特定的时间后就会把空闲连接断开。或者是服务器端设置了断开空闲连接。
解决方法:
既然会断开超时的空闲连接,那么我们就应该让客户端与服务器之间的连接“忙”起来,方法有两个:
从服务器方面入手:
修改/etc/ssh/sshd_config配置文件 ClientAliveInterval 300(默认为0)
这个参数的是意思是每5分钟,服务器向客户端发一个消息,用于保持连接
service sshd reload 生效
从客户端入手:
上面是配置需要服务器权限,如果没有服务器权限则可以使用这个方法,其思想是:客户端向服务器发一个消息,用于保持连接
secureCRT在选项 终端 反空闲 中设置每隔多少秒发送一个字符串,或者是NO-OP协议包
putty:putty -> Connection -> Seconds between keepalives ( 0 to turn off ), 默认为0, 改为300


CentOS 5远程SSH连接超时设定
操作系统:CentOS 5.6    SSH版本:OpenSSH_4.3p2
网上很多文章都说,远程SSH连接的超时设定是在/etc/ssh/sshd_config里,使用ClientAliveInterval和ClientAliveCountMax选项,我原来也这么认为的,不过一直没配置过超时。
今天配置了一下,发现这个是不对的,正确的配置是在/etc/profile里,使用TMOUT选项进行控制,如TMOUT=300,设定超时间隔为300秒。
posted @ 2013-02-28 20:04 甜咖啡 阅读(4549) | 评论 (0)编辑 收藏

远程桌面服务使局域网 (LAN) 上的计算机可以连接到服务器(也称为远程计算机)并运行位于服务器上的程序。这可以只需要在1台机器上安装应用程序,其他机器共享使用。远程桌面连接使用远程桌面服务技术,使一台计算机可远程控制另一台计算机。

windows 远程终端服务是单用户的,也就是说通过远程登录到服务器时,服务器本地将黑屏。如何做到不管用本地登录还是远程登录,同一时刻容许多个用户操作服务器计算机。

首先:

要安装工具包,需要从微软下载(远程服务器管理工具 http://www.microsoft.com/downloads/zh-cn/details.aspx?displaylang=zh-cn&FamilyID=7d2f6ad7-656b-4313-a005-4e344e43997d ),安装升级包后,在控制面板--程序和功能--打开或关闭WINDOWS功能---远程服务器管理工具--角色管理工具--远程桌面服务工具,选中前面的选择框。
在开始--命令框输入cmd,在弹出的Dos界面输入netstat -na ,如果出现 3389 端口,就说明远程终端已经启动了。

然后:

1, 下载 补丁UniversalTermsrvPatch,功能就是去除单用户登陆的限制,允许多人多用户同时并行访问登录。
2, 根据你的系统运行对应的程序:
32位系统请运行 UniversalTermsrvPatch-x86.exe;
64位系统请运行 UniversalTermsrvPatch-x64.exe。
3, 需要管理员权限。右键点程序,选择以管理员身份运行。
4, 破解后需要重启生效。
5, 备份文件: \windows\system32\termsrv.dll.backup.(如果想还原设置 请将备份文件改名为termsrv.dll替换破解的文件即可)

远程桌面的其它可能的设置:
运行gpedit.msc打开组策略,计算机配置-管理模板-Windows组件-远程桌面服务-远程桌面会话主机-连接-“限制连接数量”,如果将状态设置为“禁用”或“未配置”,则在“组策略”级别上不强制限制连接的数量。

posted @ 2013-01-06 16:00 甜咖啡 阅读(494) | 评论 (0)编辑 收藏
在Windows 2003系统上的远程桌面实际上就是终端服务,虽然远程桌面最初在Windows XP上就已经存在,但由于Windows XP的远程桌面功能,只能提供一个用户使用计算机,因此使用率并不高。而Windows 2003提供的远程桌面功能则可供多用户同时使用,在其上可以运行程序、保存文件和使用网络资源,在很多方面可以像使用终端一样,并且在管理及配置方面比原来的终端服务更方便。要更好地发挥远程桌面的作用就要对远程桌面进行相应的配置。 www.2cto.com  
  组策略编译器(gpedit.msc)配置
 
使用组策略编译器配置用户远程连接数以及用户会话数,
1,“开始”—>“运行”输入gpedit.msc回车打开组策略编译器->“计算机配置”->“管理模板”->“windows组件”->“终端服务”,右侧鼠标右键选择“限制连接数”打开属性,选择“设置”—>选择“已启用”,  “TS    允许的最大连接数”填写你所需要的数量,例如:20。确定完成最大连接数限制设置。双击“会话”->选择“为断开的会话设置时间限制”右键选择属性-》“设置”->xuanze选择“已启用”-》“结束断开连接会话”填写合适的时间,五分钟为好。
 
  终端服务配置(Tscc.msc)的使用
 
  使用终端服务配置可以更改本地计算机上该连接的属性、添加新连接或设置服务器。打开“控制面板”—〉“管理工具”,单击“终端服务器配置”启动终端服务配置窗口。
 
  1 单击左边窗口的“连接”项,右边窗口即出现可选的RDP-TCP连接,右击“RDP-TCP”,选“属性”出现RDP-Tcp属性对话框,主要配置有:
  (1)连接数设置:可在“网卡”选项中更改。设置更多地连接数可使更多的用户同时登录服务器。默认最多同时两个用户连接,如果想要使3个以上的用户同时使用远程桌面功能,则必须安装终端服务,安装后就可以任意设定用户数制。  www.2cto.com  
  安装终端服务可通过Windows的“添加/删除程序”—〉“添加/删除Windows组件”中,选中“终端服务器”来添加,根据需要完成相应配置,完成终端服务安装,重启机器生效。
  由于每个用户连接远程桌面后最小占用12MB左右的内存,因此可根据服务器内存大小来设定用户数,一般用户数不要太多,以免影响性能。如256MB内存可设定用户数8个左右,512MB内存可设定20~30个。
  (2)调整颜色分辨率(颜色深度):在“客户端设置”项中。限制颜色深度可以增强连接性能,尤其是对于慢速链接,并且还可以减轻服务器负载。“远程桌面”连接的当前默认最大颜色深度设置为 16 位。
  选中“颜色深度最大值”,可修改限定的最大颜色深度为8、15、16或24位。若不选中,则使用登录的客户端颜色设置。
  (3)让客户自动登录:在“登录设置”选项卡上。这对普通应用非常方便,可加快登录速度,提高服务效率。
  要使用自动登录,需选中“总是使用下列登录信息”,在“用户名”中,键入允许自动登录到服务器的用户的名称,在“密码”和“确认密码”中,键入该用户的密码。 这样客户端连接时将不用再输入用户名和密码,而自动进入Windows 2003桌面(注意:若此后再有用户登录,那么原来的连接将被断开)。若输入不完整,则登录时还会要求输入用户名或密码。
  如要想更安全的使用服务器,则应选中“总是提示密码”以指定该用户在登录到服务器之前始终要被提示输入密码,从而限制客户端的自动登录。
  (4)对连接自动限制管理:单击“会话”项来设定。主要用来设定超时的限制,以便释放会话所占用的资源,“结束已断开的会话”和“空闲会话限制”的时间,一般应用设为5分钟较好。对安全性要求高的也可设定“活动会话限制”的时间。“达到会话限制或者连接被中断时”下的选项,最好选“结束会话”,这样连接所占的资源就会被释放。
  (5)设置加密级别:单击“常规”项,可指定在终端服务会话期间,对于客户端与远程计算机之间发送的所有数据是否强制加密级别。分四个级别:符合 FIPS(最高级别的加密)、高(加密数据经过强 128 位加密。)、客户端兼容(加密数据经过客户端支持的最大密钥强度加密)和低(从服务器发送到客户端的数据将不会被加密)。
  (6)启用终端客户音频:在“客户端设置”项下边,默认为禁用,以节约服务器资源。当用户少时 ,单击“音频映射”去掉被禁用的选项,使终端客户能使用多媒体设备。当然,客户端计算机也必须装有声卡。  www.2cto.com  
  如果有多个用户连接到相同的服务器,则会以同一个用户名登录。
 
  (7)启用驱动器映射;此项可方便终端与服务器磁盘间文件的相互传送。启用后本地驱动器将作为网络驱动器显示在终端中。
 
  同样还有打印机、剪贴板、com端口等也可设置映射。但每设置一个都要占用一定的系统资源;所以,一般用户最好禁用。
 
  (8)服务器的安全设置:在“权限”项,可选择组或用户,限制其对终端的配置权限。另外,由于只有Administrators 和 Remote Desktop Users 组的成员可以使用终端服务连接与远程计算机连接,所以可对不同用户分组管理,对于要求安全性高的,可利用NTFS分区设置不同用户的权限。
 
“服务器设置”—》“限制每个用户使用一个会话”右键选择属性,去除“限制每个用户使用一个会话”的勾选,确认完成设置。
  整个多用户的远程连接设置到此结束。
posted @ 2013-01-06 15:59 甜咖啡 阅读(506) | 评论 (0)编辑 收藏
在远程管理方面,Windows Server 2003系统一个最明显的进步就是增加了“远程桌面”功能。这样一来,从Windows 2000保留下来的终端服务似乎就显得有点多余了。然而情况并不是这样,因为在不安装“终端服务器”的前提下,“远程桌面”功能的可管理性比较有限。搭建终端服务器以后,对Windows 2000 Server和Windows Server 2003系统的远程管理操作将更加灵活。
在Windows Server 2003(SP1)中默认没有安装终端服务器组件,用户需要手动添加该组件。安装终端服务组件的步骤如下所述:

步骤/方法

  1. 第1步,在开始菜单中依次单击“控制面板”→“添加或删除程序”菜单项,打开“添加或删除程序”窗口。然后单击“添加/删除Windows组件”按钮,打开“Windows组件向导”对话框。在“组件”列表中选中“终端服务器”复选框,如图2008112107所示。
    图2008112107 选中“终端服务器”复选框
    在Windows Server 2003中安装终端服务器组件
  2. 第2步,打开“配置警告”对话框,提示用户关于IE安全配置方面的信息。因为配置终端服务器的目的主要是为了远程管理Windows Server 2003服务器,对于浏览Internet方面的要求并不高,因此直接单击“是”按钮。返回“Windows组件”对话框,选中“终端服务器授权”复选框,并单击“下一步”→“下一步”按钮即可,如图2008112108所示。
    图2008112108 “配置警告”对话框
    在Windows Server 2003中安装终端服务器组件
  3. 第3步,在打开的为应用程序兼容性选择默认权限对话框中列出两种安装模式,即“完整安全模式”和“宽松安全模式”。选择不同的模式会应用到Windows Server 2003系统的不同安全级别。选中“完整安全模式”单选框,并单击“下一步”按钮,如图2008112109所示。
    图2008112109 选中“完整安全模式”单选框
    在Windows Server 2003中安装终端服务器组件
  4. 第4步,打开指定终端服务器许可证服务器对话框,提示用户该终端服务器必须在120天内与Windows Server 2003终端服务器许可证服务器连接才能保证正常使用。由于在“Windows组件”对话框中选中了“终端服务器授权”复选框,则意味着这台Windows Server 2003终端服务器将同时作为许可证服务器。因此选中“使用下列许可证服务器”单选框,并在编辑框中输入这台服务器的名称或IP地址。设置完毕单击“下一步”按钮,如图2008112110所示。
    图2008112110 输入许可证服务器IP地址
    在Windows Server 2003中安装终端服务器组件
  5. 第5步,在打开的终端服务器授权模式对话框中,要求用户指定这台终端服务器使用的授权模式。选中“每设备授权模式”单选框,并单击“下一步”按钮,如图2008112111所示。
    图200811211 选中“每设备授权模式”单选框
    在Windows Server 2003中安装终端服务器组件
  6. 第6步,打开“终端服务器授权安装程序”对话框,要求用户选择安装许可证服务器数据库的路径。一般可以保持默认路径,并单击“下一步”按钮,如图2008112112所示。
    图2008112112 选择许可证服务器数据库路径
    在Windows Server 2003中安装终端服务器组件
  7. 第7步,Windows组件向导开始安装终端服务器和终端服务器授权组件,在安装过程中要求提供Windows Server 2003(SP1)系统的安装光盘或指定安装程序路径。完成安装后单击“完成”按钮关闭Windows组件向导,并按照提示重新启动计算机。
posted @ 2013-01-06 15:59 甜咖啡 阅读(325) | 评论 (0)编辑 收藏
package com;
  
  import java.io.FileInputStream;
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.List;
  
  import javax.xml.parsers.SAXParser;
  import javax.xml.parsers.SAXParserFactory;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.SAXException;
  import org.xml.sax.helpers.DefaultHandler;
  
  /**
   * SAX解析XML,事件驱动
   * 只有两种节点
   * Element Node元素节点
   * Text Node文本节点 
   */
  public class SaxResolveXML {
 
  public static void main(String[] args){
  try {
  SaxResolveXML saxResolveXML = new SaxResolveXML();
  InputStream inStream = new FileInputStream("D:\\xml.xml");
  List<Person> list = saxResolveXML.getList(inStream);
  for(Person person : list){
  System.out.println(person.toString());
  }
  } catch (Exception e) {
  e.printStackTrace();
  }
 
  }
 
  public List<Person> getList(InputStream inStream) throws Exception {
  SAXParserFactory factory = SAXParserFactory.newInstance();
  SAXParser parse = factory.newSAXParser();
  SaxResolve saxResolve = new SaxResolve();
  parse.parse(inStream, saxResolve);
  inStream.close();
  return saxResolve.getPerson();
  }
 
  private final class SaxResolve extends DefaultHandler {
 
  private List<Person> list = null;
  private Person person = null;
  private String tag = null;
 
  public List<Person> getPerson(){
  return list;
  }
 
  //开始文档事件
  public void startDocument() throws SAXException {
  //初始化
  list = new ArrayList<Person>();
  }
  
  //开始元素语法事件  参数说明:命名空间、不带命名空间的标签名、含有命名空间前缀的标签名、属性
  public void startElement(String uri, String localName, String qName,
  Attributes atts) throws SAXException {
  if("person".equals(qName)){
  person = new Person();
  person.setId(Integer.parseInt(atts.getValue(0)));
  }
  tag = qName;
  }
 
  //触发文本节点事件  参数说明:整个xml内容的字符串、当前读到文本类型的开始位置、当前读到文本的数据长度
  public void characters(char[] ch, int start, int length)
  throws SAXException {
  if(tag != null){
  String data = new String(ch, start, length);
  if(tag.equals("name")){
  person.setName(data);
  }else if(tag.equals("age")){
  person.setAge(Integer.parseInt(data));
  }
  }
  }
 
  //结束元素语法事件  参数说明:命名空间、不带命名空间的标签名、含有命名空间前缀的标签名
  public void endElement(String uri, String localName, String qName)
  throws SAXException {
  if("person".equals(qName)){
  list.add(person);
  person = null;
  //对象设为空
  }
  tag = null;
  }
  }
 
 
  /*//开始文档事件
  public void startDocument() throws SAXException {
 
  }
  
  //开始元素语法事件  参数说明:命名空间、不带命名空间的标签名、含有命名空间前缀的标签名、属性
  public void startElement(String uri, String localName, String qName,
  Attributes atts) throws SAXException {
 
  }
 
  //触发文本节点事件  参数说明:整个xml内容的字符串、当前读到文本类型的开始位置、当前读到文本的数据长度
  public void characters(char[] ch, int start, int length)
  throws SAXException {
 
  }
 
  //结束元素语法事件  参数说明:命名空间、不带命名空间的标签名、含有命名空间前缀的标签名
  public void endElement(String uri, String localName, String qName)
  throws SAXException {
 
  }
  
  public void endDocument() throws SAXException {
 
  }
  
  public void endPrefixMapping(String prefix) throws SAXException {
 
  }
  
  public void ignorableWhitespace(char[] ch, int start, int length)
  throws SAXException {
 
  }
  
  public void processingInstruction(String target, String data)
  throws SAXException {
 
  }
  
  public void setDocumentLocator(Locator locator) {
 
  }
  
  public void skippedEntity(String name) throws SAXException {
 
  }
  
  public void startPrefixMapping(String prefix, String uri)
  throws SAXException {
 
  }*/
 
  }
  
 
 
 
 xml文件如下:
 <?xml version="1.0" encoding="UTF-8"?>
  <persons>
      <person id="1">
          <name>liming</name>
          <age>23</age>
      </person>
      <person id="2">
          <name>lixiangmei</name>
          <age>24</age>
      </person>
  </persons>
  
 
 
 
posted @ 2012-12-25 16:52 甜咖啡 阅读(364) | 评论 (0)编辑 收藏




export LD_LIBRARY_PATH=/usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/runtime/glnx86:/usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/sys/os/glnx86:/usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/sys/java/jre/glnx86/jre/lib/i386/native_threads:/usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/sys/java/jre/glnx86/jre/lib/i386/server:/usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/sys/java/jre/glnx86/jre/lib/i386
export XAPPLRESDIR=/usr/local/MATLAB/MATLAB_Compiler_Runtime/v716/X11/app-defaults

把以上两行加入系统的环境变量里面:具体操作如下:
vi /etc/profile
按 i 就可以编辑这个文件,开始复制
把上面两行拷贝到这个文件的最下面然后保存就可以了!
保存退出时先按一下“ESC”,然后再按“:wq”就可以保存退出了!
posted @ 2012-11-16 16:24 甜咖啡 阅读(1981) | 评论 (0)编辑 收藏
/**
  * 从数据库中查询IRI和KLO模型的数据,并下载到本地
  * @param dataTime         时次
  * @param outIRIFilePath   IRI文件下载到本地的路径
  * @param outKLOFilePath   KLO文件下载到本地的路径
  * @param outAnaFilePath   插值文件下载到本地的路径
  */
  @SuppressWarnings("static-access")
  public static void selectBlogInfo(String dataTime, String outIRIFilePath, String outKLOFilePath, String outAnaFilePath) {
  try {
  Connection con = DBConnectionManager.getInstance().getConnection();
  Statement st = con.createStatement();
  String sql = "select * from MODELTEC where DATATIME=to_date('"+dataTime+"', 'YYYY-mm-dd HH24')";
  ResultSet rs = st.executeQuery(sql);
  if (rs.next()) {
  Blob blod = rs.getBlob("IRIDATA");
  InputStream reader = blod.getBinaryStream();
  dataTime = dataTime.replaceAll("-", "");
  dataTime = dataTime.replaceAll(" ", "");
  String iriFilePath = outIRIFilePath+"\\"+dataTime+"0000.iri.grd";
  File file = new File(iriFilePath);
  OutputStream writer;
  writer = new BufferedOutputStream(new FileOutputStream(file));
  byte buf[] = new byte[1024];
  for (int i = 0; (i = reader.read(buf)) > 0;) {
  writer.write(buf, 0, i);
  }
  writer.close();
  reader.close();
 
  blod = rs.getBlob("IRIDATA");
  reader = blod.getBinaryStream();
  String kloFilePath = outKLOFilePath+"\\"+dataTime+"0000.klo.grd";
  file = new File(kloFilePath);
  writer = new BufferedOutputStream(new FileOutputStream(file));
  buf = new byte[1024];
  for (int i = 0; (i = reader.read(buf)) > 0;) {
  writer.write(buf, 0, i);
  }
  writer.close();
  reader.close();
 
  blod = rs.getBlob("ANADATA");
  reader = blod.getBinaryStream();
  String anaFilePath = outAnaFilePath+"\\"+dataTime+"0000.grd";
  file = new File(anaFilePath);
  writer = new BufferedOutputStream(new FileOutputStream(file));
  buf = new byte[1024];
  for (int i = 0; (i = reader.read(buf)) > 0;) {
  writer.write(buf, 0, i);
  }
  writer.close();
  reader.close();
  }
  DBConnectionManager.closeConnection();
  if(con!=null){con.close();}
  if(st!=null){st.close();}
  if(rs!=null){rs.close();}
  } catch (SQLException e) {
  e.printStackTrace();
  } catch (FileNotFoundException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
 
  /**
  * 把IRI和KLO模型的文件上传到数据库中
  * @param dataTime     时次
  * @param iriFilePath  要上传IRI文件的绝对路径
  * @param kloFilePath  要上传KLO文件的据对路径
  * @param ANAFilePath  要上传插值文件的据对路径
  */
  @SuppressWarnings("static-access")
  public static void insertBlogInfo(String dataTime, String IRIFilePath, String KLOFilePath, String ANAFilePath) {
  try {
  Connection con = DBConnectionManager.getInstance().getConnection();
  // 处理事务
  boolean defaultCommit;
  defaultCommit = con.getAutoCommit();
 
  con.setAutoCommit(false);
  Statement st = con.createStatement();
 
  String sql = "select * from MODELTEC where DATATIME=to_date('"+dataTime+"', 'YYYY-mm-dd HH24')";
  ResultSet rs = st.executeQuery(sql);
  if(rs.next()){
  System.out.println(dataTime+"时次已经入库!");
  return ;
  }
  // 插入一个空对象
  sql = "insert into MODELTEC(ID, DATATIME, IRIDATA, KLODATA, ANADATA) values(" +
  "SEQU_MODEL_ID.nextval, " +
  "to_date('"+dataTime+"','YYYY-mm-dd HH24'), " +
  "empty_blob(), " +
  "empty_blob(), " +
  "empty_blob())";
  st.executeUpdate(sql);
  // 用for update方式锁定数据行
  sql = "select IRIDATA,KLODATA,ANADATA from  MODELTEC where DATATIME=to_date('"+dataTime+"', 'YYYY-mm-dd HH24') for update";
  rs = st.executeQuery(sql);
  if (rs.next()) {
  // 得到java.sql.Blob对象,然后Cast为oracle.sql.BLOB
  BLOB blob = (BLOB) rs.getBlob("IRIDATA");
  // 到数据库的输出流
  OutputStream outStream = blob.getBinaryOutputStream();
  // 这里用一个文件模拟输入流
  InputStream fin = new FileInputStream(new File(IRIFilePath));
  // 将输入流写到输出流
  byte[] b = new byte[blob.getBufferSize()];
  int len = 0;
  while ((len = fin.read(b)) != -1) {
  outStream.write(b, 0, len);
  }
  // 依次关闭(注意顺序)
  fin.close();
  outStream.flush();
  outStream.close();
 
  // 得到java.sql.Blob对象,然后Cast为oracle.sql.BLOB
  blob = (BLOB) rs.getBlob("KLODATA");
  // 到数据库的输出流
  outStream = blob.getBinaryOutputStream();
  // 这里用一个文件模拟输入流
  fin = new FileInputStream(new File(IRIFilePath));
  // 将输入流写到输出流
  b = new byte[blob.getBufferSize()];
  len = 0;
  while ((len = fin.read(b)) != -1) {
  outStream.write(b, 0, len);
  }
  // 依次关闭(注意顺序)
  fin.close();
  outStream.flush();
  outStream.close();
 
  // 得到java.sql.Blob对象,然后Cast为oracle.sql.BLOB
  blob = (BLOB) rs.getBlob("ANADATA");
  // 到数据库的输出流
  outStream = blob.getBinaryOutputStream();
  // 这里用一个文件模拟输入流
  fin = new FileInputStream(new File(ANAFilePath));
  // 将输入流写到输出流
  b = new byte[blob.getBufferSize()];
  len = 0;
  while ((len = fin.read(b)) != -1) {
  outStream.write(b, 0, len);
  }
  // 依次关闭(注意顺序)
  fin.close();
  outStream.flush();
  outStream.close();
 
  con.commit();
  /* 恢复原提交状态 */
  con.setAutoCommit(defaultCommit);
  DBConnectionManager.closeConnection();
  if(con!=null){con.close();}
  if(st!=null){st.close();}
  if(rs!=null){rs.close();}
  }
  } catch (SQLException e) {
  e.printStackTrace();
  } catch (FileNotFoundException e) {
  e.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  } catch (Exception e) {
  e.printStackTrace();
  }
  }
posted @ 2012-10-19 13:17 甜咖啡 阅读(1325) | 评论 (0)编辑 收藏
    // date类型转换为String类型
  // formatType格式为yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
  // data Date类型的时间
  public static String dateToString(Date data, String formatType) {
  return new SimpleDateFormat(formatType).format(data);
  }
 
  // long类型转换为String类型
  // currentTime要转换的long类型的时间
  // formatType要转换的string类型的时间格式
  public static String longToString(long currentTime, String formatType)
  throws ParseException {
  Date date = longToDate(currentTime, formatType); // long类型转成Date类型
  String strTime = dateToString(date, formatType); // date类型转成String
  return strTime;
  }
 
  // string类型转换为date类型
  // strTime要转换的string类型的时间,formatType要转换的格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日
  // HH时mm分ss秒,
  // strTime的时间格式必须要与formatType的时间格式相同
  public static Date stringToDate(String strTime, String formatType)
  throws ParseException {
  SimpleDateFormat formatter = new SimpleDateFormat(formatType);
  Date date = null;
  date = formatter.parse(strTime);
  return date;
  }
 
  // long转换为Date类型
  // currentTime要转换的long类型的时间
  // formatType要转换的时间格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
  public static Date longToDate(long currentTime, String formatType)
  throws ParseException {
  Date dateOld = new Date(currentTime); // 根据long类型的毫秒数生命一个date类型的时间
  String sDateTime = dateToString(dateOld, formatType); // 把date类型的时间转换为string
  Date date = stringToDate(sDateTime, formatType); // 把String类型转换为Date类型
  return date;
  }
 
  // string类型转换为long类型
  // strTime要转换的String类型的时间
  // formatType时间格式
  // strTime的时间格式和formatType的时间格式必须相同
  public static long stringToLong(String strTime, String formatType)
  throws ParseException {
  Date date = stringToDate(strTime, formatType); // String类型转成date类型
  if (date == null) {
  return 0;
  } else {
  long currentTime = dateToLong(date); // date类型转成long类型
  return currentTime;
  }
  }
 
  // date类型转换为long类型
  // date要转换的date类型的时间
  public static long dateToLong(Date date) {
  return date.getTime();
  }
posted @ 2012-09-27 17:07 甜咖啡 阅读(56522) | 评论 (0)编辑 收藏
1、新建用户
useradd 用户名(gpsin) -g 当前登录用户(root) -d 根目录(/home/weiss) -s /sbin/nologin(不是用于登录)       
passwd 用户名(为该用户创建密码)
2、删除用户
userdel 用户名(gpsin)
3、修改用户根目录
usermod -d 新目录(/home/wei) 用户名(gpsin)


posted @ 2012-09-27 17:00 甜咖啡 阅读(275) | 评论 (0)编辑 收藏
window:需要两个文件
一个要执行的bat文件 test.bat
文件内容:ftp -n -s:C:\\config.txt 127.0.0.1
另一个操作ftp的命令文件 config.txt
文件内容:
user user
pass
ls
put ......
get ...... 
bye

linux:只需要一个文件即可也就是sh文件
test.sh
文件内容:ftp -i -n 127.0.0.1
user user pass
bin
ls
put ......
get ...... 
bye


ftp -nv 127.0.0.1 <<EOF
user user pass
bin
prompt
lcd /home
put ......
get ......
quit
posted @ 2012-09-26 13:00 甜咖啡 阅读(291) | 评论 (0)编辑 收藏
package db;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class DBPool {
private ComboPooledDataSource dataSource;
public static Connection con;
public DBPool() {
try {
dataSource = new ComboPooledDataSource();
dataSource.setUser("test");
dataSource.setPassword("test");
dataSource.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:orcl");
dataSource.setDriverClass("oracle.jdbc.driver.OracleDriver");
dataSource.setInitialPoolSize(2);
dataSource.setMinPoolSize(1);
dataSource.setMaxPoolSize(10);
dataSource.setMaxStatements(50);
dataSource.setMaxIdleTime(60);
dataSource.setAcquireRetryAttempts(3);   
} catch (PropertyVetoException e) {
}
}
public final static DBPool getInstance() {
return new DBPool();
}
public final Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
return null;
}
}

        //测试方法
public static void main(String[] args) throws SQLException {
con = DBPool.getInstance().getConnection();
System.out.println(con);
try {
if (con != null){con.close();}
} catch (SQLException e) {
e.printStackTrace();
}
}
}


   //初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 initialPoolSize  
    cpds.setInitialPoolSize(initialPoolSize);   
    //连接池中保留的最大连接数。Default: 15 maxPoolSize   
    cpds.setMaxPoolSize(maxPoolSize);
    //连接池中保留的最小连接数。   
    cpds.setMinPoolSize(minPoolSize);
    //获得连接的最大等待毫秒数。Default: 1000 acquireRetryDelay
    cpds.setAcquireRetryDelay(acquireRetryDelay);
    //最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 maxIdleTime   
    cpds.setMaxIdleTime(maxIdleTime);
    //当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 acquireIncrement   
    //cpds.setAcquireIncrement(3);   
    //每60秒检查所有连接池中的空闲连接。Default: 0 idleConnectionTestPeriod   
    //cpds.setIdleConnectionTestPeriod(60);
    //连接关闭时默认将所有未提交的操作回滚。Default: false autoCommitOnClose   
    //cpds.setAutoCommitOnClose(true);
    //JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0
    //cpds.setMaxStatements(1);

    //maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数
    //cpds.setMaxStatementsPerConnection(100);

    //定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:测试的表必须在初始数据源的时候就存在。Default: null preferredTestQuery  
    //cpds.setPreferredTestQuery("select sysdate from dual");   
    // 因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的   
    // 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable   
    // 等方法来提升连接测试的性能。Default: false testConnectionOnCheckout   
    //cpds.setTestConnectionOnCheckout(true);
    //如果设为true那么在取得连接的同时将校验连接的有效性。Default: false testConnectionOnCheckin   
    //cpds.setTestConnectionOnCheckin(true);   
    //定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 acquireRetryAttempts   
    //cpds.setAcquireRetryAttempts(30);     
    //获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效   
    //保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试   
    //获取连接失败后该数据源将申明已断开并永久关闭。Default: false breakAfterAcquireFailure   
    //cpds.setBreakAfterAcquireFailure(false);   

  //两次连接中间隔时间,单位毫秒。Default: 1000 acquireRetryDelay
  cpds.setAcquireRetryDelay(60000);

java.lang.AbstractMethodError: oracle.jdbc.driver.OracleResultSetImpl.getClob(异常解决办法

最近遇到了一个头痛的问题,可能大家也遇到过。经过多番的询问与查找,终于知道问题原因的所在:异常内容如下:

java.lang.AbstractMethodError: oracle.jdbc.driver.OracleResultSetImpl.getClob(Ljava/lang/String;)Ljava/sql/Clob;

问题原因:Oracle驱动版本不对

解决办法:在Oracle服务器上找到这个驱动,然后cp到Apache的lib目录下,并同是修改环境变量classpath,保证这个lib/classes12.jar在最前面;修改完后,重新启动服务,问题就可以解决。

(ojdbc14.jar在classes12.jar前面)

 

posted @ 2012-09-20 15:21 甜咖啡 阅读(5944) | 评论 (0)编辑 收藏
useradd gpsin -g root -d /inraw -s /sbin/nologin     #该用户仅用来支持FTP服务,因此不必让他登录系统
gpsin是ftp登录的用户名,root指定哪个用户可以使用该ftp用户,-d /inraw 指定ftp的根目录,-s /sbin/nologin不用于登录


passwd gpsin    给gpsin用户设置密码
posted @ 2012-09-19 14:25 甜咖啡 阅读(677) | 评论 (0)编辑 收藏

1.下载

rarlinux-3.7.1.tar.zip

#unzip rarlinux-3.7.1.tar.zip

#cd rar

#make

#make install

运行 rar --help 可以看到帮助信息,如果出现下列信息:
 #rar: /lib/tls/libc.so.6: version `GLIBC_2.4' not found (required by rar)
 #rar: /lib/tls/libc.so.6: version `GLIBC_2.7' not found (required by rar)
 则执行:
 #cp -f rar_static /usr/local/bin/rar
 这样就可以使用rar 命令了。

posted @ 2012-09-19 14:21 甜咖啡 阅读(1086) | 评论 (0)编辑 收藏

一、卸载jdk1.4

由于Redhat Enterprise Linux 5.6 中自带安装了jdk1.4.2的,所以在安装jdk1.6前我把jdk1.4.2的卸了,步骤如下:

1、打开终端输入 yum remove java
终端显示 Is this ok [y/N]:
输入y ,按回车。
终端显示 Complete! 此时jdk1.4已被卸了。
二、安装jdk1.6

1.下载:jdk-1_5_0_06-linux-i586-rpm.bin
   地址:http://java.sun.com/j2se/1.5.0/download.jsp
2.给文件加上可执行权限
   [root@esprit java]# chmod +x jdk-1_5_0_06-linux-i586-rpm.bin
chmod +x jdk-6u31-linux-i586-rpm.bin
3.执行jdk-1_5_0_06-linux-i586-rpm.bin
   [root@esprit java]# ./jdk-1_5_0_06-linux-i586-rpm.bin
./jdk-6u31-linux-i586-rpm.bin
   执行后生成jdk-6u31-linux-i586.rpm
4.安装jdk-6u31-linux-i586.rpm
rpm -ivh jdk-6u31-linux-i586.rpm
########################################### [100%]
package jdk-1.6.0_31-fcs is already installed
这里我jdk安装在/usr/java目录下

三、配置java环境变量

 环境变量配置有三种方法(分别是:修改/etc/profile文件,修改用户目录下的.bashrc文件,直接在shell下修改)
这里我只讲我用到的修改/etc/profile文件
   [root@esprit java]# vi /etc/profile
   打开文件后,按 I 键,在文件后添加:
 JAVA_HOME =/ usr / java / jdk1.6.0_31
 PATH = $JAVA_HOME / bin:$PATH
 CLASSPATH = .:$JAVA_HOME / lib / tools.jar:$JAVA_HOME / lib / dt.jar:$JAVA_HOME/lib
 export JAVA_HOME PATH CLASSPATH
 
   按esc 键
   输入:wq 保存退出。
   重新登入

四、检查jdk是否装好

在命令行输入: java -version

如果显示版本信息,表示已经安装配置成功

五、卸载jdk1.6

输入 rpm -qa|grep jdk
显示 jdk-1.6.0_24-fcs
卸载 rpm -e –nodeps jdk-1.6.0_24-fcs

posted @ 2012-09-19 14:19 甜咖啡 阅读(7073) | 评论 (1)编辑 收藏

package com.ky.ui.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;

import javax.imageio.ImageIO;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

 

/**
Email:

上午11:18:19
*/
public final class ImgRead{

// public final static String getPressImgPath(){
// return ApplicationContext.getRealPath("/template/data/util/shuiyin.gif");
// }

/** *//**
* 把图片印刷到图片上
* @param pressImg -- 水印文件
* @param targetImg -- 目标文件
* @param x
* @param y
*/
public final static void pressImage(String pressImg, String targetImg, int x, int y){
try {
File _file = new File(targetImg);
Image src = ImageIO.read(_file);
int wideth = src.getWidth(null);
int height = src.getHeight(null);
BufferedImage image = new BufferedImage(wideth, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.drawImage(src, 0, 0, wideth, height, null);

// 水印文件
File _filebiao = new File(pressImg);
Image src_biao = ImageIO.read(_filebiao);
int wideth_biao = src_biao.getWidth(null);
int height_biao = src_biao.getHeight(null);
g.drawImage(src_biao, wideth - wideth_biao - x, height - height_biao -y, wideth_biao,
height_biao, null);
// /
g.dispose();
FileOutputStream out = new FileOutputStream(targetImg);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.close();
} catch (Exception e){
e.printStackTrace();
}
}

/** *//**
* 打印文字水印图片
* @param pressText --文字
* @param targetImg -- 目标图片
* @param fontName -- 字体名
* @param fontStyle -- 字体样式
* @param color -- 字体颜色
* @param fontSize -- 字体大小
* @param x -- 偏移量
* @param y
*/

public static void pressText(String pressText, String targetImg, String fontName,int fontStyle, int color, int fontSize, int x, int y){
try{
File _file = new File(targetImg);
Image src = ImageIO.read(_file);
int wideth = src.getWidth(null);
int height = src.getHeight(null);
BufferedImage image = new BufferedImage(wideth, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.drawImage(src, 0, 0, wideth, height, null);
// String s="www.qhd.com.cn";
g.setColor(Color.RED);
g.setFont(new Font(fontName, fontStyle, fontSize));

g.drawString(pressText, wideth - fontSize - x, height - fontSize/2 - y);
g.dispose();
FileOutputStream out = new FileOutputStream(targetImg);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.close();
} catch (Exception e){
System.out.println(e);
}
}

public static void main(String[] args){
pressImage("C:/foot_05.gif", "c:/Chart.jpg", 20 ,20);
}
}

posted @ 2012-09-08 19:51 甜咖啡 阅读(286) | 评论 (0)编辑 收藏

//  获取屏幕的边界
  Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(frame.getGraphicsConfiguration());
//  获取底部任务栏高度
  int taskBarHeight = screenInsets.bottom; 

posted @ 2012-09-08 19:46 甜咖啡 阅读(1581) | 评论 (0)编辑 收藏

1、  下载vsftpd

# wget ftp://vsftpd.beasts.org/users/cevans/vsftpd-2.3.2.tar.gz

2、  解压、安装vsftpd

# tar xvfz vsftpd-2.3.2.tar.gz

# cd vsftpd-2.3.2

# make

make命令成功执行后,您将看到vsftpd文件获得当前目录中创建。

# ls -l vsftpd

3、  安装 vsftpd d Linux

# make install

make install,确保vsftpd文件复制到/ usr / local / sbin目录。

# ls -l /usr/local/sbin/vsftpd

4、  复制vsftpd手册页到/usr/share/man/man8,man5

# cp vsftpd.8 /usr/share/man/man8/

# cp vsftpd.conf.5 /usr/share/man/man5/

5、  拷贝vsftpd.cond配置文件

# cp vsftpd.conf /etc

6、   设置Anonymouse FTP访问vsftpd

# mkdir /var/ftp/

# chown root.root /var/ftp

# chmod og-w /var/ftp

 

ftp localhost

Connected to dotcom.

220 (vsFTPd 2.3.2)

530 Please login with USER and PASS.

KERBEROS_V4 rejected as an authentication type

Name (localhost:root): anonymous

331 Please specify the password.

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp>

在这个阶段,如果你试图登录与任何其他账户(除了匿名,和ftp),它就会失败,如下所示

# ftp localhost

Connected to dotcom.

220 (vsFTPd 2.3.2)

530 Please login with USER and PASS.

KERBEROS_V4 rejected as an authentication type

Name (localhost:root): ramesh

530 This FTP server is anonymous only.

Login failed.

ftp>

7、   允许LINIX登录使用vsftp

# cp RedHat/vsftpd.pam /etc/pam.d/ftp

#local_enable=YES

# ftp localhost

Connected to dotcom.

220 (vsFTPd 2.3.2)

530 Please login with USER and PASS.

KERBEROS_V4 rejected as an authentication type

Name (localhost:root): ramesh

Password:

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp>

切记再每次修改完vsftpd.conf文件之后要重启一下vsftpd

# ps -ef | grep vsftpd

# kill -9 {vsftpd-pid}

# /usr/local/sbin/vsftpd &

 

 

如果还不能登录成功,那么要关闭系统其他的ftp服务和防火墙

Service xinetd stop

Service iptables stop

posted @ 2012-08-22 16:15 甜咖啡 阅读(247) | 评论 (0)编辑 收藏
posted @ 2012-05-17 17:56 甜咖啡 阅读(175) | 评论 (0)编辑 收藏
     摘要: 各种排序算法:冒择路(入)兮(稀)快归堆,桶式排序,基数排序 冒泡排序,选择排序,插入排序,稀尔排序,快速排序,归并排序,堆排序,桶式排序,基数排序 一、冒泡排序(BubbleSort) 1. 基本思想:   两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止。 2. 排序过程:   设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气...  阅读全文
posted @ 2012-05-17 17:52 甜咖啡 阅读(821) | 评论 (0)编辑 收藏
     摘要: Java反射机制是Java语言被视为准动态语言的关键性质。Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法)。 也许你使用Java已经很长时间了,可是几乎不会用到Java反射机制。你会嗤之以鼻地告诉我,Java反射机制没啥用...  阅读全文
posted @ 2012-05-17 17:07 甜咖啡 阅读(271) | 评论 (0)编辑 收藏
1.使用mysqladmin修改mysql密码
C:\>mysqladmin -udbuser -p password newpass
Enter password: oldpass
当然用此命令的前提是你把mysql加入了环境变量,如果没有加入环境变量的话那只能在命令行下cd到mysqladmin所在的目录下与此那个次命令了!
-----------------------------------------
2.重置root密码
方法一:
在my.ini的[mysqld]字段加入:
skip-grant-tables
重启mysql服务,这时的mysql不需要密码即可登录数据库
然后进入mysql
mysql>use mysql;
mysql>update user set password=password('新密码') WHERE User='root';
mysql>flush privileges;
运行之后最后去掉my.ini中的skip-grant-tables,重启mysqld即可。
修改mysql密码方法二:
不使用修改my.ini重启服务的方法,通过非服务方式加skip-grant-tables运行mysql来修改mysql密码
停止mysql服务
打开命令行窗口,在bin目录下使用mysqld-nt.exe启动,即在命令行窗口执行: mysqld-nt --skip-grant-tables
然后另外打开一个命令行窗口,登录mysql,此时无需输入mysql密码即可进入。
按以上方法修改好密码后,关闭命令行运行mysql的那个窗口,此时即关闭了mysql,如果发现mysql仍在运行的话可以结束掉对应进程来关闭。
启动mysql服务

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

记住此方法,走遍天下无mysql密码

posted @ 2012-05-16 18:38 甜咖啡 阅读(193) | 评论 (0)编辑 收藏

先假设一个ftp地址 用户名 密码

      FTP Server: home4u.at.china.com

  User: yepanghuang

  Password: abc123

打开windows的开始菜单,执行“运行”命令,在对话框中输入ftp,按下“确定”按钮将会切换至DOS窗口,出现命令提示符

      ftp>键入命令连接FTP服务器

  ftp> open home4u.at.china.com (回车)

  稍等片刻,屏幕提示连接成功:

  ftp> connected to home4u.china.com

  接下来服务器询问用户名和口令,分别输入yepanghuang和abc123,待认证通过即可。

windows下ftp上传文件:

      比如要把 D:\index.html上传至服务器的根目录中,可以键入:

  ftp> put D:\index.html (回车)

  当屏幕提示你已经传输完毕,可以键入相关命令查看:

  ftp> dir (回车)

windows下ftp上传下载:

      假设要把服务器\images目录中的所有.jpg文件下载至本机中,可以输入指令:

  ftp> cd images(回车) [注:进入\images目录]

  ftp> mget *.jpg

  windows下ftp上传与下载工作完毕,键入bye中断连接。

  ftp> bye(回车)

下面是一些常用的FTP命令:

  1. open:与服务器相连接;

  2. send(put):上传文件;

  3. get:下载文件;

  4. mget:下载多个文件;

  5. cd:切换目录;

  6. dir:查看当前目录下的文件;

  7. del:删除文件;

  8. bye:中断与服务器的连接。

  如果想了解更多,可以键入

  ftp> help (回车)

查看命令集

  ascii: 设定以ASCII方式传送文件(缺省值)

  bell: 每完成一次文件传送,报警提示

  binary: 设定以二进制方式传送文件

  bye: 终止主机FTP进程,并退出FTP管理方式

  case: 当为ON时,用MGET命令拷贝的文件名到本地机器中,全部转换为小写字母

  cd: 同UNIX的CD命令

  cdup: 返回上一级目录

  chmod: 改变远端主机的文件权限

  close: 终止远端的FTP进程,返回到FTP命令状态,所有的宏定义都被删除

  delete: 删除远端主机中的文件

  dir [remote-directory] [local-file]: 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件

  get [remote-file] [local-file]: 从远端主机中传送至本地主机中

  help [command]: 输出命令的解释

  lcd: 改变当前本地主机的工作目录,如果缺省,就转到当前用户的HOME目录

  ls [remote-directory] [local-file]: 同DIR

posted @ 2012-05-16 18:35 甜咖啡 阅读(9077) | 评论 (0)编辑 收藏

其实在网上也看到过一些文章,介绍如何让java程序以window服务的方式启动。

今天有空,就想用c写一个window服务,在服务启动时来启动一个java程序。

因为在c方面,我十足菜鸟,先到网上搜索了一下关于如何用c写出windows服务,找到一篇介绍的相当详细,参照介绍写了一个window服务。

测试的过程中遇到一个问题,由于我的java程序启动时会在系统托盘显示一个小图标,但通过c写的window服务启运这个java程序后,系统托盘里没有显示小图标。

再搜索,原来:

windows服务程序默认是工作于WinLogon桌面的,服务启动时不会显示GUI界面.可以打开控制面板->服务,查看服务的属性->[登录]-[允许服务与桌面交互],打上钩后,系统托盘就能显示在任务栏。

 

 

用C写一个windows服务

来源:http://www.vckbase.com/document/viewdoc/?id=1474

摘要

  Windows 服务被设计用于需要在后台运行的应用程序以及实现没有用户交互的任务。为了学习这种控制台应用程序的基础知识,C(不是C++)是最佳选择。本文将建立并实现一个简单的服务程序,其功能是查询系统中可用物理内存数量,然后将结果写入一个文本文件。最后,你可以用所学知识编写自己的 Windows 服务。
  当初我写第一个 NT 服务时,我到 MSDN 上找例子。在那里我找到了一篇 Nigel Thompson 写的文章:“Creating a Simple Win32 Service in C++”,这篇文章附带一个 C++ 例子。虽然这篇文章很好地解释了服务的开发过程,但是,我仍然感觉缺少我需要的重要信息。我想理解通过什么框架,调用什么函数,以及何时调用,但 C++ 在这方面没有让我轻松多少。面向对象的方法固然方便,但由于用类对底层 Win32 函数调用进行了封装,它不利于学习服务程序的基本知识。这就是为什么我觉得 C 更加适合于编写初级服务程序或者实现简单后台任务的服务。在你对服务程序有了充分透彻的理解之后,用 C++ 编写才能游刃有余。当我离开原来的工作岗位,不得不向另一个人转移我的知识的时候,利用我用 C 所写的例子就非常容易解释 NT 服务之所以然。
  服务是一个运行在后台并实现勿需用户交互的任务的控制台程序。Windows NT/2000/XP 操作系统提供为服务程序提供专门的支持。人们可以用服务控制面板来配置安装好的服务程序,也就是 Windows 2000/XP 控制面板|管理工具中的“服务”(或在“开始”|“运行”对话框中输入 services.msc /s——译者注)。可以将服务配置成操作系统启动时自动启动,这样你就不必每次再重启系统后还要手动启动服务。
  本文将首先解释如何创建一个定期查询可用物理内存并将结果写入某个文本文件的服务。然后指导你完成生成,安装和实现服务的整个过程。


第一步:主函数和全局定义

首先,包含所需的头文件。例子要调用 Win32 函数(windows.h)和磁盘文件写入(stdio.h):

#include <windows.h>
#include <stdio.h>

接着,定义两个常量:

#define SLEEP_TIME 5000
#define LOGFILE "C:\\MyServices\\memstatus.txt"

SLEEP_TIME 指定两次连续查询可用内存之间的毫秒间隔。在第二步中编写服务工作循环的时候要使用该常量。
LOGFILE 定义日志文件的路径,你将会用 WriteToLog 函数将内存查询的结果输出到该文件,WriteToLog 函数定义如下:

int WriteToLog(char* str)
{
    FILE* log;
    log = fopen(LOGFILE, "a+");
    if (log == NULL)
    return -1;
    fprintf(log, "%s\n", str);
    fclose(log);
    return 0;
}

声明几个全局变量,以便在程序的多个函数之间共享它们值。此外,做一个函数的前向定义:

SERVICE_STATUS ServiceStatus; 
SERVICE_STATUS_HANDLE hStatus; 

void ServiceMain(int argc, char** argv); 
void ControlHandler(DWORD request); 
int InitService();

  现在,准备工作已经就绪,你可以开始编码了。服务程序控制台程序的一个子集。因此,开始你可以定义一个 main 函数,它是程序的入口点。对于服务程序来说,main 的代码令人惊讶地简短,因为它只创建分派表并启动控制分派机。

void main() 
{ 
    SERVICE_TABLE_ENTRY ServiceTable[2];
    ServiceTable[0].lpServiceName = "MemoryStatus";
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
    
    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;

    // 启动服务的控制分派机线程
    StartServiceCtrlDispatcher(ServiceTable); 
}

  一个程序可能包含若干个服务。每一个服务都必须列于专门的分派表中(为此该程序定义了一个 ServiceTable 结构数组)。这个表中的每一项都要在 SERVICE_TABLE_ENTRY 结构之中。它有两个域:

  • lpServiceName: 指向表示服务名称字符串的指针;当定义了多个服务时,那么这个域必须指定;
  • lpServiceProc: 指向服务主函数的指针(服务入口点);

  分派表的最后一项必须是服务名和服务主函数域的 NULL 指针,文本例子程序中只宿主一个服务,所以服务名的定义是可选的。
  服务控制管理器(SCM:Services Control Manager)是一个管理系统所有服务的进程。当 SCM 启动某个服务时,它等待某个进程的主线程来调用 StartServiceCtrlDispatcher 函数。将分派表传递给 StartServiceCtrlDispatcher。这将把调用进程的主线程转换为控制分派器。该分派器启动一个新线程,该线程运行分派表中每个服务的 ServiceMain 函数(本文例子中只有一个服务)分派器还监视程序中所有服务的执行情况。然后分派器将控制请求从 SCM 传给服务。

注意:如果 StartServiceCtrlDispatcher 函数30秒没有被调用,便会报错,为了避免这种情况,我们必须在 ServiceMain 函数中(参见本文例子)或在非主函数的单独线程中初始化服务分派表。本文所描述的服务不需要防范这样的情况。

  分派表中所有的服务执行完之后(例如,用户通过“服务”控制面板程序停止它们),或者发生错误时。StartServiceCtrlDispatcher 调用返回。然后主进程终止。


第二步:ServiceMain 函数

  Listing 1 展示了 ServiceMain 的代码。该函数是服务的入口点。它运行在一个单独的线程当中,这个线程是由控制分派器创建的。ServiceMain 应该尽可能早早为服务注册控制处理器。这要通过调用 RegisterServiceCtrlHadler 函数来实现。你要将两个参数传递给此函数:服务名和指向 ControlHandlerfunction 的指针。
  它指示控制分派器调用 ControlHandler 函数处理 SCM 控制请求。注册完控制处理器之后,获得状态句柄(hStatus)。通过调用 SetServiceStatus 函数,用 hStatus 向 SCM 报告服务的状态。
Listing 1 展示了如何指定服务特征和其当前状态来初始化 ServiceStatus 结构,ServiceStatus 结构的每个域都有其用途:

  • dwServiceType:指示服务类型,创建 Win32 服务。赋值 SERVICE_WIN32;
  • dwCurrentState:指定服务的当前状态。因为服务的初始化在这里没有完成,所以这里的状态为 SERVICE_START_PENDING;
  • dwControlsAccepted:这个域通知 SCM 服务接受哪个域。本文例子是允许 STOP 和 SHUTDOWN 请求。处理控制请求将在第三步讨论;
  • dwWin32ExitCode 和 dwServiceSpecificExitCode:这两个域在你终止服务并报告退出细节时很有用。初始化服务时并不退出,因此,它们的值为 0;
  • dwCheckPoint 和 dwWaitHint:这两个域表示初始化某个服务进程时要30秒以上。本文例子服务的初始化过程很短,所以这两个域的值都为 0。

  调用 SetServiceStatus 函数向 SCM 报告服务的状态时。要提供 hStatus 句柄和 ServiceStatus 结构。注意 ServiceStatus 一个全局变量,所以你可以跨多个函数使用它。ServiceMain 函数中,你给结构的几个域赋值,它们在服务运行的整个过程中都保持不变,比如:dwServiceType。
  在报告了服务状态之后,你可以调用 InitService 函数来完成初始化。这个函数只是添加一个说明性字符串到日志文件。如下面代码所示:

// 服务初始化
int InitService() 
{ 
    int result;
    result = WriteToLog("Monitoring started.");
    return(result); 
}

  在 ServiceMain 中,检查 InitService 函数的返回值。如果初始化有错(因为有可能写日志文件失败),则将服务状态置为终止并退出 ServiceMain:

error = InitService(); 
if (error) 
{
    // 初始化失败,终止服务
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    ServiceStatus.dwWin32ExitCode = -1; 
    SetServiceStatus(hStatus, &ServiceStatus); 
    // 退出 ServiceMain
    return; 
}

如果初始化成功,则向 SCM 报告状态:

// 向 SCM 报告运行状态 
ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
SetServiceStatus (hStatus, &ServiceStatus);

接着,启动工作循环。每五秒钟查询一个可用物理内存并将结果写入日志文件。

如 Listing 1 所示,循环一直到服务的状态为 SERVICE_RUNNING 或日志文件写入出错为止。状态可能在 ControlHandler 函数响应 SCM 控制请求时修改。
 

第三步:处理控制请求

  在第二步中,你用 ServiceMain 函数注册了控制处理器函数。控制处理器与处理各种 Windows 消息的窗口回调函数非常类似。它检查 SCM 发送了什么请求并采取相应行动。
  每次你调用 SetServiceStatus 函数的时候,必须指定服务接收 STOP 和 SHUTDOWN 请求。Listing 2 示范了如何在 ControlHandler 函数中处理它们。
  STOP 请求是 SCM 终止服务的时候发送的。例如,如果用户在“服务”控制面板中手动终止服务。SHUTDOWN 请求是关闭机器时,由 SCM 发送给所有运行中服务的请求。两种情况的处理方式相同:

  • 写日志文件,监视停止;
  • 向 SCM 报告 SERVICE_STOPPED 状态;

  由于 ServiceStatus 结构对于整个程序而言为全局量,ServiceStatus 中的工作循环在当前状态改变或服务终止后停止。其它的控制请求如:PAUSE 和 CONTINUE 在本文的例子没有处理。
  控制处理器函数必须报告服务状态,即便 SCM 每次发送控制请求的时候状态保持相同。因此,不管响应什么请求,都要调用 SetServiceStatus。


图一 显示 MemoryStatus 服务的服务控制面板


第四步:安装和配置服务

  程序编好了,将之编译成 exe 文件。本文例子创建的文件叫 MemoryStatus.exe,将它拷贝到 C:\MyServices 文件夹。为了在机器上安装这个服务,需要用 SC.EXE 可执行文件,它是 Win32 Platform SDK 中附带的一个工具。(译者注:Visaul Studio .NET 2003 IDE 环境中也有这个工具,具体存放位置在:C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\Bin\winnt)。使用这个实用工具可以安装和移除服务。其它控制操作将通过服务控制面板来完成。以下是用命令行安装 MemoryStatus 服务的方法:

sc create MemoryStatus binpath= c:\MyServices\MemoryStatus.exe

  发出此创建命令。指定服务名和二进制文件的路径(注意 binpath= 和路径之间的那个空格)。安装成功后,便可以用服务控制面板来控制这个服务(参见图一)。用控制面板的工具栏启动和终止这个服务。


图二 MemoryStatus 服务的属性窗口

  MemoryStatus 的启动类型是手动,也就是说根据需要来启动这个服务。右键单击该服务,然后选择上下文菜单中的“属性”菜单项,此时显示该服务的属性窗口。在这里可以修改启动类型以及其它设置。你还可以从“常规”标签中启动/停止服务。以下是从系统中移除服务的方法:

sc delete MemoryStatus

指定 “delete” 选项和服务名。此服务将被标记为删除,下次西通重启后,该服务将被完全移除。


第五步:测试服务

  从服务控制面板启动 MemoryStatus 服务。如果初始化不出错,表示启动成功。过一会儿将服务停止。检查一下 C:\MyServices 文件夹中 memstatus.txt 文件的服务输出。在我的机器上输出是这样的:

Monitoring started.
273469440
273379328
273133568
273084416
Monitoring stopped.

  为了测试 MemoryStatus 服务在出错情况下的行为,可以将 memstatus.txt 文件设置成只读。这样一来,服务应该无法启动。
  去掉只读属性,启动服务,在将文件设成只读。服务将停止执行,因为此时日志文件写入失败。如果你更新服务控制面板的内容,会发现服务状态是已经停止。
 

开发更大更好的服务程序

  理解 Win32 服务的基本概念,使你能更好地用 C++ 来设计包装类。包装类隐藏了对底层 Win32 函数的调用并提供了一种舒适的通用接口。修改 MemoryStatus 程序代码,创建满足自己需要的服务!为了实现比本文例子所示范的更复杂的任务,你可以创建多线程的服务,将作业划分成几个工作者线程并从 ServiceMain 函数中监视它们的执行。


posted @ 2012-04-24 11:58 甜咖啡 阅读(1756) | 评论 (0)编辑 收藏

最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了。

 

下面是参考网络资源总结的一些在Java编程中尽可能要做到的一些地方。
1. 尽量在合适的场合使用单例
使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:
第一,控制资源的使用,通过线程同步来控制资源的并发访问;
第二,控制实例的产生,以达到节约资源的目的;
第三,控制数据共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信。

2. 尽量避免随意使用静态变量
要知道,当某个对象被定义为stataic变量所引用,那么gc通常是不会回收这个对象所占有的内存,如
Java代码
  1. public class A{   
  2. static B b = new B();   
  3. }  
public class A{ static B b = new B(); }
 
此时静态变量b的生命周期与A类同步,如果A类不会卸载,那么b对象会常驻内存,直到程序终止。
3. 尽量避免过多过常的创建Java对象
尽量避免在经常调用的方法,循环中new对象,由于系统不仅要花费时间来创建对象,而且还要花时间对这些对象进行垃圾回收和处理,在我们可以控制的范围内,最大限度的重用对象,最好能用基本的数据类型或数组来替代对象。
4. 尽量使用final修饰符
带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。为String类指定final防止了使用者覆盖length()方法。另外,如果一个类是final的,则该类所有方法都是final的。Java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50%。
5. 尽量使用局部变量
调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。
6. 尽量处理好包装类型和基本类型两者的使用场所
虽然包装类型和基本类型在使用过程中是可以相互转换,但它们两者所产生的内存区域是完全不同的,基本类型数据产生和处理都在栈中处理,包装类型是对象,是在堆中产生实例。
在集合类对象,有对象方面需要的处理适用包装类型,其他的处理提倡使用基本类型。
7. 慎用synchronized,尽量减小synchronize的方法
都知道,实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。synchronize方法被调用时,直接会把当前对象锁 了,在方法执行完之前其他线程无法调用当前对象的其他方法。所以synchronize的方法尽量小,并且应尽量使用方法同步代替代码块同步。
8. 尽量使用StringBuilder和StringBuffer进行字符串连接
这个就不多讲了。
9. 尽量不要使用finalize方法
实际上,将资源清理放在finalize方法中完成是非常不好的选择,由于GC的工作量很大,尤其是回收Young代内存时,大都会引起应用程序暂停,所以再选择使用finalize方法进行资源清理,会导致GC负担更大,程序运行效率更差。
10. 尽量使用基本数据类型代替对象
String str = "hello";
上面这种方式会创建一个“hello”字符串,而且JVM的字符缓存池还会缓存这个字符串;
String str = new String("hello");
此时程序除创建字符串外,str所引用的String对象底层还包含一个char[]数组,这个char[]数组依次存放了h,e,l,l,o
11. 单线程应尽量使用HashMap、ArrayList
HashTable、Vector等使用了同步机制,降低了性能。
12. 尽量合理的创建HashMap
当你要创建一个比较大的hashMap时,充分利用另一个构造函数
public HashMap(int initialCapacity, float loadFactor)
避免HashMap多次进行了hash重构,扩容是一件很耗费性能的事,在默认中initialCapacity只有16,而loadFactor是 0.75,需要多大的容量,你最好能准确的估计你所需要的最佳大小,同样的Hashtable,Vectors也是一样的道理。
13. 尽量减少对变量的重复计算
for(int i=0;i<list.size();i++)
应该改为
for(int i=0,len=list.size();i<len;i++)
并且在循环中应该避免使用复杂的表达式,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。 
14. 尽量避免不必要的创建
A a = new A();
if(i==1){list.add(a);}
应该改为
if(i==1){
A a = new A();
list.add(a);}
15. 尽量在finally块中释放资源
程序中使用到的资源应当被释放,以避免资源泄漏。这最好在finally块中去做。不管程序执行的结果如何,finally块总是会执行的,以确保资源的正确关闭。 
16. 尽量使用移位来代替'a/b'的操作
"/"是一个代价很高的操作,使用移位的操作将会更快和更有效
int num = a / 4;
int num = a / 8;
应该改为
int num = a >> 2;
int num = a >> 3;
但注意的是使用移位应添加注释,因为移位操作不直观,比较难理解
17.尽量使用移位来代替'a*b'的操作
同样的,对于'*'操作,使用移位的操作将会更快和更有效
int num = a * 4;
int num = a * 8;
应该改为
int num = a << 2;
int num = a << 3;
18. 尽量确定StringBuffer的容量
StringBuffer 的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再 丢弃旧的数组。在大多数情况下,你可以在创建 StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。 
如:StringBuffer buffer = new StringBuffer(1000);  
19. 尽量早释放无用对象的引用
大部分时,方法局部引用变量所引用的对象 会随着方法结束而变成垃圾,因此,大部分时候程序无需将局部,引用变量显式设为null。
例如:
Java代码
  1. Public void test(){   
  2. Object obj = new Object();   
  3. ……   
  4. Obj=null;   
  5. }  
Public void test(){ Object obj = new Object(); …… Obj=null; }
 
上面这个就没必要了,随着方法test()的执行完成,程序中obj引用变量的作用域就结束了。但是如果是改成下面:
Java代码
  1. Public void test(){   
  2. Object obj = new Object();   
  3. ……   
  4. Obj=null;   
  5. //执行耗时,耗内存操作;或调用耗时,耗内存的方法   
  6. ……   
  7. }  
Public void test(){ Object obj = new Object(); …… Obj=null; //执行耗时,耗内存操作;或调用耗时,耗内存的方法 …… }
 
这时候就有必要将obj赋值为null,可以尽早的释放对Object对象的引用。
20. 尽量避免使用二维数组
二维数据占用的内存空间比一维数组多得多,大概10倍以上。
21. 尽量避免使用split
除非是必须的,否则应该避免使用split,split由于支持正则表达式,所以效率比较低,如果是频繁的几十,几百万的调用将会耗费大量资源,如果确实需 要频繁的调用split,可以考虑使用apache的StringUtils.split(string,char),频繁split的可以缓存结果。
22. ArrayList & LinkedList
一 个是线性表,一个是链表,一句话,随机查询尽量使用ArrayList,ArrayList优于LinkedList,LinkedList还要移动指 针,添加删除的操作LinkedList优于ArrayList,ArrayList还要移动数据,不过这是理论性分析,事实未必如此,重要的是理解好2 者得数据结构,对症下药。
23. 尽量使用System.arraycopy ()代替通过来循环复制数组
System.arraycopy() 要比通过循环来复制数组快的多 
24. 尽量缓存经常使用的对象
尽可能将经常使用的对象进行缓存,可以使用数组,或HashMap的容器来进行缓存,但这种方式可能导致系统占用过多的缓存,性能下降,推荐可以使用一些第三方的开源工具,如EhCache,Oscache进行缓存,他们基本都实现了FIFO/FLU等缓存算法。
25. 尽量避免非常大的内存分配
有时候问题不是由当时的堆状态造成的,而是因为分配失败造成的。分配的内存块都必须是连续的,而随着堆越来越满,找到较大的连续块越来越困难。
26. 慎用异常
当创建一个异常时,需要收集一个栈跟踪(stack track),这个栈跟踪用于描述异常是在何处创建的。构建这些栈跟踪时需要为运行时栈做一份快照,正是这一部分开销很大。当需要创建一个 Exception 时,JVM 不得不说:先别动,我想就您现在的样子存一份快照,所以暂时停止入栈和出栈操作。栈跟踪不只包含运行时栈中的一两个元素,而是包含这个栈中的每一个元素。
如 果您创建一个 Exception ,就得付出代价。好在捕获异常开销不大,因此可以使用 try-catch 将核心内容包起来。从技术上讲,您甚至可以随意地抛出异常,而不用花费很大的代价。招致性能损失的并不是 throw 操作——尽管在没有预先创建异常的情况下就抛出异常是有点不寻常。真正要花代价的是创建异常。幸运的是,好的编程习惯已教会我们,不应该不管三七二十一就 抛出异常。异常是为异常的情况而设计的,使用时也应该牢记这一原则。

相关回复:
xuanyuan 写道
7.慎用synchronized,尽量减小synchronize的方法
re:同意,不过文中有个地方说错了,使用synchronized关键字并不一定都是锁定当前对象的,要看具体的锁是什么。如果是在方法上加的synchronized,则是以对象本身为锁的,如果是静态方法则锁的粒度是类。
---------------
9.尽量不要使用finalize方法
re:同意,其实不推荐用finalize方法的根本原因在于,JVM的规范并不保证何时执行该方法,所以用这个方法来释放资源很不合适,有可能造成长时间资源得不到释放。
---------------
16.尽量使用移位来代替'a/b'的操作;17.尽量使用移位来代替'a*b'的操作
re:个人不太同意这两条。这样做确实有更好的性能,但是却牺牲了可读性。这两个操作符对很多程序员来说并不直观。我认为在如今硬件价格不那么昂贵的情况下,略微牺牲一些性能,换来更好的可读性和可维护性是好的选择。
 
wuzhengju 写道
19.尽量早释放无用对象的引用
大部分时,方法局部引用变量所引用的对象 会随着方法结束而变成垃圾,因此,大部分时候程序无需将局部,引用变量显式设为null。
例如:
Public void test(){
Object obj = new Object();
……
Obj=null;
}
上面这个就没必要了,随着方法test()的执行完成,程序中obj引用变量的作用域就结束了。但是如果是改成下面:
Public void test(){
Object obj = new Object();
……
Obj=null;
//执行耗时,耗内存操作;或调用耗时,耗内存的方法
……
}
如果Object obj = new Object(); 如果这对象并不是大对象,这有必要吗?Obj=null;只是告诉jvm这个对象已经成为垃圾,至于什么时候回收,还不能确定! 这可读性也不好!
posted @ 2012-04-16 14:49 甜咖啡 阅读(197) | 评论 (0)编辑 收藏

下面的代码片段是由经过验证的程序修改而来。观察这些代码片段你会发现,跟以前的版本相比,在Java7里,文件相关的操作变得简单的多了。通过使用新的Files类里提供的各种方法,你可以只用一行代码就能完成下列的文件操作:

  • 创建文件
  • 删除文件
  • 复制文件
  • 文件移动/改名

这篇文件是以你对Java7里提供的新的Path类很熟悉为前提,如果你不熟悉这个类,这里就简单说一句,Path是文件系统里对位置的一个逻辑概念,例如c:\ 和../foobar.txt都是Path。

创建和删除文件

下面的代码片段向你展示的是用 Files.createFile (Path target) 方法创建文件的基本用法。

  1. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
    Path file = Files.createFile (target);  

很多时候,出于安全的原因,你可能希望在创建的文件上设置一下属性,例如:是否可读/可写/写执行。这些属性依赖于文件系统的种类,你需要使用跟文件系统相应的权限辅助类来完成这种操作。例如,PosixFilePermission和PosixFilePermissions为POSIX文件系统设计的。下面的是在POSIX文件系统上的文件设置读写权限的用法。

  1. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
    Set<PosixFilePermission> perms = PosixFilePermissions.fromString ("rw-rw-rw-");
    FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute (perms);
    Files.createFile (target, attr);

这个java.nio.file.attribute包里提供了很多关于FilePermission的类。

警告当创建一个带有权限属性的文件时,请注意包含这个文件的文件夹是否有权限的强制约束。例如,你会发现,由于这些限制,尽管你给创建的文件指定了rw-rw-rw权限,实际创建的结果却是rw-r–r–。

删除文件更简单,使用Files.delete (Path)这个方法。

  1. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
    Files.delete (target);  

拷贝和移动文件

下面的代码向你展示的是使用Files.copy (Path source, Path target)方法做文件拷贝的基本用法。

  1. Path source = Paths.get ("C:\\My Documents\\Stuff.txt");  
  2. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
    Files.copy (source, target);  

经常的,在拷贝文件的过程中你可能希望指定一些操作设置。在Java7里,你可以通过使用StandardCopyOption enum来设置这些属性。下面看一个例子。

  1. import static java.nio.file.StandardCopyOption.*;  
  2. Path source = Paths.get ("C:\\My Documents\\Stuff.txt");  
  3. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
  4. Files.copy (source, target, REPLACE_EXISTING);  

拷贝操作时可以使用的属性还包括COPY_ATTRIBUTES (保留文件属性) 和ATOMIC_MOVE (确保移动事务操作的成功,否则进行回滚)。

移动文件的操作跟拷贝很相似,使用Files.move (Path source, Path target)方法。

同样,你也可以指定移动操作的属性,使用Files.move (Path source, Path target, CopyOptions...) 方法里的参数来设置。

  1. import static java.nio.file.StandardCopyOption.*;  
  2. Path source = Paths.get ("C:\\My Documents\\Stuff.txt");  
  3. Path target = Paths.get ("D:\\Backup\\MyStuff.txt");
    Files.move (source, target, REPLACE_EXISTING,COPY_ATTRIBUTES);  

可以看出,新的用于文件操作的NIO.2 API 非常便于使用。

posted @ 2012-04-16 10:25 甜咖啡 阅读(227) | 评论 (0)编辑 收藏

众所周知,随机数是任何一种编程语言最基本的特征之一。而生成随机数的基本方式也是相同的:产生一个0到1之间的随机数。看似简单,但有时我们也会忽略了一些有趣的功能。

我们从书本上学到什么?

最明显的,也是直观的方式,在Java中生成随机数只要简单的调用:

  1. java.lang.Math.random() 

在所有其他语言中,生成随机数就像是使用Math工具类,如abs, pow, floor, sqrt和其他数学函数。大多数人通过书籍、教程和课程来了解这个类。一个简单的例子:从0.0到1.0之间可以生成一个双精度浮点数。那么通过上面的信息,开发人员要产生0.0和10.0之间的双精度浮点数会这样来写:

  1. Math.random() * 10 

而产生0和10之间的整数,则会写成:

  1. Math.round(Math.random() * 10) 

进阶

通过阅读Math.random()的源码,或者干脆利用IDE的自动完成功能,开发人员可以很容易发现,java.lang.Math.random()使用一个内部的随机生成对象 - 一个很强大的对象可以灵活的随机产生:布尔值、所有数字类型,甚至是高斯分布。例如:

  1. new java.util.Random().nextInt(10) 

它有一个缺点,就是它是一个对象。它的方法必须是通过一个实例来调用,这意味着必须先调用它的构造函数。如果在内存充足的情况下,像上面的表达式是可以接受的;但内存不足时,就会带来问题。

一个简单的解决方案,可以避免每次需要生成一个随机数时创建一个新实例,那就是使用一个静态类。猜你可能想到了java.lang.Math,很好,我们就是改良java.lang.Math的初始化。虽然这个工程量低,但你也要做一些简单的单元测试来确保其不会出错。

假设程序需要生成一个随机数来存储,问题就又来了。比如有时需要操作或保护种子(seed),一个内部数用来存储状态和计算下一个随机数。在这些特殊情况下,共用随机生成对象是不合适的。

并发

在Java EE多线程应用程序的环境中,随机生成实例对象仍然可以被存储在类或其他实现类,作为一个静态属性。幸运的是,java.util.Random是线程安全的,所以不存在多个线程调用会破坏种子(seed)的风险。

另一个值得考虑的是多线程java.lang.ThreadLocal的实例。偷懒的做法是通过Java本身API实现单一实例,当然你也可以确保每一个线程都有自己的一个实例对象。

虽然Java没有提供一个很好的方法来管理java.util.Random的单一实例。但是,期待已久的Java 7提供了一种新的方式来产生随机数:

  1. java.util.concurrent.ThreadLocalRandom.current().nextInt(10) 

这个新的API综合了其他两种方法的优点:单一实例/静态访问,就像Math.random()一样灵活。ThreadLocalRandom也比其他任何处理高并发的方法要更快。

经验

Chris Marasti-Georg 指出:

  1. Math.round(Math.random() * 10) 

使分布不平衡,例如:0.0 - 0.499999将四舍五入为0,而0.5至1.499999将四舍五入为1。那么如何使用旧式语法来实现正确的均衡分布,如下:

  1. Math.floor(Math.random() * 11) 

幸运的是,如果我们使用java.util.Random或java.util.concurrent.ThreadLocalRandom就不用担心上述问题了。

Java实战项目里面介绍了一些不正确使用java.util.Random API的危害。这个教训告诉我们不要使用:

  1. Math.abs(rnd.nextInt())%n 

而使用:

  1. rnd.nextInt(n) 
posted @ 2012-04-16 10:01 甜咖啡 阅读(179) | 评论 (0)编辑 收藏
package com.wss;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

public class GPS_GNSS_XML_Color {
    //删除节点时传入的参数
    private static String deleteNumber;
    
    //修改节点时传入的参数
    private static String updateNumber;
    
    //读取传入的路径,返回一个document对象
    public static Document loadInit(String filePath){
        Document document = null;
        try{
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            document = builder.parse(new File(filePath));
            document.normalize();
            return document;
        }catch(Exception e){
            e.printStackTrace();
            System.out.println(e.getMessage());
            return null;
        }
    }

    /**
     * 删除制定的xml
     * @param filePath
     * @return
     */
    public static boolean deleteXML(String filePath){
        deleteNumber = "421f481e-790c-41be-91e3-27d215b73ce2";
        Document document = loadInit(filePath);
        try{
            NodeList nodeList = document.getElementsByTagName("color");
            for(int i=0; i<nodeList.getLength(); i++){
                String number_ = document.getElementsByTagName("number").item(i).getFirstChild().getNodeValue();
                //删除节点时传入的参数
                if(number_.equals(deleteNumber)){
                    Node node = nodeList.item(i);
                    node.getParentNode().removeChild(node);
                    saveXML(document, filePath);
                }
            }
            return true;
        }catch(Exception e){
            e.printStackTrace();
            System.out.println(e.getMessage());
            return false;
        }
    }
    
    /**
     * 修改制定的xml
     * @param filePath
     * @return
     */
    public static boolean updateXML(String filePath){
        updateNumber = "421f481e-790c-41be-91e3-27d215b73ce2";
         //读取传入的路径,返回一个document对象
         Document document = loadInit(filePath);
         try{
            //获取叶节点
             NodeList nodeList = document.getElementsByTagName("color");
            //遍历叶节点
             for(int i=0; i<nodeList.getLength(); i++){
                 String number = document.getElementsByTagName("number").item(i).getFirstChild().getNodeValue();
                 String colorValue = document.getElementsByTagName("colorValue").item(i).getFirstChild().getNodeValue();
                 Double minValue = Double.parseDouble(document.getElementsByTagName("minValue").item(i).getFirstChild().getNodeValue());
                 Double maxValue = Double.parseDouble(document.getElementsByTagName("maxValue").item(i).getFirstChild().getNodeValue());
                 //修改节点时传入的参数
                 if(number.equals(updateNumber)){
                     document.getElementsByTagName("colorValue").item(i).getFirstChild().setNodeValue("black");
                     document.getElementsByTagName("minValue").item(i).getFirstChild().setNodeValue("2222");
                     document.getElementsByTagName("maxValue").item(i).getFirstChild().setNodeValue("22222");
                     System.out.println();
                 }
             }
             saveXML(document, filePath);
             return true;
         }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
             return false;
         }
    }
    
    /**
     * 添加节点
     * @param filePath
     * @return
     */
    public static boolean addXML(String filePath){
        try{
            //读取传入的路径,返回一个document对象
            Document document = loadInit(filePath);
            //创建叶节点
            Element eltColor = document.createElement("color");
            Element eltNumber = document.createElement("number");//创建叶节点的第一个元素
            Element eltColorValue = document.createElement("colorValue");//创建叶节点的第二个元素
            Element eltMinValue = document.createElement("minValue");//创建叶节点的第三个元素
            Element eltMaxValue = document.createElement("maxValue");//创建叶节点的第四个元素
            Text number_ = document.createTextNode(UUID.randomUUID().toString());//创建叶节点的第一个元素下的文本节点
            eltNumber.appendChild(number_);//把该文本节点加入到叶节点的第一个元素里面
            Text colorValue_ = document.createTextNode("colorValue");//创建叶节点的第二个元素下的文本节点
            eltColorValue.appendChild(colorValue_);//把该文本节点加入到叶节点的第二个元素里面
            Text minValue_ = document.createTextNode("100");//创建叶节点的第三个元素下的文本节点
            eltMinValue.appendChild(minValue_);//把该文本节点加入到叶节点的第三个元素里面
            Text maxValue_ = document.createTextNode("200");//创建叶节点的第四个元素下的文本节点
            eltMaxValue.appendChild(maxValue_);//把该文本节点加入到叶节点的第四个元素里面
            //把叶节点下的元素加入到叶节点下
            eltColor.appendChild(eltNumber);
            eltColor.appendChild(eltColorValue);
            eltColor.appendChild(eltMinValue);
            eltColor.appendChild(eltMaxValue);
            //获取根节点
            Element eltRoot = document.getDocumentElement();
            //把叶节点加入到根节点下
            eltRoot.appendChild(eltColor);
            //更新修改后的源文件
            saveXML(document, filePath);
            return true;
        }catch(Exception e){
            e.printStackTrace();
            System.out.println(e.getMessage());
            return false;
        }
    }
    
    /**
     * 把修改后的document写进源文件(更新源文件)
     * @param document
     * @param filePath
     * @return
     */
    public static boolean saveXML(Document document, String filePath){
        try{
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            
            DOMSource source = new DOMSource(document);
            StreamResult result = new StreamResult(new File(filePath));
            transformer.transform(source, result);
            return true;
        }catch(Exception e){
            e.printStackTrace();
            System.out.println(e.getMessage());
            return false;
        }
    }
    
    /**
     * 获取xml文件的所有记录
     * @param filePath
     * @return
     */
    public static List<ColorValue> selectXML(String filePath){
         List<ColorValue> colorValueList = new ArrayList<ColorValue>();
         try{
             //读取传入的路径,返回一个document对象
             Document document = loadInit(filePath);
             //获取叶节点
             NodeList nodeList = document.getElementsByTagName("color");
             //遍历叶节点
             for(int i=0; i<nodeList.getLength(); i++){
                 ColorValue colorValue = new ColorValue();
                 String number_ = document.getElementsByTagName("number").item(i).getFirstChild().getNodeValue();
                 String colorValue_ = document.getElementsByTagName("colorValue").item(i).getFirstChild().getNodeValue();
                 Double minValue_ = Double.parseDouble(document.getElementsByTagName("minValue").item(i).getFirstChild().getNodeValue());
                 Double maxValue_ = Double.parseDouble(document.getElementsByTagName("maxValue").item(i).getFirstChild().getNodeValue());
                 colorValue.setNumber(number_);
                 colorValue.setColorValue(colorValue_);
                 colorValue.setMinValue(minValue_);
                 colorValue.setMaxValue(maxValue_);
                 colorValueList.add(colorValue);
             }
             return colorValueList;
         }catch(Exception e){
             e.printStackTrace();
             System.out.println(e.getMessage());
             return null;
         }
    }
}






package com.wss;

public class ColorValue {

    private String number;
    private String colorValue;
    private Double minValue;
    private Double maxValue;
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    public String getColorValue() {
        return colorValue;
    }
    public void setColorValue(String colorValue) {
        this.colorValue = colorValue;
    }
    public Double getMinValue() {
        return minValue;
    }
    public void setMinValue(Double minValue) {
        this.minValue = minValue;
    }
    public Double getMaxValue() {
        return maxValue;
    }
    public void setMaxValue(Double maxValue) {
        this.maxValue = maxValue;
    }
}



<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Colors>
    <color>
        <number>7007b384-fab3-4779-9171-229d0664b6b5</number>
        <colorValue>black</colorValue>
        <minValue>2222</minValue>
        <maxValue>22222</maxValue>
    </color>
    <color>
        <number>421f481e-790c-41be-91e3-27d215b73ce2</number>
        <colorValue>colorValue</colorValue>
        <minValue>100</minValue>
        <maxValue>200</maxValue>
    </color>
</Colors>
posted @ 2011-11-08 21:56 甜咖啡 阅读(9550) | 评论 (1)编辑 收藏

 

        // 写文件UTF-8格式 写一行
  public static void writerTxtFile(String filePath, String text) {
  OutputStreamWriter fs;
  try {
  fs = new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8");
  fs.write(text + "\n");
  fs.flush();
  fs.close();
  } catch (UnsupportedEncodingException e1) {
  e1.printStackTrace();
  } catch (FileNotFoundException e1) {
  e1.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
 
  // 写文件UTF-8格式 写一行
  public static void writerStringBuffer(String filePath, StringBuffer text) {
  OutputStreamWriter fs;
  try {
  fs = new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8");
  fs.write(text + "\n");
  fs.flush();
  fs.close();
  } catch (UnsupportedEncodingException e1) {
  e1.printStackTrace();
  } catch (FileNotFoundException e1) {
  e1.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
 
  // 写文件
  public static void writerTxtFile(String filePath, List<String> list) {
  OutputStreamWriter fs;
  try {
  fs = new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8");
  for(int i=0; i<list.size(); i++){
  fs.write(list.get(i) + "\n");
  }
  fs.flush();
  fs.close();
  } catch (UnsupportedEncodingException e1) {
  e1.printStackTrace();
  } catch (FileNotFoundException e1) {
  e1.printStackTrace();
  } catch (IOException e) {
  e.printStackTrace();
  }
  }

 

posted @ 2011-11-04 12:33 甜咖啡 阅读(213) | 评论 (0)编辑 收藏

package dateapp;

import java.util.Date;
import java.util.Calendar;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Frame;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
//import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.JSpinner.NumberEditor;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.border.LineBorder;

public class DateChooseJButton extends JButton {

 private DateChooser dateChooser = null;

 private String preLabel = "";

 public DateChooseJButton() {
  this(getNowDate());
 }

 public DateChooseJButton(SimpleDateFormat df, String dateString) {
  this();
  setText(df, dateString);
 }

 public DateChooseJButton(Date date) {
  this("", date);
 }

 public DateChooseJButton(String preLabel, Date date) {
  if (preLabel != null)
   this.preLabel = preLabel;
  setDate(date);
  setBorder(null);
  setCursor(new Cursor(Cursor.HAND_CURSOR));
  super.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    if (dateChooser == null)
     dateChooser = new DateChooser();
    Point p = getLocationOnScreen();
    p.y = p.y + 30;
    dateChooser.showDateChooser(p);
   }
  });
 }

 private static Date getNowDate() {
  return Calendar.getInstance().getTime();
 }

 private static SimpleDateFormat getDefaultDateFormat() {
  return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 }

 // 覆盖父类的方法
 public void setText(String s) {
  Date date;
  try {
   date = getDefaultDateFormat().parse(s);
  } catch (ParseException e) {
   date = getNowDate();
  }
  setDate(date);
 }

 public void setText(SimpleDateFormat df, String s) {
  Date date;
  try {
   date = df.parse(s);
  } catch (ParseException e) {
   date = getNowDate();
  }
  setDate(date);
 }

 public void setDate(Date date) {
  super.setText(preLabel + getDefaultDateFormat().format(date));
 }

 public Date getDate() {
  String dateString = getText().substring(preLabel.length());
  try {
   return getDefaultDateFormat().parse(dateString);
  } catch (ParseException e) {
   return getNowDate();
  }

 }

 // 覆盖父类的方法使之无效
 public void addActionListener(ActionListener listener) {
 }

 private class DateChooser extends JPanel implements ActionListener,
   ChangeListener {
  int startYear = 1980; // 默认【最小】显示年份
  int lastYear = 2050; // 默认【最大】显示年份
  int width = 400; // 界面宽度
  int height = 200; // 界面高度

  Color backGroundColor = Color.gray; // 底色
  // 月历表格配色----------------//
  Color palletTableColor = Color.white; // 日历表底色
  Color todayBackColor = Color.orange; // 今天背景色
  Color weekFontColor = Color.blue; // 星期文字色
  Color dateFontColor = Color.black; // 日期文字色
  Color weekendFontColor = Color.red; // 周末文字色

  // 控制条配色------------------//
  Color controlLineColor = Color.pink; // 控制条底色
  Color controlTextColor = Color.white; // 控制条标签文字色

  Color rbFontColor = Color.white; // RoundBox文字色
  Color rbBorderColor = Color.red; // RoundBox边框色
  Color rbButtonColor = Color.pink; // RoundBox按钮色
  Color rbBtFontColor = Color.red; // RoundBox按钮文字色

  JDialog dialog;
  JSpinner yearSpin;
  JSpinner monthSpin;
  JSpinner hourSpin;
  JComboBox minSpin;
  JComboBox secondBox;
  JButton[][] daysButton = new JButton[6][7];

  DateChooser() {

   setLayout(new BorderLayout());
   setBorder(new LineBorder(backGroundColor, 2));
   setBackground(backGroundColor);

   JPanel topYearAndMonth = createYearAndMonthPanal();
   add(topYearAndMonth, BorderLayout.NORTH);
   JPanel centerWeekAndDay = createWeekAndDayPanal();
   add(centerWeekAndDay, BorderLayout.CENTER);

  }

  private JPanel createYearAndMonthPanal() {

   Calendar c = getCalendar();
   int currentYear = c.get(Calendar.YEAR);
   int currentMonth = c.get(Calendar.MONTH) + 1;
   int currentHour = c.get(Calendar.HOUR_OF_DAY);
   int currentMin = c.get(Calendar.MINUTE);
   int currentSecond = c.get(Calendar.SECOND);

   JPanel result = new JPanel();
   result.setLayout(new FlowLayout());
   result.setBackground(controlLineColor);

   yearSpin = new JSpinner(new SpinnerNumberModel(currentYear,
     startYear, lastYear, 1));
   yearSpin.setPreferredSize(new Dimension(48, 20));
   yearSpin.setName("Year");
   yearSpin.setEditor(new JSpinner.NumberEditor(yearSpin, "####"));
   yearSpin.addChangeListener(this);
   result.add(yearSpin);

   JLabel yearLabel = new JLabel("年");
   yearLabel.setForeground(controlTextColor);
   result.add(yearLabel);

   monthSpin = new JSpinner(new SpinnerNumberModel(currentMonth, 1,
     12, 1));
   monthSpin.setPreferredSize(new Dimension(35, 20));
   monthSpin.setName("Month");
   monthSpin.addChangeListener(this);
   result.add(monthSpin);

   JLabel monthLabel = new JLabel("月");
   monthLabel.setForeground(controlTextColor);
   result.add(monthLabel);

   hourSpin = new JSpinner(new SpinnerNumberModel(currentHour, 0, 23,
     1));
   hourSpin.setPreferredSize(new Dimension(35, 20));
   hourSpin.setName("Hour");
   hourSpin.addChangeListener(this);
   result.add(hourSpin);

   JLabel hourLabel = new JLabel("时");
   hourLabel.setForeground(controlTextColor);
   result.add(hourLabel);

   minSpin = new JComboBox();
   ;
   addComboBoxItem(minSpin);
   minSpin.setPreferredSize(new Dimension(45, 20));
   minSpin.setName("Min");
   minSpin.addItemListener(new java.awt.event.ItemListener() {
    public void itemStateChanged(java.awt.event.ItemEvent e) {
     JComboBox source = (JComboBox) e.getSource();
     Calendar c = getCalendar();
     if (source.getName().equals("Min")) {
      c.set(Calendar.MINUTE, getSelectedMin());
      setDate(c.getTime());
      return;
     }
    }
   });
   result.add(minSpin);

   JLabel minLabel = new JLabel("分");
   hourLabel.setForeground(controlTextColor);
   result.add(minLabel);

   secondBox = new JComboBox();
   addComboBoxItem(secondBox);
   secondBox.setPreferredSize(new Dimension(45, 20));
   secondBox.setName("Second");
   // secondBox.addActionListener(this) ;
   secondBox.addItemListener(new java.awt.event.ItemListener() {
    public void itemStateChanged(java.awt.event.ItemEvent e) {
     JComboBox source = (JComboBox) e.getSource();
     Calendar c = getCalendar();
     if (source.getName().equals("Second")) {
      c.set(Calendar.SECOND, getSelectedSecond());
      setDate(c.getTime());
      return;
     }
    }
   });

   result.add(secondBox);

   JLabel secondLabel = new JLabel("秒");
   hourLabel.setForeground(controlTextColor);
   result.add(secondLabel);

   return result;
  }

  private void addComboBoxItem(JComboBox comboBox) {
   for (int i = 0; i < 60; i++) {
    comboBox.addItem(i);
   }

  }

  private JPanel createWeekAndDayPanal() {
   String colname[] = { "日", "一", "二", "三", "四", "五", "六" };
   JPanel result = new JPanel();
   // 设置固定字体,以免调用环境改变影响界面美观
   result.setFont(new Font("宋体", Font.PLAIN, 12));
   result.setLayout(new GridLayout(7, 7));
   result.setBackground(Color.white);
   JLabel cell;

   for (int i = 0; i < 7; i++) {
    cell = new JLabel(colname[i]);
    cell.setHorizontalAlignment(JLabel.RIGHT);
    if (i == 0 || i == 6)
     cell.setForeground(weekendFontColor);
    else
     cell.setForeground(weekFontColor);
    result.add(cell);
   }

   int actionCommandId = 0;
   for (int i = 0; i < 6; i++)
    for (int j = 0; j < 7; j++) {
     JButton numberButton = new JButton();
     numberButton.setBorder(null);
     numberButton.setHorizontalAlignment(SwingConstants.RIGHT);
     numberButton.setActionCommand(String
       .valueOf(actionCommandId));
     numberButton.addActionListener(this);
     numberButton.setBackground(palletTableColor);
     numberButton.setForeground(dateFontColor);
     if (j == 0 || j == 6)
      numberButton.setForeground(weekendFontColor);
     else
      numberButton.setForeground(dateFontColor);
     daysButton[i][j] = numberButton;
     result.add(numberButton);
     actionCommandId++;
    }

   return result;
  }

  private JDialog createDialog(Frame owner) {
   JDialog result = new JDialog(owner, "日期时间选择", true);
   result.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
   result.getContentPane().add(this, BorderLayout.CENTER);
   result.pack();
   result.setSize(width, height);
   return result;
  }

  void showDateChooser(Point position) {
   Frame owner = (Frame) SwingUtilities
     .getWindowAncestor(DateChooseJButton.this);
   if (dialog == null || dialog.getOwner() != owner)
    dialog = createDialog(owner);
   dialog.setLocation(getAppropriateLocation(owner, position));
   flushWeekAndDay();
   dialog.show();
  }

  Point getAppropriateLocation(Frame owner, Point position) {
   Point result = new Point(position);
   Point p = owner.getLocation();
   int offsetX = (position.x + width) - (p.x + owner.getWidth());
   int offsetY = (position.y + height) - (p.y + owner.getHeight());

   if (offsetX > 0) {
    result.x -= offsetX;
   }

   if (offsetY > 0) {
    result.y -= offsetY;
   }

   return result;

  }

  private Calendar getCalendar() {
   Calendar result = Calendar.getInstance();
   result.setTime(getDate());
   return result;
  }

  private int getSelectedYear() {
   return ((Integer) yearSpin.getValue()).intValue();
  }

  private int getSelectedMonth() {
   return ((Integer) monthSpin.getValue()).intValue();
  }

  private int getSelectedHour() {
   return ((Integer) hourSpin.getValue()).intValue();
  }

  private int getSelectedMin() {
   return (Integer) this.minSpin.getSelectedItem();
  }

  private int getSelectedSecond() {
   return (Integer) this.secondBox.getSelectedItem();
  }

  private void dayColorUpdate(boolean isOldDay) {
   Calendar c = getCalendar();
   int day = c.get(Calendar.DAY_OF_MONTH);
   c.set(Calendar.DAY_OF_MONTH, 1);
   int actionCommandId = day - 2 + c.get(Calendar.DAY_OF_WEEK);
   int i = actionCommandId / 7;
   int j = actionCommandId % 7;
   if (isOldDay)
    daysButton[i][j].setForeground(dateFontColor);
   else
    daysButton[i][j].setForeground(todayBackColor);
  }

  private void flushWeekAndDay() {
   Calendar c = getCalendar();
   c.set(Calendar.DAY_OF_MONTH, 1);
   int maxDayNo = c.getActualMaximum(Calendar.DAY_OF_MONTH);
   int dayNo = 2 - c.get(Calendar.DAY_OF_WEEK);
   for (int i = 0; i < 6; i++) {
    for (int j = 0; j < 7; j++) {
     String s = "";
     if (dayNo >= 1 && dayNo <= maxDayNo)
      s = String.valueOf(dayNo);
     daysButton[i][j].setText(s);
     dayNo++;
    }
   }
   dayColorUpdate(false);
  }

  public void stateChanged(ChangeEvent e) {
   JSpinner source = (JSpinner) e.getSource();
   Calendar c = getCalendar();
   if (source.getName().equals("Hour")) {
    c.set(Calendar.HOUR_OF_DAY, getSelectedHour());
    setDate(c.getTime());
    return;
   }

   dayColorUpdate(true);

   if (source.getName().equals("Year"))
    c.set(Calendar.YEAR, getSelectedYear());
   else
    // (source.getName().equals("Month"))
    c.set(Calendar.MONTH, getSelectedMonth() - 1);
   setDate(c.getTime());
   flushWeekAndDay();
  }

  public void actionPerformed(ActionEvent e) {
   JButton source = (JButton) e.getSource();
   if (source.getText().length() == 0)
    return;
   dayColorUpdate(true);
   source.setForeground(todayBackColor);
   int newDay = Integer.parseInt(source.getText());
   Calendar c = getCalendar();
   c.set(Calendar.DAY_OF_MONTH, newDay);
   setDate(c.getTime());
  }

 }

 public static void main(String[] args){
  new JButton();
 }
}

上述日期控件继承JButton,使用时只要构造出来JButton对象就行了。


posted @ 2011-11-04 12:32 甜咖啡 阅读(4442) | 评论 (1)编辑 收藏

package com.wss;

import java.awt.BorderLayout;

public class SearchTest extends JFrame {

 /**
  *
  */
 private static final long serialVersionUID = 1L;
 private JPanel contentPane;
 private JTextField latitude;
 private JTextField longitude;
 private JTextField max;
 private JTextField min;
 private JTextField center;
 private JComboBox begin;
 private JComboBox end;
 private JTable table;
 private DefaultTableModel dm;
 /**
  * Launch the application.
  */
 public static void main(String[] args) {
  EventQueue.invokeLater(new Runnable() {
   public void run() {
    try {
     SearchTest frame = new SearchTest();
     frame.setVisible(true);
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  });
 }

 /**
  * Create the frame.
  */
 public SearchTest() {
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  getToolkit();
  setSize(Toolkit.getDefaultToolkit().getScreenSize());
  contentPane = new JPanel();
  contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
  contentPane.setLayout(new BorderLayout(0, 0));
  setContentPane(contentPane);
  
  JPanel panel = new JPanel();
  contentPane.add(panel, BorderLayout.NORTH);
  
  JLabel label = new JLabel("纬度:");
  panel.add(label);
  
  latitude = new JTextField();
  panel.add(latitude);
  latitude.setColumns(10);
  
  JLabel label_1 = new JLabel("经度:");
  panel.add(label_1);
  
  longitude = new JTextField();
  panel.add(longitude);
  longitude.setColumns(10);
  
  JLabel label_2 = new JLabel("时间:");
  panel.add(label_2);
  
  //获取数据库里的时间正序输出
  List<GPSBean> list_ = BusinessSelect.selectTime("select distinct to_char(obvdatetime,'YYYY-mm-dd HH24:MI:SS') t from gps order by t asc");
  String[] time = new String[list_.size()];
  for(int a=0; a<list_.size(); a++){
   time[a] = list_.get(a).getTime();
  }
  begin = new JComboBox(time);
  panel.add(begin);
  
  JLabel label_3 = new JLabel("至");
  panel.add(label_3);
  
  end = new JComboBox(time);
  panel.add(end);
    
  JButton close = new DateChooseJButton();
  panel.add(close);
  
  //点击事件
  search.addActionListener(new SearchTest_search_actionAdapter(this));
  
  JPanel panel_1 = new JPanel();
  contentPane.add(panel_1, BorderLayout.CENTER);
  
  String name[] = {"ID","时间","纬度","经度","值"};
  String sql = "select * from gps order by id desc";
  List<GPSBean> list = BusinessSelect.selectGPS(sql);
  Object gpsValue[][] = new Object[list.size()][5];
  
  for(int i=0; i<list.size(); i++){
   GPSBean gpsBean = list.get(i);
   Object value[] =
    {
     gpsBean.getId(),
     gpsBean.getObvdateTime(),
     gpsBean.getLongitude(),
     gpsBean.getLatitude(),
     gpsBean.getTecvalue()
    };
   for(int j=0; j<value.length; j++){
    gpsValue[i][j] = value[j];
   }
  }
  
  dm = new DefaultTableModel(gpsValue, name);
  table = new JTable(dm);
  table.setPreferredScrollableViewportSize(new Dimension(800,600));
  
  JScrollPane scrollPane = new JScrollPane(table);
  panel_1.add(scrollPane);
  
  JPanel panel_s = new JPanel();
  contentPane.add(panel_s, BorderLayout.SOUTH);
  
  JLabel max_ = new JLabel("最大值:");
  panel_s.add(max_);
  
  max = new JTextField();
  panel_s.add(max);
  max.setColumns(10);
  
  JLabel min_ = new JLabel("最小值:");
  panel_s.add(min_);
  
  min = new JTextField();
  panel_s.add(min);
  min.setColumns(10);
  
  JLabel center_ = new JLabel("中值:");
  panel_s.add(center_);
  
  center = new JTextField();
  panel_s.add(center);
  center.setColumns(10);
 }
 
 public void search_actionPerformed(ActionEvent e){
  dm.setRowCount(0);
  String latitude_value = latitude.getText();
  String longitude_value = longitude.getText();
  
  String begin_value = begin.getSelectedItem().toString();
  String end_value = end.getSelectedItem().toString();
  
  String sql = "";
  
  if(latitude_value.equals("") && longitude_value.equals("")){
   sql = "select * from (select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS') as d, latitude, longitude, tecvalue, abs(latitude-0) a, abs(longitude-0) b " +
     "from gps where obvdateTime>=TO_DATE('"+begin_value
    +"','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('"+end_value
    +"','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc) where a<3 and b<5 order by d asc, a asc,b asc";
  }else{
   sql = "select * from (select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS') as d, latitude, longitude, tecvalue, abs(latitude-"
     +Double.parseDouble(latitude_value)
     +") a, abs(longitude-"+Double.parseDouble(longitude_value)
     +") b from gps where obvdateTime>=TO_DATE('"+begin_value
     +"','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('"+end_value
     +"','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc) where a<3 and b<5 order by d asc, a asc,b asc";
  }
  
  ResultSet rs = CommontDAO.selectFile(sql);
  Vector<Object> v;
  String time = "2011-02-28 00:00:00";
  List<GPSBean> gpsBeanList = new ArrayList<GPSBean>();
  try{
   while(rs.next()){
    if(time.equals(rs.getString(2)) || time == rs.getString(2)){
    }else{
     GPSBean gpsBean = new GPSBean();
     gpsBean.setId(Integer.parseInt(rs.getString(1)));
     gpsBean.setObvdateTime(rs.getString(2));
     gpsBean.setLatitude(Double.parseDouble(rs.getString(3)));
     gpsBean.setLongitude(Double.parseDouble(rs.getString(4)));
     gpsBean.setTecvalue(Double.parseDouble(rs.getString(5)));
     gpsBeanList.add(gpsBean);
     
     time = rs.getString(2);
     v = new Vector<Object>();
     v.add(rs.getString(1));
     v.add(rs.getString(2));
     v.add(rs.getString(3));
     v.add(rs.getString(4));
     v.add(rs.getString(5));
     dm.addRow(v);
    }
   }
  }catch(Exception ex){
   ex.printStackTrace();
   System.out.println(ex.getMessage());
  }finally{
   CommontDAO.cloes(rs);
   Double tecValue[] = new Double[gpsBeanList.size()];
   for(int i=0; i<gpsBeanList.size(); i++){
    tecValue[i] = gpsBeanList.get(i).getTecvalue();
   }
   
   Double center_value = Sort.center(tecValue);
   Double max_value = Sort.max(tecValue);
   Double min_value = Sort.min(tecValue);
   
   
   max.setText(max_value+"");
   min.setText(min_value+"");
   center.setText(center_value+"");
  }
 }
}
class SearchTest_search_actionAdapter implements ActionListener {
 private SearchTest adaptee;

 SearchTest_search_actionAdapter(SearchTest adaptee) {
  this.adaptee = adaptee;
 }

 public void actionPerformed(ActionEvent e) {
  adaptee.search_actionPerformed(e);
 }
}




package com.wss;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.sql.*;
import java.util.*;

public class BusinessSelect {

 //根据sql查询记录
 public static List<GPSBean> selectGPS(String sql){
  ResultSet rs = null;
  List<GPSBean> list = new ArrayList<GPSBean>();
  try{
   rs = CommontDAO.selectFile(sql);
   while(rs.next()){
    GPSBean gpsBean = new GPSBean();
    gpsBean.setId(Integer.parseInt(rs.getString(1)));
    gpsBean.setObvdateTime(rs.getString(2));
    gpsBean.setLongitude(Double.parseDouble(rs.getString(3)));
    gpsBean.setLatitude(Double.parseDouble(rs.getString(4)));
    gpsBean.setTecvalue(Double.parseDouble(rs.getString(5)));
    list.add(gpsBean);
//    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
   } 
   return list;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return null;
  }finally{
   CommontDAO.cloes(rs);
  }
 }
 
 //搜索(根据经度和纬度查询最近一点的记录)
 public static List<GPSBean> selectGPS(Double latitude_, Double longitude_){
  ResultSet rs = null;
  List<GPSBean> list = new ArrayList<GPSBean>();
  try{
   //获取比指定点大的最近的1个值
   String sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a from gps order by a desc";
   rs = CommontDAO.selectFile(sql);
   while(rs.next()){
    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6));
   }
   System.out.println("---------------------------------------------------------------------------");
   
   sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(longitude-"+longitude_+") b from gps order by b desc";
   rs = CommontDAO.selectFile(sql);
   while(rs.next()){
//    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6));
   }
   System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
   
   sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a, abs(longitude-"+longitude_+") b from gps order by a asc, b asc";
   //重要
//   sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a, abs(longitude-"+longitude_+") b from gps where obvdateTime>=TO_DATE('2011-03-01 00:00:00','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('2011-03-01 02:00:00','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc";
   while(rs.next()){
//    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7));
   }
   
   return list;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return null;
  }finally{
   CommontDAO.cloes(rs);
  }
 }
 
 //搜索(根据经度和纬度查询最近一点的记录)
 public static List<GPSBean> selectGPS(Double latitude_, Double longitude_, String begin, String end){
  ResultSet rs = null;
  List<GPSBean> list = new ArrayList<GPSBean>();
  String sql = "select id, to_char(obvdateTime,'YYYY-mm-dd HH24:MI:SS'), latitude, longitude, tecvalue, abs(latitude-"+latitude_+") a, abs(longitude-"+longitude_+") b from gps where obvdateTime>=TO_DATE('"+begin+"','YYYY-mm-dd HH24:MI:SS') and obvdateTime<=TO_DATE('"+end+"','YYYY-mm-dd HH24:MI:SS') order by a asc, b asc";
  rs = CommontDAO.selectFile(sql);
  String test = "";
  try{
   while(rs.next()){
    GPSBean gpsBean = new GPSBean();
    gpsBean.setId(Integer.parseInt(rs.getString(1)));
    gpsBean.setObvdateTime(rs.getString(2));
    gpsBean.setLatitude(Double.parseDouble(rs.getString(3)));
    gpsBean.setLongitude(Double.parseDouble(rs.getString(4)));
    gpsBean.setTecvalue(Double.parseDouble(rs.getString(5)));
    list.add(gpsBean);
//    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7));
//    System.out.println(rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5));
//    test += rs.getString(1)+","+rs.getString(2)+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7)+"\r\n";
   }
//   File f = new File("D:/test.txt");
//   OutputStream out = new FileOutputStream(f,true);
//   out.write(test.getBytes());
   return list;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return null;
  }finally{
   CommontDAO.cloes(rs);
  }
 }
 
 //获取时间
 public static List<GPSBean> selectTime(String sql){
  ResultSet rs = null;
  List<GPSBean> list = new ArrayList<GPSBean>();
  try{
   rs = CommontDAO.selectFile(sql);
   while(rs.next()){
    GPSBean gpsBean = new GPSBean();
    gpsBean.setTime(rs.getString(1));
    list.add(gpsBean);
   } 
   return list;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return null;
  }finally{
   CommontDAO.cloes(rs);
  }
 }
}

 




package com.wss;

public class GPSBean {

 private int id;
 private String obvdateTime;
 private double longitude;
 private double latitude;
 private double tecvalue;
 private String time;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getObvdateTime() {
  return obvdateTime;
 }
 public void setObvdateTime(String obvdateTime) {
  this.obvdateTime = obvdateTime;
 }
 public double getLongitude() {
  return longitude;
 }
 public void setLongitude(double longitude) {
  this.longitude = longitude;
 }
 public double getLatitude() {
  return latitude;
 }
 public void setLatitude(double latitude) {
  this.latitude = latitude;
 }
 public double getTecvalue() {
  return tecvalue;
 }
 public void setTecvalue(double tecvalue) {
  this.tecvalue = tecvalue;
 }
 public String getTime() {
  return time;
 }
 public void setTime(String time) {
  this.time = time;
 }
}





package com.wss;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.db.DBConnectionManager;

public class CommontDAO {

 private static DBConnectionManager dbcm = DBConnectionManager.getInstance();
 
 //insert语句(支持多条sql)
 public static boolean insertFile(String sql){
  Connection con = null;
  Statement st = null;
  try{
   con = dbcm.getConnection();
   st = con.createStatement();
   sql = sql.substring(0, sql.length()-1);
   String[] num = sql.split(";");
   for(int i=0; i<num.length; i++){
    st.addBatch(num[i]);
   }
   st.executeBatch();
   return true;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return false;
  }finally{
   close(con, st);
  }
 }

 //select语句(返回一个ResultSet)
 public static ResultSet selectFile(String sql){
  Connection con = null;
  Statement st = null;
  ResultSet rs = null;
  try{
   con = dbcm.getConnection();
   st = con.createStatement();
   rs = st.executeQuery(sql);
   return rs;
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
   return rs;
  }
 }

 public static void close(Connection con){
  try{
   if(con != null){
    con.close();
   }
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
  }
 }

 public static void close(Connection con, Statement st){
  try{
   if(st != null){
    st.close();
   }
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
  }
  close(con);
 }
 
 public static void close(Connection con, Statement st, ResultSet rs){
  try{
   if(rs != null){
    rs.close();
   }
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
  }
  close(con, st);
 }
 
 public static void cloes(ResultSet rs){
  try{
   if(rs != null){
    rs.close();
   }
  }catch(Exception e){
   e.printStackTrace();
   System.out.println(e.getMessage());
  }
 }
}






package com.wss;

public class Sort {

 //求最大值
 public static Double max(Double[] value){
  //把数组第一个值最为一个标志
  Double num1 = value[0];
  //中间变量
  Double temp = 0.0;
  for(int i=1; i<value.length; i++){
   if(num1 < value[i]){
    temp = num1;
    num1 = value[i];
    value[i] = temp;
   }
  }
  return num1;
 }
 
 //求最小值
 public static Double min(Double[] value){
  //把数组第一个值最为一个标志
  Double num1 = value[0];
  //中间变量
  Double temp = 0.0;
  for(int i=0; i<value.length; i++){
   if(num1 > value[i]){
    temp = num1;
    num1 = value[i];
    value[i] = temp;
   }
  }
  return num1;
 }
 
 //求中值
 public static Double center(Double[] value){
  Double temp = 0.0;
  //排序
  for(int i=0; i<value.length; i++){
   for(int j=i+1; j<value.length; j++){
    if(value[i] > value[j]){
     temp = value[j];
     value[j] = value[i];
     value[i] = temp;
    }
   }
  }
  //求中值所在的下标位置
  int num = value.length/2;
  return value[num];
  
 }
 
 public static void main(String[] args){
  Double value[] = {4.0, 1.0, 2.0, 3.0};
  System.out.println(Sort.center(value));
 }
}







posted @ 2011-11-04 12:31 甜咖啡 阅读(1588) | 评论 (0)编辑 收藏
DWR(Direct Web Remoting)是一个WEB远程调用框架.利用这个框架可以让AJAX开发变得很简单.利用DWR可以在客户端利用JavaScript直接调用服务端的Java方法并返回值给JavaScript就好像直接本地客户端调用一样(DWR根据Java类来动态生成JavaScrip代码).它的最新版本DWR0.6添加许多特性如:支持Dom Trees的自动配置,支持Spring(JavaScript远程调用spring bean),更好浏览器支持,还支持一个可选的commons-logging日记操作.

以上摘自open-open,它通过反射,将java翻译成javascript,然后利用回调机制,轻松实现了javascript调用Java代码。

其大概开发过程如下:
1.编写业务代码,该代码是和dwr无关的。
2.确认业务代码中哪些类、哪些方法是要由javascript直接访问的。
3.编写dwr组件,对步骤2的方法进行封装。
4.配置dwr组件到dwr.xml文件中,如果有必要,配置convert,进行java和javascript类型互转。
5.通过反射机制,dwr将步骤4的类转换成javascript代码,提供给前台页面调用。
5.编写网页,调用步骤5的javascript中的相关方法(间接调用服务器端的相关类的方法),执行业务逻辑,将执行结果利用回调函数返回。
6.在回调函数中,得到执行结果后,可以继续编写业务逻辑的相关javascript代码。

下面以用户注册的例子,来说明其使用。(注意,本次例子只是用于演示,说明DWR的使用,类设计并不是最优的)。

1.先介绍下相关的Java类

  User: 用户类,
  public class User {
//登陆ID,主键唯一
private String id;
//姓名
private String name;
//口令
private String password;
//电子邮件
private String email;
        
//以下包含getXXX和setXXX方法
.......
  }

  UserDAO:实现User的数据库访问,这里作为一个演示,编写测试代码
  public class UserDAO {
    //存放保存的数据
    private static Map dataMap = new HashMap();

    //持久用户
    public boolean save(User user) {
      if (dataMap.containsKey(user.getId()))
        return false;
      System.out.println("下面开始保存用户");
      System.out.println("id:"+user.getId());
      System.out.println("password:"+user.getPassword());
      System.out.println("name:"+user.getName());
      System.out.println("email:"+user.getEmail());
      dataMap.put(user.getId(), user);
      System.out.println("用户保存结束");
      return true;
    }

    //查找用户
    public User find(String id) {
      return (User)dataMap.get(id);
    }
}

  DWRUserAccess:DWR组件,提供给javascript访问的。

  public class DWRUserAccess {

      UserDAO userDAO = new UserDAO();

      public boolean save(User user) {
        return userDAO.save(user);
      }

      public User find(String id) {
        return userDAO.find(id);
      }
  }
  

  下面说明下程序执行的流程

  1.用户在页面上输入相关注册信息,id、name、password、email,点击“提交”按钮
  2.javascript代码开始执行,根据用户填写相关信息,通过dwr提供的DWRUserAccess.js里save的方法,调用服务器端的DWRUserAccess类save方法,将注册信息保存。
  3.通过DWRUserAccess.jsp里的find方法,调用服务器端DWRUserAccess类里的find方法,执行用户信息查找。

  注意,在以上的执行过程中,DWRUserAccess是供DWR调用的,是DWR组件,因此需要将DWRUserAccess类配置到dwr中。

  接下来讲解本次dwr测试环境的配置。

  1.新建一个webapp,命名为testApp
  2.将dwr.jar拷贝到testApp的WEB-INF的lib目录下
  3.编译上面的User,UserDAO,DWRUserAccess类,放到classes目录下
  4.在web.xml中配置servlet,适配路径到dwr目录下,如下所示
    <servlet>
    <servlet-name>dwr-invoker</servlet-name>
    <display-name>DWR Servlet</display-name>
    <description>Direct Web Remoter Servlet</description>
    <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
    <init-param>
      <param-name>debug</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>scriptCompressed</param-name>
      <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dwr-invoker</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
  </servlet-mapping>

  以上的配置可以拦截testApp下所有指向dwr的请求,关于这个拦截器,我们会在后面介绍。

  5.WEB-INF下新建一个dwr.xml文件,内容如下:
  < xml version="1.0" encoding="UTF-8" >
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
  <allow>
<create creator="new" javascript="DWRUserAccess">
      <param name="class" value="test.DWRUserAccess"/>
    </create>
<convert converter="bean" match="test.User"/>
  </allow>
</dwr>

  这里我们把DWRUserAccess配置到了dwr中,create元素中,creater="new"表示每调用一次DWRUserAccess时,需要new一个这样的类;javascript="DWRUserAccess",表示提供给前台页面调用的javascirpt文件是DWRUserAccess.js。

  convert元素用于数据类型转换,即java类和javascript之间相互转换,因为和前台交换的是User对象,因此需要对此使用bean转换,我们将在后面介绍这个类。

  4.编写测试的HTML页面 test.html
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>DWR测试</TITLE>
<meta http-equiv=Content-Type content="text/html; charset=gb2312">
<script src="/oblog312/dwr/engine.js"></script>
<script src="/oblog312/dwr/util.js"></script>
<script src="/oblog312/dwr/interface/DWRUserAccess.js"></script>
</HEAD>
<BODY>
<B>用户注册</B><br>
------------------------------------------------
<Br>
<form name="regForm">
登陆ID:<input type="text" name="id"><br>
口  令:<input type="password" name="password"><br>
姓  名:<input type="text" name="name"><br>
电子邮件:<input type="text" name="email"><br>
<input type="button" name="submitBtn" value="提交" onclick="OnSave()"><br>
    </form>

<br>
<br><B>用户查询</B><br>
------------------------------------------------
<Br>
<form name="queryForm">
登陆ID:<input type="text" name="id"><br>
<input type="button" name="submitBtn" value="提交" onclick="OnFind()"><br>
</form>
<br>
</BODY>
</HTML>
<SCRIPT LANGUAGE="JavaScript">
<!--
function saveFun(data) {
if (data) {
  alert("注册成功!");
} else {
  alert("登陆ID已经存在!");
}
}

function OnSave() {
var userMap = {};
userMap.id = regForm.id.value;
userMap.password = regForm.password.value;
userMap.name = regForm.name.value;
userMap.email = regForm.email.value;
DWRUserAccess.save(userMap, saveFun);
}

function findFun(data) {
if (data == null) {
  alert("无法找到用户:"+queryForm.id.value);
  return;
}

alert("找到用户,nid:"+data.id+",npassword:"+data.password+",nname:"+data.name+",nemail:"+data.email);

}

function OnFind() {
DWRUserAccess.find(queryForm.id.value, findFun);
}
//-->
</SCRIPT>


以下对页面的javascript进行解释

<script src="/oblog312/dwr/engine.js"></script>
<script src="/oblog312/dwr/util.js"></script>
这两个是dwr提供的,用户可以不必关心,只需要导入即可

<script src="/oblog312/dwr/interface/DWRUserAccess.js"></script>
是我们编写的DWRUserAccess类,经dwr反射后,生成的javascript代码,它和DWRUserAccess.java是对应的,供用户调用,实际上我们就是通过这个js文件去调用服务器端的DWRUserAccess类的。

<SCRIPT LANGUAGE="JavaScript">
<!--
function saveFun(data) {
if (data) {
  alert("注册成功!");
} else {
  alert("用户名已经存在!");
}
}

function OnSave() {
var userMap = {};
userMap.id = regForm.id.value;
userMap.password = regForm.password.value;
userMap.name = regForm.name.value;
userMap.email = regForm.email.value;
DWRUserAccess.save(userMap, saveFun);
}

function findFun(data) {
if (data == null) {
  alert("无法找到用户:"+queryForm.id.value);
  return;
}

alert("找到用户,nid:"+data.id+",npassword:"+data.password+",nname:"+data.name+",nemail:"+data.email);

}

function OnFind() {
DWRUserAccess.find(queryForm.id.value, findFun);
}
//-->
</SCRIPT>

这段javascirpt代码,我们来看下OnSave函数,首先它构造一个map,将表单数据都设置到map中,然后调用DWRUserAccess.save(userMap, saveFun),执行save操作。大家可以注意到,服务器端的DWRUserAccess中的save方法是这样的:boolean save(User user),其参数是一个User对象,返回一个boolean值;而客户端的方法是这样的:save(userMap,saveFun),第一个参数userMap是javascirpt中的map对象,在这里相当于服务器端的User对象(在服务器端执行时,会通过convert转换成User对象),前面我们提到dwr是利用回调函数来返回执行结果的,第二个参数saveFun即是一个回调函数。在函数function saveFun(data)中,data是执行结果,这里是一个bool值,非常简单的,我们通过判断data是否为真,可以知道用户名是否重复,用户是否注册成功。

看一下OnFind查找函数,执行结果在回调函数findFun(data)中,因为服务器端返回的是一个User对象,通过convert,将会转换成javascript的一个map对象,
于是在findFun中,通过data.id、data.name、data.password、data.email我们可以轻松的访问到这个User对象。


好了配置完毕,启动服务器,在目录中打入localhost/testApp/test.html。

1.在“用户注册”表单中,id框中输入admin,password中输入123456,name中输入chenbug,email中输入chenbug@zj.com,点击提交按钮,弹出对话框:“注册成功”,在服务器后台可以看到信息如下:

下面开始保存用户
id:admin
password:123456
name:chenbug
email:chenbug@zj.com
用户保存结束

再次点击提交按钮,弹出对话框“登陆ID已经存在”。

2.在“用户查询”对话框中,输入登陆ID为admin,点击提交按钮,提示找到用户,并显示相关信息,输入admin123,点击提交按钮,提示无法找到用户。

至此,测试结束。


后续:
1。拦截器 uk.ltd.getahead.dwr.DWRServlet
该类拦截所有指向dwr目录下的请求,并调用Processor的handler方法进行处理,在uk.ltd.getahead.dwr.impl.DefaultProcessor下,我们可以看到详细的处理过程。
if (pathInfo.length() == 0 ||
            pathInfo.equals(HtmlConstants.PATH_ROOT) ||
            pathInfo.equals(req.getContextPath()))
        {
            resp.sendRedirect(req.getContextPath() + servletPath + HtmlConstants.FILE_INDEX);
        }
        else if (pathInfo.startsWith(HtmlConstants.FILE_INDEX))
        {
            index.handle(req, resp);
        }
        else if (pathInfo.startsWith(HtmlConstants.PATH_TEST))
        {
            test.handle(req, resp);
        }
        else if (pathInfo.startsWith(HtmlConstants.PATH_INTERFACE))
        {
            iface.handle(req, resp);
        }
        else if (pathInfo.startsWith(HtmlConstants.PATH_EXEC))
        {
            exec.handle(req, resp);
        }
        else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_ENGINE))
        {
            file.doFile(req, resp, HtmlConstants.FILE_ENGINE, HtmlConstants.MIME_JS);
        }
        else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_UTIL))
        {
            file.doFile(req, resp, HtmlConstants.FILE_UTIL, HtmlConstants.MIME_JS);
        }
        else if (pathInfo.equalsIgnoreCase(HtmlConstants.FILE_DEPRECATED))
        {
            file.doFile(req, resp, HtmlConstants.FILE_DEPRECATED, HtmlConstants.MIME_JS);
        }
        else
        {
            log.warn("Page not found (" + pathInfo + "). In debug/test mode try viewing /[WEB-APP]/dwr/"); //$NON-NLS-1$ //$NON-NLS-2$
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
        }

通过判断request请求的servlet路径,进行处理,大家可以自己去参看,这里不详细讨论。


2.bean转换器,<convert converter="bean" match="test.User"/>
将dwr.jar解压缩,在路径ukltdgetaheaddwr下可以看到dwr.xml,这里配置了系统默认的一些转换器,
<converter id="bean" class="uk.ltd.getahead.dwr.convert.BeanConverter"/>即是刚才用到User类的转换器,进入代码我们来看看它是如何在javascript和java间进行转换的。

打开BeanConverter代码,定位到函数

public Object convertInbound(Class paramType, InboundVariable iv, InboundContext inctx) throws ConversionException

即是将javascript对象转换成java对象的,其中
paramType即Class类型,在上面的例子中是test.User,
InboundVariable iv,是传入的值,通过iv.getValue可以得到传入的javascript值串
InboundContext inctx,是入口参数上下文,用于保存转换的后java对象。

因为前台传入的是一个javascript的map类型,而map肯定是以{开始和以}结束的,于是在这个函数一开始进行了判断
if (!value.startsWith(ConversionConstants.INBOUND_MAP_START))
        {
            throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingOpener", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$
        }

        if (!value.endsWith(ConversionConstants.INBOUND_MAP_END))
        {
            throw new IllegalArgumentException(Messages.getString("BeanConverter.MissingCloser", ConversionConstants.INBOUND_MAP_START)); //$NON-NLS-1$
        }

javascript中,map里各个项是用逗号连接的,如var userMap = {id:'admin',password:'123456',name:'chenbug',email:'chenbug@zj.com'};而每个项的键值对是用冒号连接的,
在convertInbound函数的接下来的处理中,即是通过分析map字串,通过paramType构造java实例(即User类),然后通过反射,将这些键值对设置到java实例中,并返回。
这样就完成了javascript到java的转换。


另一个函数
public String convertOutbound(Object data, String varname, OutboundContext outctx) throws ConversionException

即是将java对象转换为javascript对象(其实是声明和赋值语句)。
Object data ,是待转换的java对象
String varname,是javascript中的该对象的变量名
OutboundContext outctx,传出参数上下文,用于保存转换后的javascript值

StringBuffer buffer = new StringBuffer();
        buffer.append("var "); //$NON-NLS-1$
        buffer.append(varname);
        buffer.append("={};"); //$NON-NLS-1$
这里声明了map类型的变量。

即下来来的代码即是通过反射进行变量赋值,如下
  buffer.append(varname);
                    buffer.append('.');
                    buffer.append(name);
                    buffer.append('=');
                    buffer.append(nested.getAssignCode());
                    buffer.append(';');
大家可以自己去参看更多的代码。

3.dwr本身提供了一个测试环境,大家在配置完后,可以在IE中输入地址http://localhost/testApp/dwr/index.html,看到配置的各DWR组件,并进行相关测试。
posted @ 2011-10-13 09:36 甜咖啡 阅读(284) | 评论 (0)编辑 收藏

先准备好软件:

Apache官方下载地址:apache_2.0.55-win32-x86-no_ssl.msi更多版本在这里

php官方下载地址:php-5.0.5-Win32.zip更多镜像下载地址更多版本下载

mysql官方下载地址:mysql-4.1.14-win32.zip更多镜像下载地址更多版本下载

一、安装Apache,配置成功一个普通网站服务器

运行下载好的“apache_2.0.55-win32-x86-no_ssl.msi”,出现如下界面:

 

出现Apache HTTP Server 2.0.55的安装向导界面,点“Next”继续

 

确认同意软件安装使用许可条例,选择“I accept the terms in the license agreement”,点“Next”继续

 

将Apache安装到Windows上的使用须知,请阅读完毕后,按“Next”继续

 

设置系统信息,在Network Domain下填入您的域名(比如:goodwaiter.com),在Server Name下填入您的服务器名称(比如:www.goodwaiter.com,也就是主机名加上域名),在Administrator's Email Address下填入系统管理员的联系电子邮件地址(比如:yinpeng@xinhuanet.com),上述三条信息仅供参考,其中联系电子邮件地址会在当系统故障时提供给访问者,三条信息均可任意填写,无效的也行。下面有两个选择,图片上选择的是为系统所有用户安装,使用默认的80端口,并作为系统服务自动启动;另外一个是仅为当前用户安装,使用端口8080,手动启动。一般选择如图所示。按“Next”继续。]

 

选择安装类型,Typical为默认安装,Custom为用户自定义安装,我们这里选择Custom,有更多可选项。按“Next”继续

 

出现选择安装选项界面,如图所示,左键点选“Apache HTTP Server 2.0.55”,选择“This feature, and all subfeatures, will be installed on local hard drive.”,即“此部分,及下属子部分内容,全部安装在本地硬盘上”。点选“Change...”,手动指定安装目录。

 

我这里选择安装在“D:\”,各位自行选取了,一般建议不要安装在操作系统所在盘,免得操作系统坏了之后,还原操作把Apache配置文件也清除了。选“OK”继续。

 

返回刚才的界面,选“Next”继续。

 

确认安装选项无误,如果您认为要再检查一遍,可以点“Back”一步步返回检查。点“Install”开始按前面设定的安装选项安装。

 

正在安装界面,请耐心等待,直到出现下面的画面。

 

安装向导成功完成,这时右下角状态栏应该出现了下面的这个绿色图标,表示Apache服务已经开始运行,按“Finish”结束Apache的软件安装

 

我们来熟悉一下这个图标,很方便的,在图标上左键单击,出现如下界面,有“Start(启动)”、“Stop(停止)”、“Restart(重启动)”三个选项,可以很方便的对安装的Apache服务器进行上述操作。

 

好了现在我们来测试一下按默认配置运行的网站界面,在IE地址栏打“http://127.0.0.1”,点“转到”,就可以看到如下页面,表示Apache服务器已安装成功。

 

现在开始配置Apache服务器,使它更好的替我们服务,事实上,如果不配置,你的安装目录下的Apache2\htdocs文件夹就是网站的默认根目录,在里面放入文件就可以了。这里我们还是要配置一下,有什么问题或修改,配置始终是要会的,如图所示,“开始”、“所有程序”、“Apache HTTP Server 2.0.55”、“Configure Apache Server”、“Edit the Apache httpd conf Configuration file”,点击打开。

 

XP的记事本有了些小变化,很实用的一个功能就是可以看到文件内容的行、列位置,按下图所示,点“查看”,勾选“状态栏”,界面右下角就多了个标记,“Ln 78, Col 10”就表示“行 78,列 10”,这样可以迅速的在文件中定位,方便解说。当然,你也可以通过“编辑”,“查找”输入关键字来快速定位。每次配置文件的改变,保存后,必须在 Apache服务器重启动后生效,可以用前面讲的小图标方便的控制服务器随时“重启动”。

 

现在正式开始配置Apache服务器,“Ln 228”,或者查找关键字“DocumentRoot”(也就是网站根目录),找到如下图所示地方,然后将""内的地址改成你的网站根目录,地址格式请照图上的写,主要是一般文件地址的“\”在Apache里要改成“/”。

 

“Ln 253”,同样,你也可以通过查找“

 

“Ln321”,DirectoryIndex(目录索引,也就是在仅指定目录的情况下,默认显示的文件名),可以添加很多,系统会根据从左至右的顺序来优先显示,以单个半角空格隔开,比如有些网站的首页是index.htm,就在光标那里加上“index.htm ”文件名是任意的,不一定非得“index.html”,比如“test.php”等,都可以。

 

这里有一个选择配置选项,以前可能要配置,现在好像修正过来了,不用配置了,就是强制所有输出文件的语言编码,html文件里有语言标记(,这个就是设定文档语言为gb2312)的也会强制转换。如果打开的网页出现乱码,请先检查网页内有没有上述 html语言标记,如果没有,添加上去就能正常显示了。把“# DefaultLanguage nl”前面的“# ”去掉,把“nl”改成你要强制输出的语言,中文是“zh-cn”,保存,关闭。

 

好了,简单的Apache配置就到此结束了,现在利用先前的小图标重启动,所有的配置就生效了,你的网站就成了一个网站服务器,如果你加载了防火墙,请打开80或8080端口,或者允许Apache程序访问网络,否则别人不能访问。如果你有公网IP(一般ADSL或电话拨号上网的都是),就可以邀请所有能上网的朋友访问使用http://你的IP地址(IP地址查询可访问http://www.goodwaiter.com,查询内容内即是)你的网站了;如果你没有公网IP,也可以把内网IP地址告诉局域网内的其它用户,让他们通过http://你的内网IP地址,访问你的网站。

二、php的安装、以module方式,将php与apache结合使你的网站服务器支持php服务器脚本程序

将下载的php安装文件php-5.0.5-Win32.zip右键解压缩。

 

指定解压缩的位置,我的设定在“D:\php”

 

查看解压缩后的文件夹内容,找到“php.ini-dist”文件,将其重命名为“php.ini”,打开编辑,找到下面图中的地方, Ln385,有一个“register_globals = Off”值,这个值是用来打开全局变量的,比如表单送过来的值,如果这个值设为“Off”,就只能用“$_POST['变量名']、$_GET['变量名 ']”等来取得送过来的值,如果设为“On”,就可以直接使用“$变量名”来获取送过来的值,当然,设为“Off”就比较安全,不会让人轻易将网页间传送的数据截取。这个值是否改成“On”就看自己感觉了,是安全重要还是方便重要?

 

这里还有一个地方要编辑,功能就是使php能够直接调用其它模块,比如访问mysql,如下图所示,Ln563,选择要加载的模块,去掉前面的 “;”,就表示要加载此模块了,加载的越多,占用的资源也就多一点,不过也多不到哪去,比如我要用mysql,就要把“;extension= php_mysql.dll”前的“;”去掉。所有的模块文件都放在php解压缩目录的“ext”之下,我这里的截图是把所有能加载的模块都加载上去了,前面的“;”没去掉的,是因为“ext”目录下默认没有此模块,加载会提示找不到文件而出错。这里只是参考,一般不需要加载这么多,需要的加载上就可以了,编辑好后保存,关闭。

 

如果上一步加载了其它模块,就要指明模块的位置,否则重启Apache的时候会提示“找不到指定模块”的错误,这里介绍一种最简单的方法,直接将php安装路径、里面的ext路径指定到windows系统路径中——在“我的电脑”上右键,“属性”,选择“高级”标签,点选“环境变量”,在“系统变量”下找到“Path”变量,选择,双击或点击“编辑”,将“;D:\php;D:\php\ext”加到原有值的后面,当然,其中的“D:\php” 是我的安装目录,你要将它改为自己的php安装目录,如下图所示,全部确定。系统路径添加好后要重启电脑才能生效,可以现在重启,也可以在所有软件安装或配置好后重启。

 

现在开始将php以module方式与Apache相结合,使php融入Apache,照先前的方法打开Apache的配置文件,Ln 173,找到这里,添加进如图所示选中的两行,第一行“LoadModule php5_module D:/php/php5apache2.dll”是指以module方式加载php,第二行“PHPIniDir "D:/php"”是指明php的配置文件php.ini的位置,是当然,其中的“D:/php”要改成你先前选择的php解压缩的目录。

 

还是Apache的配置文件,Ln 757,加入“AddType application/x-httpd-php .php”、“AddType application/x-httpd-php .html”两行,你也可以加入更多,实质就是添加可以执行php的文件类型,比如你再加上一行“AddType application/x-httpd-php .htm”,则.htm文件也可以执行php程序了,你甚至还可以添加上一行“AddType application/x-httpd-php .txt”,让普通的文本文件格式也能运行php程序。

 

前面所说的目录默认索引文件也可以改一下,因为现在加了php,有些文件就直接存为.php了,我们也可以把“index.php”设为默认索引文件,优先顺序就自己排了,我的是放在第一位。编辑完成,保存,关闭。

 

现在,php的安装,与Apache的结合已经全部完成,用屏幕右下角的小图标重启Apache,你的Apache服务器就支持了php。

三、mysql的安装,与php、Apache相结合

打开下载的mysql安装文件mysql-4.1.14-win32.zip,双击解压缩,运行“setup.exe”,出现如下界面

 

mysql安装向导启动,按“Next”继续

 

选择安装类型,有“Typical(默认)”、“Complete(完全)”、“Custom(用户自定义)”三个选项,我们选择“Custom”,有更多的选项,也方便熟悉安装过程

 

在“Developer Components(开发者部分)”上左键单击,选择“This feature, and all subfeatures, will be installed on local hard drive.”,即“此部分,及下属子部分内容,全部安装在本地硬盘上”。在上面的“MySQL Server(mysql服务器)”、“Client Programs(mysql客户端程序)”、“Documentation(文档)”也如此操作,以保证安装所有文件。点选“Change...”,手动指定安装目录。

 

填上安装目录,我的是“D:\mysql”,也建议不要放在与操作系统同一分区,这样可以防止系统备份还原的时候,数据被清空。按“OK”继续。

 

返回刚才的界面,按“Next”继续。

 

确认一下先前的设置,如果有误,按“Back”返回重做。按“Install”开始安装。

 

正在安装中,请稍候,直到出现下面的界面

 

这里是询问你是否要注册一个mysql.com的账号,或是使用已有的账号登陆mysql.com,一般不需要了,点选“Skip Sign-Up”,按“Next”略过此步骤。

 

现在软件安装完成了,出现上面的界面,这里有一个很好的功能,mysql配置向导,不用向以前一样,自己手动乱七八糟的配置my.ini了,将 “Configure the Mysql Server now”前面的勾打上,点“Finish”结束软件的安装并启动mysql配置向导。

 

mysql配置向导启动界面,按“Next”继续。

 

选择配置方式,“Detailed Configuration(手动精确配置)”、“Standard Configuration(标准配置)”,我们选择“Detailed Configuration”,方便熟悉配置过程。

 

选择服务器类型,“Developer Machine(开发测试类,mysql占用很少资源)”、“Server Machine(服务器类型,mysql占用较多资源)”、“Dedicated MySQL Server Machine(专门的数据库服务器,mysql占用所有可用资源)”,大家根据自己的类型选择了,一般选“Server Machine”,不会太少,也不会占满。

 

选择mysql数据库的大致用途,“Multifunctional Database(通用多功能型,好)”、“Transactional Database Only(服务器类型,专注于事务处理,一般)”、“Non-Transactional Database Only(非事务处理型,较简单,主要做一些监控、记数用,对MyISAM数据类型的支持仅限于non-transactional),随自己的用途而选择了,我这里选择“Transactional Database Only”,按“Next”继续。

 

对InnoDB Tablespace进行配置,就是为InnoDB 数据库文件选择一个存储空间,如果修改了,要记住位置,重装的时候要选择一样的地方,否则可能会造成数据库损坏,当然,对数据库做个备份就没问题了,这里不详述。我这里没有修改,使用用默认位置,直接按“Next”继续

 

选择您的网站的一般mysql访问量,同时连接的数目,“Decision Support(DSS)/OLAP(20个左右)”、“Online Transaction Processing(OLTP)(500个左右)”、“Manual Setting(手动设置,自己输一个数)”,我这里选“Online Transaction Processing(OLTP)”,自己的服务器,应该够用了,按“Next”继续

 

是否启用TCP/IP连接,设定端口,如果不启用,就只能在自己的机器上访问mysql数据库了,我这里启用,把前面的勾打上,Port Number:3306,按“Next”继续

 

这个比较重要,就是对mysql默认数据库语言编码进行设置,第一个是西文编码,第二个是多字节的通用utf8编码,都不是我们通用的编码,这里选择第三个,然后在Character Set那里选择或填入“gbk”,当然也可以用“gb2312”,区别就是gbk的字库容量大,包括了gb2312的所有汉字,并且加上了繁体字、和其它乱七八糟的字——使用mysql的时候,在执行数据操作命令之前运行一次“SET NAMES GBK;”(运行一次就行了,GBK可以替换为其它值,视这里的设置而定),就可以正常的使用汉字(或其它文字)了,否则不能正常显示汉字。按 “Next”继续。

 

选择是否将mysql安装为windows服务,还可以指定Service Name(服务标识名称),是否将mysql的bin目录加入到Windows PATH(加入后,就可以直接使用bin下的文件,而不用指出目录名,比如连接,“mysql.exe -uusername -ppassword;”就可以了,不用指出mysql.exe的完整地址,很方便),我这里全部打上了勾,Service Name不变。按“Next”继续。

 

这一步询问是否要修改默认root用户(超级管理)的密码(默认为空),“New root password”如果要修改,就在此填入新密码(如果是重装,并且之前已经设置了密码,在这里更改密码可能会出错,请留空,并将“Modify Security Settings”前面的勾去掉,安装配置完成后另行修改密码),“Confirm(再输一遍)”内再填一次,防止输错。“Enable root access from remote machines(是否允许root用户在其它的机器上登陆,如果要安全,就不要勾上,如果要方便,就勾上它)”。最后“Create An Anonymous Account(新建一个匿名用户,匿名用户可以连接数据库,不能操作数据,包括查询)”,一般就不用勾了,设置完毕,按“Next”继续。

 

确认设置无误,如果有误,按“Back”返回检查。按“Execute”使设置生效。

 

设置完毕,按“Finish”结束mysql的安装与配置——这里有一个比较常见的错误,就是不能“Start service”,一般出现在以前有安装mysql的服务器上,解决的办法,先保证以前安装的mysql服务器彻底卸载掉了;不行的话,检查是否按上面一步所说,之前的密码是否有修改,照上面的操作;如果依然不行,将mysql安装目录下的data文件夹备份,然后删除,在安装完成后,将安装生成的 data文件夹删除,备份的data文件夹移回来,再重启mysql服务就可以了,这种情况下,可能需要将数据库检查一下,然后修复一次,防止数据出错。

与Apache及php相结合,前面已提过,这里再说一下,在php安装目录下,找到先前重命名并编辑过的 php.ini,如下图所示,Ln563,把“;extension=php_mysql.dll”前的“;”去掉,加载mysql模块。保存,关闭后,重启apache就可以了。这里也可以选择其它要加载的模块,去掉前面的“;”,就表示要加载此模块了,加载的越多,占用的资源也就多一点,不过也多不到哪去。所有的模块文件都放在php解压缩目录的“ext”之下,我这里的截图是把所有能加载的模块都加载上去了,前面的“;”没去掉的,是因为“ext” 目录下默认没有此模块,加载会提示找不到文件而出错。这里只是参考,一般不需要加载这么多,需要的加载上就可以了,编辑好后保存,关闭。

 

同样,加载了模块后,就要指明模块的位置,否则重启Apache的时候会提示“找不到指定模块”的错误,这里介绍一种最简单的方法,直接将 php安装路径、里面的ext路径指定到windows系统路径中——在“我的电脑”上右键,“属性”,选择“高级”标签,点选“环境变量”,在“系统变量”下找到“Path”变量,选择,双击或点击“编辑”,将“;D:\php;D:\php\ext”加到原有值的后面,当然,其中的“D:\php”是我的安装目录,你要将它改为自己的php安装目录,如下图所示,全部确定。系统路径添加好后要重启电脑才能生效,可以现在重启,也可以在所有软件安装或配置好后重启。

 
posted @ 2011-09-27 13:06 甜咖啡 阅读(188) | 评论 (0)编辑 收藏
系统主要是通过tomcat运行,将tomcat和jre打包后发送给客户使用,绿色的方式安装使用,由于客户也不搞开发,所以就仅仅是jre和tomcat和应用程序
我使用的jre6,免安装版版的tomcat6;目录结构是这样的

[我的应用名字]
  |-jre6
  |-tomcat6
  |-go_tomcat.bat

go_tomcat.bat文件内容

@ECHO OFF
set JRE_HOME=.\jre6
set PATH=%JRE_HOME%\bin;%PATH%
set TOMCAT_HOME=.\tomcat6
cd .\%TOMCAT_HOME%\bin
rem 启动tomcat服务
.\startup.bat
posted @ 2011-09-16 18:01 甜咖啡 阅读(1915) | 评论 (1)编辑 收藏

mysql这个数据库是开源的,尤其适合一些轻量级的软件开发,但是其安装过程与使用过程总是让一些初学者摸不着头脑。我也是从这样的痛苦中过来的,在此希望我的经验对小菜们有些许帮助。

1.下载地址:

http://www.5ipopo.com/soft/17815.html

2.配置参数

1)解压缩绿色版软件到D:\Java\mysql-5.1.14-beta-win32。

2)修改D:\Java\mysql-5.1.14-beta-win32\my-small.ini文件内容,添加红色内容:

[client]
#password = your_password
port  = 3306
socket  = /tmp/mysql.sock
default-character-set=gbk

[mysqld]
port  = 3306
socket  = /tmp/mysql.sock
default-character-set=gbk
skip-locking
key_buffer = 16K
max_allowed_packet = 1M
table_cache = 4
sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 64K

3.安装MySQL5的服务,服务名自己定义为MySQL5

1)在DOS窗口下进入D:\Java\mysql-5.1.14-beta-win32\bin目录

开始——运行——cmd

2)执行安装MySQL服务名的命令:

D:\Java\mysql-5.1.14-beta-win32\bin> mysqld --install MySQL5 --defaults-file=D:\Java\mysql-5.1.14-beta-win32\my-small.ini

请注意红色字体中的粗体部分,此为你mysql的路径,不要一味的粘贴。)
【数据库学习笔记】MySQL5绿色版安装教程(自己总结)

3)启动MySQL5服务:

D:\Java\mysql-5.1.14-beta-win32\bin>net start mysql5

【数据库学习笔记】MySQL5绿色版安装教程(自己总结)

4)登陆MySQL5服务器

D:\Java\mysql-5.1.14-beta-win32\bin>mysql -uroot -p

注意密码为空,直接按回车就可以了。

【数据库学习笔记】MySQL5绿色版安装教程(自己总结)

5)查看数据库:

mysql>show databases;

【数据库学习笔记】MySQL5绿色版安装教程(自己总结)

 

安装部分到此结束,此后为操作部分,转载自网上。

 

6)使用数据库
mysql>
 use test 
Database changed

7)查看数据库中的表
sql>
 show tables; 
Empty set (0.00 sec)

8)创建表ttt
mysql>
 create table ttt(a int,b varchar(20)); 
Query OK, 0 rows affected (0.00 sec)

9)插入三条数据
mysql>
 insert into ttt values(1,'aaa'); 
Query OK, 1 row affected (0.02 sec)

mysql>
 insert into ttt values(2,'bbb'); 
Query OK, 1 row affected (0.00 sec)

mysql>
 insert into ttt values(3,'ccc'); 
Query OK, 1 row affected (0.00 sec)

10)查询数据
mysql>
 select * from ttt; 
+------+------+
| a      | b       |
+------+------+
   1 | aaa     |
   2 | bbb    |
   3 | ccc     |
+------+------+
3 rows in set (0.00 sec)

11)删除数据
mysql>
 delete from ttt where a=3; 
Query OK, 1 row affected (0.01 sec)

删除后查询操作结果:
mysql>
 select * from ttt; 
+------+------+
| a    | b         |
+------+------+
   1 | aaa      |
   2 | bbb     |
+------+------+
2 rows in set (0.00 sec)

12)更新数据
mysql>
 update ttt set b = 'xxx' where a =2; 
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

查看更新结果:
mysql>
 select * from ttt;+------+------+
| a    | b          |
+------+------+
   1 | aaa      |
   2 | xxx       |
+------+------+
2 rows in set (0.00 sec)

13)删除表
mysql>
 drop table ttt; 
Query OK, 0 rows affected (0.00 sec)

查看数据库中剩余的表:
mysql>
 show tables; 
Empty set (0.00 sec)


3.更改MySQL5数据库root用户的密码

1)使用mysql数据库
mysql>
 use mysql 
Database changed

2)查看mysql数据库中所有的表
mysql>
 show tables; 
+---------------------------+
| Tables_in_mysql           |
+---------------------------+
| columns_priv              |
| db                        |
| func                      |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| host                      |
| proc                      |
| procs_priv                |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
| user                      |
+---------------------------+
17 rows in set (0.00 sec)

3)删除mysql数据库中用户表的所有数据
mysql>
 delete from user; 
Query OK, 3 rows affected (0.00 sec)

4)创建一个root用户,密码为“xiaohui”。
mysql>
 grant all on *.* to root@'%' identified by 'xiaohui' with grant option; 
Query OK, 0 rows affected (0.02 sec)

5)查看user表中的用户
mysql>
 select User from user; 
+------+
| User |
+------+
| root |
+------+
1 row in set (0.00 sec)

6)重启MySQL5:更改了MySQL用户后,需要重启MySQL服务器才可以生效。
D:\mysql-5.0.67-win32\bin>
net stop mysql5 
MySQL5 服务正在停止..
MySQL5 服务已成功停止。

D:\mysql-5.0.67-win32\bin>
net start mysql5 
MySQL5 服务正在启动 .
MySQL5 服务已经启动成功。

7)重新登陆MySQL5服务器
D:\mysql-5.0.67-win32\bin>
mysql -uroot -pxiaohui 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.67-community MySQL Community Edition (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

4.数据库的创建与删除

1)创建数据库testdb
mysql>
 create database testdb; 
Query OK, 1 row affected (0.02 sec)

2)使用数据库testdb
mysql>
 use testdb; 
Database changed

3)删除数据库testdb
mysql>
 drop database testdb; 
Query OK, 0 rows affected (0.00 sec)

4)退出登陆
mysql>
 exit 
Bye

5.操作数据库数据的一般步骤

1、启动MySQL服务器
2、登陆数据库服务器
3、使用某个要操作的数据库
4、操作该数据库中的表,可执行增删改查各种操作。
5、退出登陆。

6.mysql5的卸载 
删除服务,执行mysqld --remove MySQL5 即可。

posted @ 2011-09-16 17:58 甜咖啡 阅读(2120) | 评论 (1)编辑 收藏

总体思想:

1.前台网页用js得到裁剪图片的id及x,y,宽度和高度。

2.服务端根据id取出要裁剪的图片 。

3.根据这些参数来生成裁剪的图像。

后台代码如下:

package com.wodexiangce;

import java.awt.Rectangle;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.util.Iterator;

import javax.imageio.ImageIO;

import javax.imageio.ImageReadParam;

import javax.imageio.ImageReader;

import javax.imageio.stream.ImageInputStream;

/** *//**

*

*

* @author <a href="mailto:lqinglong@yahoo.cn">qinglong.lu</a>

*

* 2008-3-21

*/

public class OperateImage ...{

      

    //===源图片路径名称如:c:/1.jpg

    private String srcpath ;

        

    //===剪切图片存放路径名称.如:c:/2.jpg

    private String subpath ;

   

    //===剪切点x坐标

    private int x ;

   

    private int y ;   

     

    //===剪切点宽度

    private int width ;

    

    private int height ;

   

    public OperateImage()...{

           

    } 

    public OperateImage(int x,int y,int width,int height)...{

         this.x = x ;

         this.y = y ;

         this.width = width ;  

         this.height = height ;

    }

   

    /** *//**

     * 对图片裁剪,并把裁剪完蛋新图片保存 。

     */

    public void cut() throws IOException...{

        

        FileInputStream is = null ;

        ImageInputStream iis =null ;

    

        try...{  

            //读取图片文件

            is = new FileInputStream(srcpath);

           

            /**//*

             * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader

             * 声称能够解码指定格式。 参数:formatName - 包含非正式格式名称 .

             *(例如 "jpeg" 或 "tiff")等 。

             */

            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("jpg"); 

            ImageReader reader = it.next();

            //获取图片流

            iis = ImageIO.createImageInputStream(is);

              

            /**//*

             * <p>iis:读取源.true:只向前搜索 </p>.将它标记为 ‘只向前搜索’。

             * 此设置意味着包含在输入源中的图像将只按顺序读取,可能允许 reader

             *  避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。

             */

            reader.setInput(iis,true) ;

           

            /**//*

             * <p>描述如何对流进行解码的类<p>.用于指定如何在输入时从 Java Image I/O

             * 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件

             * 将从其 ImageReader 实现的 getDefaultReadParam 方法中返回

             * ImageReadParam 的实例。 

             */

            ImageReadParam param = reader.getDefaultReadParam();

            

            /**//*

             * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域,通过 Rectangle 对象

             * 的左上顶点的坐标(x,y)、宽度和高度可以定义这个区域。

             */

            Rectangle rect = new Rectangle(x, y, width, height);

           

             

            //提供一个 BufferedImage,将其用作解码像素数据的目标。

            param.setSourceRegion(rect);

            /**//*

             * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将

             * 它作为一个完整的 BufferedImage 返回。

             */

            BufferedImage bi = reader.read(0,param);               

     

            //保存新图片

            ImageIO.write(bi, "jpg", new File(subpath));    

        }

       

        finally...{

            if(is!=null)

               is.close() ;      

            if(iis!=null)

               iis.close(); 

        }

       

        

    

    }

    public int getHeight() ...{

        return height;

    }

    public void setHeight(int height) ...{

        this.height = height;

    }

    public String getSrcpath() ...{

        return srcpath;

    }

    public void setSrcpath(String srcpath) ...{

        this.srcpath = srcpath;

    }

    public String getSubpath() ...{

        return subpath;

    }

    public void setSubpath(String subpath) ...{

        this.subpath = subpath;

    }

    public int getWidth() ...{

        return width;

    }

    public void setWidth(int width) ...{

        this.width = width;

    }

    public int getX() ...{

        return x;

    }

    public void setX(int x) ...{

        this.x = x;

    }

    public int getY() ...{

        return y;

    }

    public void setY(int y) ...{

        this.y = y;

    }

    public static void main(String[] args)throws Exception...{

       

        String name = "d:/2005121210161588950.jpg";

       

        OperateImage o = new OperateImage(100,100,100,100);

        o.setSrcpath(name); 

        o.setSubpath("D:/2.jpg");

        o.cut() ; 

         

    }

}

posted @ 2011-08-02 18:43 甜咖啡 阅读(721) | 评论 (0)编辑 收藏

3.DOM4J生成和解析XML文档


DOM4J 是一个非常非常优秀的Java XML
API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写
XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。

import java.io.File;  
import java.io.FileWriter;  
import java.io.IOException;
import java.io.Writer;  
import java.util.Iterator;  

import org.dom4j.Document;  
import org.dom4j.DocumentException;  
import org.dom4j.DocumentHelper;  
import org.dom4j.Element;  
import org.dom4j.io.SAXReader;  
import org.dom4j.io.XMLWriter;  
/** 
*  
* @author hongliang.dinghl 
* Dom4j 生成XML文档与解析XML文档 
*/ 
public class Dom4jDemo implements XmlDocument {  

public void createXml(String fileName) {  
Document document = DocumentHelper.createDocument();  
Element employees=document.addElement("employees");  
Element employee=employees.addElement("employee");  
Element name= employee.addElement("name");  
name.setText("ddvip");  
Element sex=employee.addElement("sex");  
sex.setText("m");  
Element age=employee.addElement("age");  
age.setText("29");  
try {  
Writer fileWriter=new FileWriter(fileName);  
XMLWriter xmlWriter=new XMLWriter(fileWriter);  
xmlWriter.write(document);  
xmlWriter.close();  
} catch (IOException e) {  

System.out.println(e.getMessage());  
}  


}  


public void parserXml(String fileName) {  
File inputXml=new File(fileName);  
SAXReader saxReader = new SAXReader();  
try {  
Document document = saxReader.read(inputXml);  
Element employees=document.getRootElement();  
for(Iterator i = employees.elementIterator(); i.hasNext();){  
Element employee = (Element) i.next();  
for(Iterator j = employee.elementIterator(); j.hasNext();){  
Element node=(Element) j.next();  
System.out.println(node.getName()+":"+node.getText());  
}  

}  
} catch (DocumentException e) {  
System.out.println(e.getMessage());  
}  
System.out.println("dom4j parserXml");  
}  
}
posted @ 2011-07-19 16:33 甜咖啡 阅读(206) | 评论 (0)编辑 收藏

4.JDOM生成和解析XML  

为减少DOM、SAX的编码量,出现了JDOM;优点:20-80原则,极大减少了代码量。使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。

import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.util.List;  

import org.jdom.Document;  
import org.jdom.Element;  
import org.jdom.JDOMException;  
import org.jdom.input.SAXBuilder;  
import org.jdom.output.XMLOutputter;  
/** 
*  
* @author hongliang.dinghl 
* JDOM 生成与解析XML文档 
*  
*/ 
public class JDomDemo implements XmlDocument {  

public void createXml(String fileName) {  
Document document;  
Element  root;  
root=new Element("employees");  
document=new Document(root);  
Element employee=new Element("employee");  
root.addContent(employee);  
Element name=new Element("name");  
name.setText("ddvip");  
employee.addContent(name);  
Element sex=new Element("sex");  
sex.setText("m");  
employee.addContent(sex);  
Element age=new Element("age");  
age.setText("23");  
employee.addContent(age);  
XMLOutputter XMLOut = new XMLOutputter();  
try {  
XMLOut.output(document, new FileOutputStream(fileName));  
} catch (FileNotFoundException e) {  
e.printStackTrace();  
} catch (IOException e) {  
e.printStackTrace();  
}  

}  

public void parserXml(String fileName) {  
SAXBuilder builder=new SAXBuilder(false);   
try {  
Document document=builder.build(fileName);  
Element employees=document.getRootElement();   
List employeeList=employees.getChildren("employee");  
for(int i=0;iElement employee=(Element)employeeList.get(i);  
List employeeInfo=employee.getChildren();  
for(int j=0;jSystem.out.println(((Element)employeeInfo.get(j)).getName()+":"+((Element)employeeInfo.get(j)).getValue());  

}  
}  
} catch (JDOMException e) {  

e.printStackTrace();  
} catch (IOException e) {  

e.printStackTrace();  
}   

}  
}
posted @ 2011-07-19 16:33 甜咖啡 阅读(189) | 评论 (0)编辑 收藏

2.SAX生成和解析XML文档


为解决DOM的问题,出现了SAX。SAX
,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;

import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.IOException;  
import java.io.InputStream;  

import javax.xml.parsers.ParserConfigurationException;  
import javax.xml.parsers.SAXParser;  
import javax.xml.parsers.SAXParserFactory;  

import org.xml.sax.Attributes;  
import org.xml.sax.SAXException;  
import org.xml.sax.helpers.DefaultHandler;  
/** 
*  
* @author hongliang.dinghl 
* SAX文档解析 
*/ 
public class SaxDemo implements XmlDocument {  

public void createXml(String fileName) {  
System.out.println("<<"+filename+">>");  
}  

public void parserXml(String fileName) {  
SAXParserFactory saxfac = SAXParserFactory.newInstance();  

try {  

SAXParser saxparser = saxfac.newSAXParser();  

InputStream is = new FileInputStream(fileName);  

saxparser.parse(is, new MySAXHandler());  

} catch (ParserConfigurationException e) {  

e.printStackTrace();  

} catch (SAXException e) {  

e.printStackTrace();  

} catch (FileNotFoundException e) {  

e.printStackTrace();  

} catch (IOException e) {  

e.printStackTrace();  

}  

}  

}  

class MySAXHandler extends DefaultHandler {  

boolean hasAttribute = false;  

Attributes attributes = null;  

public void startDocument() throws SAXException {  

System.out.println("文档开始打印了");  

}  

public void endDocument() throws SAXException {  

System.out.println("文档打印结束了");  

}  

public void startElement(String uri, String localName, String qName,  

Attributes attributes) throws SAXException {  

if (qName.equals("employees")) {  

return;  

}  

if (qName.equals("employee")) {  

System.out.println(qName);  

}  

if (attributes.getLength() > 0) {  

this.attributes = attributes;  

this.hasAttribute = true;  

}  

}  

public void endElement(String uri, String localName, String qName)  

throws SAXException {  

if (hasAttribute && (attributes != null)) {  

for (int i = 0; i < attributes.getLength(); i++) {  

System.out.println(attributes.getQName(0)  
+ attributes.getValue(0));  

}  

}  

}  

public void characters(char[] ch, int start, int length)  

throws SAXException {  

System.out.println(new String(ch, start, length));  

}  


package com.alisoft.facepay.framework.bean;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
*
* @author hongliang.dinghl
* SAX文档解析
*/
public class SaxDemo implements XmlDocument {
public void createXml(String fileName) {
System.out.println("<<"+filename+">>");
}
public void parserXml(String fileName) {
SAXParserFactory saxfac = SAXParserFactory.newInstance();
try {
SAXParser saxparser = saxfac.newSAXParser();
InputStream is = new FileInputStream(fileName);
saxparser.parse(is, new MySAXHandler());
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class MySAXHandler extends DefaultHandler {
boolean hasAttribute = false;
Attributes attributes = null;
public void startDocument() throws SAXException {
System.out.println("文档开始打印了");
}
public void endDocument() throws SAXException {
System.out.println("文档打印结束了");
}
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equals("employees")) {
return;
}
if (qName.equals("employee")) {
System.out.println(qName);
}
if (attributes.getLength() > 0) {
this.attributes = attributes;
this.hasAttribute = true;
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (hasAttribute && (attributes != null)) {
for (int i = 0; i < attributes.getLength(); i++) {
System.out.println(attributes.getQName(0)
+ attributes.getValue(0));
}
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch, start, length));
}
}
posted @ 2011-07-19 16:32 甜咖啡 阅读(349) | 评论 (0)编辑 收藏

1.DOM生成和解析XML文档


为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM
接口来操作这个树结构。优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
*
* @author hongliang.dinghl
* DOM生成与解析XML文档
*/
public class DomDemo implements XmlDocument {
private Document document;
private String fileName;
public void init() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
this.document = builder.newDocument();
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
}
}
public void createXml(String fileName) {
Element root = this.document.createElement("employees");
this.document.appendChild(root);
Element employee = this.document.createElement("employee");
Element name = this.document.createElement("name");
name.appendChild(this.document.createTextNode("丁宏亮"));
employee.appendChild(name);
Element sex = this.document.createElement("sex");
sex.appendChild(this.document.createTextNode("m"));
employee.appendChild(sex);
Element age = this.document.createElement("age");
age.appendChild(this.document.createTextNode("30"));
employee.appendChild(age);
root.appendChild(employee);
TransformerFactory tf = TransformerFactory.newInstance();
try {
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
StreamResult result = new StreamResult(pw);
transformer.transform(source, result);
System.out.println("生成XML文件成功!");
} catch (TransformerConfigurationException e) {
System.out.println(e.getMessage());
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (TransformerException e) {
System.out.println(e.getMessage());
}
}
public void parserXml(String fileName) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(fileName);
NodeList employees = document.getChildNodes();
for (int i = 0; i < employees.getLength(); i++) {
Node employee = employees.item(i);
NodeList employeeInfo = employee.getChildNodes();
for (int j = 0; j < employeeInfo.getLength(); j++) {
Node node = employeeInfo.item(j);
NodeList employeeMeta = node.getChildNodes();
for (int k = 0; k < employeeMeta.getLength(); k++) {
System.out.println(employeeMeta.item(k).getNodeName()
+ ":" + employeeMeta.item(k).getTextContent());
}
}
}
System.out.println("解析完毕");
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
} catch (SAXException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
posted @ 2011-07-19 16:12 甜咖啡 阅读(291) | 评论 (0)编辑 收藏

一、前言
  
  用Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单API(Simple
API for XML)称为SAX和基于树和节点的文档对象模型(Document Object Module)称为DOM。Sun公司提供了Java API
for XML
Parsing(JAXP)接口来使用SAX和DOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。
  
  JAXP接口包含了三个包:
  
  (1)org.w3c.dom W3C推荐的用于XML标准规划文档对象模型的接口。
  
  (2)org.xml.sax 
用于对XML进行语法分析的事件驱动的XML简单API(SAX)
  
  (3)javax.xml.parsers解析器工厂工具,程序员获得并配置特殊的特殊语法分析器。
  
  二、前提
  
  DOM编程不要其它的依赖包,因为JDK里自带的JDK里含有的上面提到的org.w3c.dom、org.xml.sax
和javax.xml.parsers包就可以满意条件了。
  
  三、使用DOM解析XML文档
  
  我们现在来看看DOM是如何解析XML的吧!同样的,我将从一个简单的不能再简单的例子来说明DOM是如何解析XML文档的,先让我们看看XML是什么内容吧:
  
  <?xml
version="1.0"
encoding="gb2312"?>
  
  <books>
  
  <book
email="zhoujunhui">
  
  <name>rjzjh</name>
  
  <price>jjjjjj</price>
  
  </book>
  
  </books>
  
  简单的不能再简单了。但是该有的都有了,根元素、属性、子节点。好了,能反应问题就行了,下面来看看解析这个XML文件的Java代码吧!
  
  1
public class DomParse {
  
  2   public
DomParse(){
  
  3      DocumentBuilderFactory
domfac=DocumentBuilderFactory.newInstance();
  
  4      try
{
  
  5          DocumentBuilder
dombuilder=domfac.newDocumentBuilder();
  
  6          InputStream is=new
FileInputStream("bin/library.xml");
  
  7          Document
doc=dombuilder.parse(is);
  
  8
  
  9          Element
root=doc.getDocumentElement();
  
  10         NodeList
books=root.getChildNodes();
  
  11         if(books!=null){
  
  12            
for(int i=0;i<books.getLength();i++){
  
  13                Node
book=books.item(i);
  
  14                if(book.getNodeType()==Node.ELEMENT_NODE){
  
  15         String
email=book.getAttributes().getNamedItem("email").getNodeValue();
  
  16                   
System.out.println(email);
  
  17         for(Node
node=book.getFirstChild();node!=null;node=node.getNextSibling()){
  
  18                if(node.getNodeType()==Node.ELEMENT_NODE){
  
  19                    if(node.getNodeName().equals("name")){
  
  20                     String
name=node.getNodeValue();
  
  21                    String
name1=node.getFirstChild().getNodeValue();
  
  22                              System.out.println(name);
  
  23                              System.out.println(name1);
  
  24                          
}
  
  25                   if(node.getNodeName().equals("price")){
  
  26                       String
price=node.getFirstChild().getNodeValue();
  
  27                              System.out.println(price);
  
  28                          
}
  
  29                       }
  
  30                   
}
  
  31                }
  
  32            
}
  
  33         }
  
  34      } catch
(ParserConfigurationException e)
{
  
  35         e.printStackTrace();
  
  36      } catch
(FileNotFoundException e)
{
  
  37         e.printStackTrace();
  
  38      } catch
(SAXException e) {
  
  39         e.printStackTrace();
  
  40     
} catch (IOException e)
{
  
  41         e.printStackTrace();
  
  42     
}
  
  43  }
  
  44  public static void main(String[] args)
{
  
  45      new DomParse();
  
  46  }
  
  47
}
  
  四、代码解释
  
  先看看这个程序引用类:
  
  import
java.io.FileInputStream;
  
  import
java.io.FileNotFoundException;
  
  import
java.io.IOException;
  
  import java.io.InputStream;
  
  import
javax.xml.parsers.DocumentBuilder;
  
  import
javax.xml.parsers.DocumentBuilderFactory;
  
  import
javax.xml.parsers.ParserConfigurationException;
  
  //下面主要是org.xml.sax包的类
  
  import
org.w3c.dom.Document;
  
  import org.w3c.dom.Element;
  
  import
org.w3c.dom.Node;
  
  import org.w3c.dom.NodeList;
  
  import
org.xml.sax.SAXException;
  
  上面那么简单的代码一看就明白了,但是为了介绍个DOM编程的大概还是来看看这个程序吧:
  
  (1)得到DOM解析器的工厂实例
  
  DocumentBuilderFactory
domfac=DocumentBuilderFactory.newInstance();
  
  得到javax.xml.parsers.DocumentBuilderFactory;类的实例就是我们要的解析器工厂
  
  (2)从DOM工厂获得DOM解析器
  
  DocumentBuilder
dombuilder=domfac.newDocumentBuilder();
  
  通过javax.xml.parsers.DocumentBuilderFactory实例的静态方法newDocumentBuilder()得到DOM解析器
  
  (3)把要解析的XML文档转化为输入流,以便DOM解析器解析它
  
  InputStream
is=new
FileInputStream("bin/library.xml");
  
  InputStream是一个接口。
  
  (4)解析XML文档的输入流,得到一个Document
  
  Document
doc=dombuilder.parse(is);
  
  由XML文档的输入流得到一个org.w3c.dom.Document对象,以后的处理都是对Document对象进行的
  
  (5)得到XML文档的根节点
  
  Element
root=doc.getDocumentElement();
  
  在DOM中只有根节点是一个org.w3c.dom.Element对象。
  
  (6)得到节点的子节点
  
  NodeList books=root.getChildNodes();
  
  for(int
i=0;i<books.getLength();i++){
  
  Node
book=books.item(i);
  
  }
  
  这是用一个org.w3c.dom.NodeList接口来存放它所有子节点的,还有一种轮循子节点的方法,后面有介绍
  
  (7)取得节点的属性值
  
  String
email=book.getAttributes().getNamedItem("email").getNodeValue();
  
  System.out.println(email);
  
  注意,节点的属性也是它的子节点。它的节点类型也是Node.ELEMENT_NODE
  
  (8)轮循子节点
  
  for(Node
node=book.getFirstChild();node!=null;node=node.getNextSibling()){
  
  if(node.getNodeType()==Node.ELEMENT_NODE){
  
  if(node.getNodeName().equals("name")){
  String
name=node.getNodeValue();
  
  String
name1=node.getFirstChild().getNodeValue();
  
  System.out.println(name);
  
  System.out.println(name1);
  
  }
  
  if(node.getNodeName().equals("price")){
  
  String
price=node.getFirstChild().getNodeValue();
  
  System.out.println(price);
  }
  
  }
  
  这段代码的打印输出为:
  
  null
  
  alterrjzjh
  
  jjjjjj
  
  从上面可以看出
  
  String
name=node.getNodeValue();  是一个空值。而
  
  String
name1=node.getFirstChild().getNodeValue(); 才是真正的值,这是因为DOM把<name>rjzjh</name>也当作是两层结构的节点,其父节点是<name>,子节点rjzjh才是我们真正想得到的。

posted @ 2011-07-19 09:57 甜咖啡 阅读(1977) | 评论 (0)编辑 收藏
  1. package test; 
  2.  
  3. import java.util.Calendar; 
  4. import java.util.Date; 
  5. import java.util.GregorianCalendar; 
  6. import java.util.Timer; 
  7.  
  8. import javax.servlet.ServletContextEvent; 
  9. import javax.servlet.ServletContextListener; 
  10.  
  11. public class ContextListener implements ServletContextListener { 
  12.      
  13.     //定时器 
  14.     Timer timer = null
  15.      
  16.     //销毁 
  17.     public void contextDestroyed(ServletContextEvent event) { 
  18.         timer.cancel();      
  19.         event.getServletContext().log("定时器以销毁"); 
  20.  
  21.     } 
  22.  
  23.     //初始化 
  24.     public void contextInitialized(ServletContextEvent event) { 
  25.         timer = new Timer(); 
  26.         event.getServletContext().log("定时器已启动"); 
  27.         //设置在每晚19:15分执行任务 
  28.         Calendar calendar = Calendar.getInstance(); 
  29.         calendar.set(Calendar.HOUR_OF_DAY, 19); 
  30.         calendar.set(Calendar.MINUTE, 16); 
  31.         calendar.set(Calendar.SECOND, 0); 
  32.         Date date = calendar.getTime(); 
  33.          
  34.         timer.schedule(new Task(),date); 
  35.         event.getServletContext().log("已经添加任务调度表");  
  36.     } 
  37.  
  38. }


  1. package test; 
  2.  
  3. import java.util.Date; 
  4. import java.util.TimerTask; 
  5. /**
  6. * 具体任务
  7. */ 
  8. public class Task extends TimerTask { 
  9.  
  10.     private static boolean isRunning = false
  11.  
  12.     @Override 
  13.     public void run() { 
  14.         if (!isRunning) { 
  15. isRunning = true
  16.             System.out.println("开始执行........."+new Date()); 
  17.             isRunning = false
  18.         }else
  19.             System.out.println("上次任务还没执行完"); 
  20.         } 
  21.     } 
  22.  
  23. }


 

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <web-app version="2.4"  
  3.     xmlns="http://java.sun.com/xml/ns/j2ee"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee  
  6.     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 
  7.  
  8. <!-- 定时监听器 -->     
  9. <listener>   
  10.   <listener-class>test.ContextListener</listener-class>  
  11. </listener>  
  12.   <welcome-file-list> 
  13.     <welcome-file>index.jsp</welcome-file> 
  14.   </welcome-file-list> 
  15. </web-app> 
posted @ 2011-07-13 16:21 甜咖啡 阅读(308) | 评论 (0)编辑 收藏
这个类最终功能是每天某个时间点(如每晚22点)执行某一功能.

首先介绍java定时器(java.util.Timer)有定时执行计划任务的功能,通过设定定时器的间隔时间,会自动在此间隔时间后执行预先安排好的任务(java.util. TimerTask)

如: 每隔一个小时执行任务 timer.schedule(TimerTask, 0, 60 * 60 * 1000);

    schedule方法的第一个参数是需要执行的任务,此类的类型为java.util.TimerTask,第二个参数为执行任务前等待时间,此处0表示不等待,第三个参数为间隔时间,单位为毫秒

由于我们希望当Web工程启动时,定时器能自动开始计时,这样在整个Web工程的生命期里,就会定时的执行任务,因此启动定时器的类不能是一般的类,此处用Servlet的监听器类来启动定时器,通过在配置文件里配置此监听器, 让其在工程启动时自动加载运行,存活期为整个Web工程生命期.

要运用Servlet侦听器需要实现javax.servlet.ServletContextListener接口,以下是类设计:






public class WorkServiceImpl implements WorkService , ServletContextListener ...{


public void contextDestroyed(ServletContextEvent arg0) ...{
 
    timer.cancel();
    System.out.println("定时器已销毁");
     }

public void contextInitialized(ServletContextEvent event) ...{
 
      timer = new java.util.Timer(true);
      sampleTask =   new SampleTask(event.getServletContext());
      System.out.println("定时器已启动");
            timer.schedule(sampleTask, 0, 60 * 60 * 1000);
            System.out.println("已经添加任务调度表");
     }
}


class SampleTask extends TimerTask...{  

 
private ServletContext context; 
    private static boolean isRunning = false;
    private static boolean flag = true;
    private static final int C_SCHEDULE_HOUR = 23;
    private WorkServiceImpl workService;
  
    public SampleTask(ServletContext context)...{
     this.context = context;
    } 

    public void run() ...{
     workService = new WorkServiceImpl();
        Calendar cal = Calendar.getInstance();
        if (!isRunning) ...{
            if (C_SCHEDULE_HOUR == cal.get(Calendar.HOUR_OF_DAY) && flag) ...{
                isRunning = true;
                workService.autoWorkOff();
                isRunning = false;
                flag = false;
                context.log("指定任务执行结束");
            }
        } else ...{
            context.log("上一次任务执行还未结束");
        }
        if(C_SCHEDULE_HOUR != cal.get(Calendar.HOUR_OF_DAY))...{
            flag = true;
        }
      }
}



要使用此监听器需要在web.xml中配置,如下:
<listener>
        <listener-class>com.css.wam.service.impl.WorkServiceImpl</listener-class>
</listener>


这样在web工程启动时,就会自动启动此监听器
posted @ 2011-07-13 16:20 甜咖啡 阅读(161) | 评论 (0)编辑 收藏
//   SessionListener.java    
   
     
   
  import  
java.io.*;    
   
  import   java.util.*;    
   
  import  
javax.servlet.http.*;    
   
     
   
  //监听登录的整个过程    
 
 
  public   class   SessionListener   implements    
   
   
 
HttpSessionBindingListener    
   
  {    
   
     
   

  public   String   privateInfo="";   //生成监听器的初始化参数字符串    
   
 
private   String   logString="";   //日志记录字符串    
   
  private   int  
count=0;   //登录人数计数器    
   
     
   
  public  
SessionListener(String   info){    
   
  this.privateInfo=info;    

   
  }    
   
     
   
  public   int   getCount(){  
 
   
  return   count;    
   
  }    
   
     
 
 
  public   void   valueBound(HttpSessionBindingEvent   event)    
   

  {    
   
  count++;    
   
  if  
(privateInfo.equals("count"))    
   
  {    
   
  return;    

   
  }    
   
  try{    
   
  Calendar   calendar=new
  GregorianCalendar();    
   
 
System.out.println("LOGIN:"+privateInfo+"    
   
   
 
TIME:"+calendar.getTime());    
   
  logString="\nLOGIN:"+privateInfo+"
  TIME:"+calendar.getTime()  
   
   
  +"\n";    
   
 
for(int   i=1;i<1000;i++){    
   
  File   file=new  
File("yeeyoo.log"+i);    
   
  if(!(file.exists()))    
   
 
file.createNewFile();   //如果文件不存在,创建此文件    
   
 
if(file.length()>1048576)   //如果文件大于1M,重新创建一个文件    
   
  continue;  
 
   
  FileOutputStream   foo=new   FileOutputStream  
   
   

  ("yeeyoo.log"+i,true);//以append方式打开创建文件    
   
 
foo.write(logString.getBytes(),0,logString.length());   //写入日志  
   
   

  字符串    
   
  foo.close();    
   
  break;//退出    
 
 
  }    
   
  }catch(FileNotFoundException   e){}    
   

  catch(IOException   e){}    
   
  }    
   
     
   

  public   void   valueUnbound(HttpSessionBindingEvent   event)    
   

  {    
   
  count--;    
   
  if  
(privateInfo.equals("count"))    
   
  {    
   
  return;    

   
  }    
   
  try{    
   
  Calendar   calendar=new
  GregorianCalendar();    
   
 
System.out.println("LOGOUT:"+privateInfo+"    
   
   
 
TIME:"+calendar.getTime());    
   
logString="\nLOGOUT:"+privateInfo+" TIME:"+calendar.getTime()
   
 
 
  +"\n";    
   
  for(int   i=1;i<1000;i++){    
   
 
File   file=new   File("yeeyoo.log"+i);    
   
  if(!(file.exists()))  
 
   
  file.createNewFile();   //如果文件不存在,创建此文件    
   
 
if(file.length()>1048576)   //如果文件大于1M,重新创建一个文件    
   
  continue;  
 
   
  FileOutputStream   foo=new   FileOutputStream  
   
   

  ("yeeyoo.log"+i,true);//以append方式打开创建文件    
   
 
foo.write(logString.getBytes(),0,logString.length());   //写入日志  
   
   

  字符串    
   
  foo.close();    
   
  break;//退出    
 
 
  }    
   
  }catch(FileNotFoundException   e){}    
   

  catch(IOException   e){}    
   
  }    
   
     
   

  }    
   
     
   
  登录日志的实现:    
   
     
 
 
  下面再来看看我们的登录Servlet中使用这个监听器的部分源代码:    
   
  ……    
   
 
HttpSession   session   =   req.getSession   (true);    
   
  ……    

   
////////////////////////////////////////////////////////////////
   
   
  ///////    
   
  SessionListener  
sessionListener=new   SessionListener("    
   
   
 
IP:"+req.getRemoteAddr());   //对于每一个会话过程均启动一个监听器    
   
 
session.setAttribute("listener",sessionListener);   //将监听器植入  
   
   

  HttpSession,这将激发监听器调用valueBound方法,从而记录日志文件  
   
   
  。    

   
  ////////////////////////////////////////////////////////////////  

   
   
  ///////    
   
 
当系统退出登录时,只需简单地调用session.removeAttribute  
   
   
 
(“listener”);即可自动调用监听器的valueUnbound方法。或者,当  
   
   
  Session  
Time   Out的时候也会调用此方法。    
   
     
   
     
   
 
登录人数的统计:    
   
  ServletContext  
session1=getServletConfig().getServletContext  
   
   
 
();//取得ServletContext对象实例    
   
 
if((SessionListener)session1.getAttribute("listener1")==null)    
   
 
{    
   
  SessionListener   sessionListener1=new  
SessionListener("count");//  
   
   
 
只设置一次,不同于上面日志文件的记录每次会话均设置。即当第一个客  
   
   
 
户连接到服务器时启动一个全局变量,此后所有的客户将使用相同的上下  
   
   
  文。    
   
 
session1.setAttribute("listener1",sessionListener1);//将监听器对  
   
   

  象设置成ServletContext的属性,具有全局范围有效性,即所有的客户均  
   
   
  可以取得它的实例。
   
   
  }    
   
 
session.setAttribute("listener1",(SessionListener)  
   
   
 
session1.getAttribute("listener1"));//取出此全局对象,并且将此对  
   
   
 
象绑定到某个会话中,此举将促使监听器调用valueBound,计数器加一。    
   
 
在此后的程序中随时可以用以下代码取得当前的登录人数:    
   
 
((SessionListener)session.getAttribute("listener1")).getCount()    
   

  getCount()是监听器的一个方法,即取得当前计数器的值也就是登录人数  
   
   
  了。

修改web.xml,增加:  
   
     
   
<listener>
   

  <listener-class>SessionListener</listener-class>    
   

  </listener>  
   
     
   
         
<servlet-mapping>  
   
                 
<servlet-name>SessionListener</servlet-name>  
   
         
        <url-pattern>/servlet/SessionListener</url-pattern>  
 
 
          </servlet-mapping>  
   
     
   
       
  <servlet>  
   
                 
<servlet-name>SessionListener</servlet-name>  
   
         
        <servlet-class>SessionListener</servlet-class>  
   

  </servlet>  
posted @ 2011-07-13 16:19 甜咖啡 阅读(1159) | 评论 (0)编辑 收藏
表类型
MySQL的数据表类型很多,其中比较重要的是MyISAM,InnoDB这两种。
这两种类型各有优缺点,需要根据实际情况选择适合的,MySQL支持对不同的表设置不同的类型。下面做个对比:
MyISAM表类型是一种比较成熟稳定的表类型,但是MyISAM对一些功能不支持。
MyISAMInnoDB
事务不支持支持
数据行锁定不支持,只有表锁定支持
外键约束不支持支持
表空间大小相对小相对大,最大是2倍
全文索引支持不支持
GIS数据支持不支持
COUNT问题执行COUNT(*)查询时,速度慢
一般情况下我觉得选择MyISAM就行,如果需要事务,或者需要很多用户同时修改某个数据表里的数据时,可以考虑InnoDB数据表。
数据类型
1.整型(xxxint)
MySQL数据类型含义
tinyint(m)1个字节表示(-128~127)
smallint(m)2个字节表示(-32768~32767)
mediumint(m)3个字节表示(-8388608~8388607)
int(m)4个字节表示(-2147483648~2147483647)
bigint(m)8个字节表示(+-9.22*10的18次方)
右侧的取值范围是在未加unsigned关键字的情况下,如果加了unsigned,则最大值翻倍,如tinyint unsigned的取值范围为(0~256)。
书上说int(m)括弧里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围,我测了一下,定义一个字段number 类型为int(4),插入一条记录"123456",用mysql query broswer执行SELECT查询,返回的结果集中123456正确显示,没有影响到显示的宽度,不知道这个m有什么用。

2.浮点型(float和double)
MySQL数据类型含义
float(m,d)单精度浮点型,8位精度(4字节),m是十进制数字的总个数,
d是小数点后面的数字个数。
double(m,d)双精度浮点型,16位精度(8字节)
参数m只影响显示效果,不影响精度,d却不同,会影响到精度。
比如设一个字段定义为float(5,3),如果插入一个数123.45678,实际数据库里存的是123.457,小数点后面的数别四舍五入截成457了,但总个数不受到限制(6位,超过了定义的5位)。

3.定点数(decimal)
decimal(m,d) 定点类型
浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。参数m是定点类型数字的最大个数(精度),范围为0~65,d小数点右侧数字的个数,范围为0~30,但不得超过m。
对定点数的计算能精确到65位数字。

4.字符串(char,varchar,xxxtext)
MySQL数据类型含义
char(n)固定长度的字符串,最多255个字符
varchar(n)固定长度的字符串,最多65535个字符
tinytext可变长度字符串,最多255个字符
text可变长度字符串,最多65535个字符
mediumtext可变长度字符串,最多2的24次方-1个字符
longtext可变长度字符串,最多2的32次方-1个字符
char和varchar:
1.都可以通过指定n,来限制存储的最大字符数长度,char(20)和varchar(20)将最多只能存储20个字符,超过的字符将会被截掉。n必须小于该类型允许的最大字符数。
2.char类型指定了n之后,如果存入的字符数小于n,后面将会以空格补齐,查询的时候再将末尾的空格去掉,所以char类型存储的字符串末尾不能有空格,varchar不受此限制。
3.内部存储的机制不同。char是固定长度,char(4)不管是存一个字符,2个字符或者4个字符(英文的),都将占用4个字节,varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),所以varchar(4),存入一个字符将占用2个字节,2个字符占用3个字节,4个字符占用5个字节。
4.char类型的字符串检索速度要比varchar类型的快。

varchar和text:
1.都是可变长度的,最多能存储65535个字符。
2.varchar可指定n,text不能指定,内部存储varchar是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),text是实际字符数+2个字节。
3.text类型不能有默认值。
4.varchar可直接创建索引,text创建索引要指定前多少个字符。查询速度varchar要快于text,在都创建了索引的情况下,text的索引好像没起作用,参见这篇文章:http://forums.mysql.com/read.php?24,105964,105964

5.二进制数据(xxxBlob)
XXXBLOB和xxxtext是对应的,不过存储方式不同,xxxTEXT是以文本方式存储的,如果存储英文的话区分大小写,而xxxBlob是以二进制方式存储的,不区分大小写。
xxxBlob存储的数据只能整体读出。
xxxTEXT可以指定字符集,xxxblob不用指定字符集。

6.日期时间类型(date,time,datetime,timestamp)
MySQL数据类型含义
date日期'2008-12-2'
time时间'12:25:36'
datetime日期时间'2008-12-2 22:06:44'
timestamp不固定
timestamp比较特殊,如果定义一个字段的类型为timestamp,这个字段的时间会在其他字段修改的时候自动刷新。所以这个数据类型的字段可以存放这条记录最后被修改的时间,而不是真正来的存放时间。
数据类型的属性
MySQL关键字含义
NULL数据列可包含NULL值
NOT NULL数据列不允许包含NULL值
DEFAULT xxx默认值,如果插入记录的时候没有指定值,将取这个默认值
PRIMARY KEY主键
AUTO_INCREMENT递增,如果插入记录的时候没有指定值,则在上一条记录的值上加1,仅适用于整数类型
UNSIGNED无符号
CHARACTER SET name指定一个字符集
posted @ 2011-06-27 09:24 甜咖啡 阅读(396) | 评论 (0)编辑 收藏

类继承关系映射
(1)DB表之间不存在继承关系,要把JavaBean中的继承关系映射到关系数据库中的有三种映射方式:
·每个类建一张表
·所有类建一张表
·只为具体类建表

eg. 以公司Company(一方)和员工Employee(多方),Employee有两个子:类小时工HourlyEmployee和正式员工SalariedEmployee


1)每个类建一张表
可以有效减少数据冗余,减少字段,查询效率不很高。
配置文件:
Company.hbm.xml
<class name="Company" table="company">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name" type="string"/>
   <!-- Company与Employee是多态关联,
    但是由于DB没有描述Employee类和它的两个子类的继承关系,
    因此无法映射Company类的employees集合,
    所以该文件仅仅映射了Company的id和name属性 -->
</class>
<一>:需要针对每个类写映射配置文件,就和普通的单表映射的xml文件相同
Employee.hbm.xml
<class name="Employee" table="employee">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name"/>

</class>

HourlyEmployee.hbm.xml
<class name="HourlyEmployee" table="hourly">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name"/>
   <property name="rate"></property>
   <many-to-one name="company" class="Company"
    column="companyid" cascade="save-update"></many-to-one>
</class>

SalaryEmployee.hbm.xml
<class name="SalariedEmployee" table="salaried">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name"/>
   <property name="salary"></property>
  
   <many-to-one name="company" class="Company"
    column="companyid" cascade="save-update"></many-to-one>
</class>
采用这种独立映射方式的配置方法,在配置文件中没有定义这些类之间的任何关系,也就是说,三个类都是独立存在的。使用这种映射方式解决了相同属性必须使用相同字段名的限制,但是从父类继承的属性需要在每个子类中都进行相应的定义,造成属性配置的重复。
<二>也可以使用一个xml文件来进行映射,要使用<union-subclass>标签!!!
注意:这里不能使用id生成策略中的native,而是要指定特定的生成策略。
Employee2.hbm.xml:
<class name="Employee" table="employee">
   <id name="oid" column="oid" >
       <generator class="hilo">
           <param name="table">tt_hi</param>
           <param name="column">hi</param>
        </generator>
   </id>
   <property name="name"/>
  
    <union-subclass name="HourlyEmployee" table="hourly" >
     <property name="rate"></property>
     <many-to-one name="Company"
column="companyid" cascade="save-update">
</many-to-one>
    </union-subclass>
   
    <union-subclass name="SalariedEmployee"
table="salaried" >
     <property name="salary"></property>
     <many-to-one name="Company" column="companyid"
cascade="save-update">
</many-to-one>
    </union-subclass>
    </class>

使用这种方式除了每个子类对应一个表外,其定义方式与java对象的继承非常相似,即子类可以继承父类中公共的属性定义,解决了属性配置的重复,但是,造成了相同属性必须使用相同字段名的限制。
2)所有类建一张表
查寻效率比较高,但是会产生很多空间浪费,当子类中的非空约束,就不大适用了,这是对于子类要使用<subclass>标签表示。
配置文件:
Company2.hbm.xml:
<class name="Company" table="company">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name" type="string"/>
   <set name="employees"
cascade="all-delete-orphan" inverse="true">
    <key column="companyid"></key>
    <one-to-many class="Employee"/>
   </set>
   </class>
Employee3.hbm.xml:
<class name="Employee" table="employee2">
   <id name="oid" column="oid" >
       <generator class="native">
        </generator>
   </id>
   <property name="name" />
   <discriminator column="employee_type" type="string"/>

   <subclass name="HourlyEmployee"
discriminator-value="hourly">
    <property name="rate"></property>
     <many-to-one name="Company"
column="companyid" cascade="all">
</many-to-one>
   </subclass>
  
   <subclass name="SalariedEmployee"
discriminator-value="salaried">
   <property name="salary"></property>
     <many-to-one name="Company"
column="companyid" cascade="save-update">
</many-to-one>   
   </subclass>
</class>
使 用这种映射方式需要注意的是它通过<discriminator>标签(<discriminator column="employee_type" type="string"/>)增加一个字段(这里是employee_type字段)来标示某个记录是属于哪个实体对象的。通过< subclass>标记中的discriminator-value属性来定义哪个值代表哪个子类的持久化对象。
3)只为具体类建表
·适用于不使用多态的情况下
·跟每个类建一张表的区别:
① 每个类一张表的映射策略所建立的表示独立的,每个表都包括子类所自定义 的属性和由父类锁继承的属性的映射字段。
② 只为具体类建表,子类所对应的表只包括子类所定义的属性,而子类所对应的 表与父类所对应的表是通过外键来进行关联的,即当持久化一个子类时,需要在父 类的表和子类的表各增加一条记录,这两个记录通过外键来关联。
·好处:父类所定义的属性就在父类的表中进行映射,而子类所定义的属性就在子类的表中进行映射。避免了子类所定义的表中仍然需要定义父类属性的映射字段。
·映射文件中的子类可以使用<join-subclass>标签来表示,并且引用父类的主 键作为共享主键,就是不需要指定id生成策略
配置文件:
Company3.hbm.xml:
<class name="Company" table="company3">
   <id name="oid" column="oid" >
        <generator class="native">
        </generator>
   </id>
   <property name="name" type="string"/>
  
   <set name="employees" cascade="all-delete-orphan"
inverse="true">
    <key column="companyid"></key>
    <one-to-many class="Employee"/>
   </set>
</class>
Employee4.hbm.xml:
<class name="Employee" table="employee3">
   <id name="oid" column="oid" >
       <generator class="native">
        </generator>
   </id>
   <property name="name" />
  
   <joined-subclass name="HourlyEmployee" table="hourly2">
    <key column="oid"></key>
    <property name="rate"></property>
    <many-to-one name="Company" column="companyid"
cascade="save-update">
</many-to-one>
   </joined-subclass>

   <joined-subclass name="SalariedEmployee" table="salaried2">
    <key column="oid"></key>
    <property name="salary"></property>
    <many-to-one name="Company" column="companyid"
cascade="save-update">
</many-to-one>
   </joined-subclass>
</class>

posted @ 2011-03-26 23:41 甜咖啡 阅读(497) | 评论 (0)编辑 收藏

根据hibernate的文档,有两种方式实现实体对象的主键自动增长。
第一种:设置ID的增长策略是sequence,同时指定sequence的名字,最好每个表建一个sequence,此种做法就如同MS-SQL,MY-SQL中的自动增长一样,不需要创建触发器,具体的oracle数据库脚本及hibernate配置文件如下:

oracle数据表的创建脚本:
CREATE TABLE DEPARTMENT (  
    ID NUMBER(19,0) DEFAULT '0' NOT NULL,  
    NAME VARCHAR2(255) NOT NULL,  
    DESCRIPTION CLOB  
);  
ALTER TABLE DEPARTMENT ADD CONSTRAINT PRIMARY_0 PRIMARY KEY(ID) ENABLE;  
ALTER TABLE DEPARTMENT ADD CONSTRAINT UK_DEPARTMENT_1 UNIQUE (NAME);  

CREATE SEQUENCE DEPARTMENT_ID_SEQ MINVALUE 10000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;

CREATE TABLE DEPARTMENT (
ID NUMBER(19,0) DEFAULT '0' NOT NULL,
NAME VARCHAR2(255) NOT NULL,
DESCRIPTION CLOB
);
ALTER TABLE DEPARTMENT ADD CONSTRAINT PRIMARY_0 PRIMARY KEY(ID) ENABLE;
ALTER TABLE DEPARTMENT ADD CONSTRAINT UK_DEPARTMENT_1 UNIQUE (NAME);

CREATE SEQUENCE DEPARTMENT_ID_SEQ MINVALUE 10000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;

创建DEPARTMENT表,并为DEPARTMENT表创建一个单独的SEQUENCE,名字为SEQUENCE_ID_SEQ,并不需要创建触发器。

[2]hibernate映射文件的配置:
Java代码
<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC  
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
<hibernate-mapping package="com.liyanframework.demo.domain">  
    <class name="Department" table="DEPARTMENT">  
        <id name="id" column="ID">  
            <generator class="sequence">  
                <param name="sequence">DEPARTMENT_ID_SEQ</param>  
            </generator>  
        </id>  
        <property name="name" column="NAME" type="string" />  
        <property name="description" column="DESCRIPTION" type="text" />  
    </class>  
</hibernate-mapping>  


在hibernate映射文件中,对ID的生成策略选择sequence,指定sequence的名字DEPARTMENT_ID_SEQ 就可以了,当你保存新对象的时候,hibernate会自动取得DEPARTMENT_ID_SEQ.NEXTVAL作为新对象的ID保存到数据库,所以 不需要再使用触发器再来生成新记录的ID。
[/list]
第二种:设置ID的增长策略是native,但是需要创建一个名字为 hibernate_sequence(这个名字好像是hibernate默认的sequence名字,不创建会出错的)的全局使用的sequence, 然后再对每一个表的ID生成的时候,使用触发器,取得hibernate_sequence.CURRVAL作为新记录的ID,具体的oracle数据库 脚本及hibernate配置文件如下:
[list]
[1]oracle数据表的创建脚本:
Java代码
CREATE TABLE STAFF (  
    ID NUMBER(19,0) DEFAULT '0' NOT NULL,  
    NAME VARCHAR2(255) NOT NULL,  
    AGE NUMBER(3,0) NOT NULL,  
    BIRTHDAY DATE NOT NULL,  
    SALARY NUMBER(10,2) NOT NULL,  
    LEVELNESS FLOAT NOT NULL,  
    CREATETIME TIMESTAMP NOT NULL,  
    ENABLE CHAR(2) DEFAULT 'Y' NOT NULL,  
    STATUS VARCHAR2(64) NOT NULL,  
    DEPARTMENT_ID NUMBER(19,0)  
);  
ALTER TABLE STAFF ADD CONSTRAINT PRIMARY_1 PRIMARY KEY(ID) ENABLE;  
ALTER TABLE STAFF ADD CONSTRAINT STAFF_IBFK_0 FOREIGN KEY(DEPARTMENT_ID) REFERENCES DEPARTMENT(ID) ENABLE;  
ALTER TABLE STAFF ADD CONSTRAINT UK_STAFF_1 UNIQUE (NAME);  
CREATE INDEX IDX_STAFF_STATUS ON STAFF(STATUS);  

CREATE SEQUENCE HIBERNATE_SEQUENCE MINVALUE 90000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;  

CREATE OR REPLACE TRIGGER STAFF_ID_TRG BEFORE INSERT ON STAFF  
FOR EACH ROW  
BEGIN  
    IF INSERTING AND :NEW.ID IS NULL THEN  
        SELECT HIBERNATE_SEQUENCE.CURRVAL INTO :NEW.ID FROM DUAL;  
    END IF;  
END;

CREATE TABLE STAFF (
ID NUMBER(19,0) DEFAULT '0' NOT NULL,
NAME VARCHAR2(255) NOT NULL,
AGE NUMBER(3,0) NOT NULL,
BIRTHDAY DATE NOT NULL,
SALARY NUMBER(10,2) NOT NULL,
LEVELNESS FLOAT NOT NULL,
CREATETIME TIMESTAMP NOT NULL,
ENABLE CHAR(2) DEFAULT 'Y' NOT NULL,
STATUS VARCHAR2(64) NOT NULL,
DEPARTMENT_ID NUMBER(19,0)
);
ALTER TABLE STAFF ADD CONSTRAINT PRIMARY_1 PRIMARY KEY(ID) ENABLE;
ALTER TABLE STAFF ADD CONSTRAINT STAFF_IBFK_0 FOREIGN KEY(DEPARTMENT_ID) REFERENCES DEPARTMENT(ID) ENABLE;
ALTER TABLE STAFF ADD CONSTRAINT UK_STAFF_1 UNIQUE (NAME);
CREATE INDEX IDX_STAFF_STATUS ON STAFF(STATUS);

CREATE SEQUENCE HIBERNATE_SEQUENCE MINVALUE 90000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;

CREATE OR REPLACE TRIGGER STAFF_ID_TRG BEFORE INSERT ON STAFF
FOR EACH ROW
BEGIN
IF INSERTING AND :NEW.ID IS NULL THEN
   SELECT HIBERNATE_SEQUENCE.CURRVAL INTO :NEW.ID FROM DUAL;
END IF;
END;

创建STAFF表,但是并没有为STAFF创建相应的主键sequence,而是创建了一个名字为HIBERNATE_SEQUENCE的 sequence,然后创建一个触发器STAFF_ID_TRG,当执行INSERT操作时,hibernate会先执行一次 HIBERNATE_SEQUENCE.NEXTVAL,所以在触发器中只需要取得HIBERNATE_SEQUENCE.CURRVAL作为新记录的 ID。

[2]hibernate映射文件的配置:
Java代码
<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC  
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
<hibernate-mapping package="com.liyanframework.demo.domain">  
    <class name="Staff" table="STAFF">  
        <id name="id" column="ID">  
            <generator class="native" />  
        </id>  
        <property name="name" column="NAME" type="string" />  
        <property name="age" column="AGE" type="integer" />  
        <property name="birthday" column="BIRTHDAY" type="date" />  
        <property name="salary" column="SALARY" type="big_decimal" />  
        <property name="level" column="LEVELNESS" type="float" />  
        <property name="createTime" column="CREATETIME" type="timestamp" />  
        <property name="enable" column="ENABLE" type="character" />  
        <property name="status" column="STATUS" type="string" />  
        <many-to-one name="department" column="DEPARTMENT_ID" class="Department" />  
    </class>  
</hibernate-mapping>

在hibernate映射文件中,对ID的生成策略选择native,hibernate会根据你数据库的触发器来生成新记录的ID。[/list]
比 较两种做法,第二种做法也就是hibernate在代码中,实现了oracle中的触发器功能。对于不同的情况,选择不懂的做法。如果新的系统,新建的 oracle数据库,推荐使用第一种做法,简单,容易移植到其他支持自动增长的数据库;如果是老的系统,需要把其他数据库转换为oracle的,那就要用 第二种了,使用native的方式,可以不改动配置文件,兼容oracle和mysql之类带有自动增长的数据库。
posted @ 2011-03-26 23:40 甜咖啡 阅读(1907) | 评论 (0)编辑 收藏

通常在数据库或者现实的实体关系中存在3种现象: 1-1  ,1-N , N-N  其中1对1的关系 好比一个丈夫 只有一个 妻子 ,一个妻子也只有一个老婆,一对多的关系 就像 1个人能有多个 房子,而一个房子只能有一个房主, 多对多 好比一个班有多个老师来教,而一个老师能教多个班。

在实体设计中 也存在这样映射关系,一对一 用的比较少,一对多或者 多对多 用的比较常见。

先来介绍下一对一 ;

 每种映射关系都存在 有连接表和无连接表 两种情况,下面我都讲解 无连接表的情况。

第一种情况; 基于外键的双向 关联

什么意思呢; 基于外键的关联好比 一个表的外键是另一个表的主键,学过数据库的朋友应该都知道这种主从表关系(父子表关系)。

数据的表设计就不多做解释了,下面着重讲解 映射文件的写法;

在hibernate框架中的我们都知道 一个表应该对应一个实体 即模型(bean) 所有主从表的话基本要设计两个bean对象,那么每个bean对象就必须写上一个xml问价作为hibernate框架 控制的桥梁。

在主表对应的bean对象的 xml文件的写法如下;

<hibernate-mapping package="lee‘>

<class name="对应bean对象的全路径" table=“对应的表名">

    <id name="id的名字" column="表中的字段名" > <!-- 如果 两个的名字一样的则column可以不写-->

       <ganerator class="native” /> 主键生成策略</id>

<property name="其他的属性名">

........

<!-- 关键代码-->

    主bean 类的写法加上一个属性 表示 另一个 bean的 变量,在子bean中同样如此

    <one-to-one name="对应子表中的对象的变量名"

" class="另一个bean对象的全路径" cascade="all" property-ref="在另一个bean中代表本类的变量名"></one-to-one>  cascade="all"表示 同步两个表

</class>

</ hibernate-mapping>

另一个bean ,即子表bean的xml文件的写法

<前面和主bean一样>

主键生成策略:foreign

<many-to-one name="对应主bean对象的变量名" unique=“true”表示唯一外键

column=“外键名”

class="主bean的全路径"></many-to-one>

 

2:基于主键的双向 1-1关联

什么是基于主键 ; 即一个表的主键是另一个的主键,一个的主键变化 另一个表也同时变化

xml写法

<one-to-one name="另一个bean的变量名" class=“另一个bean的全路径” cascade="all">

posted @ 2011-03-26 23:39 甜咖啡 阅读(770) | 评论 (0)编辑 收藏

刚接触java的ssh框架,有很多东西都不了解,最近遇到复合主键的问题,不知道在前台jsp页面中如何调用复合主键,网上查到了一篇博文(http://blog.csdn.net/ttaaoo36/archive/2010/07/26/5766810.aspx)解决了这个问题,现在也把我的内容贴出来。

1.oracle中建表语句

drop table CUSTRICH cascade constraints;

/*==============================================================*/
/* Table: CUSTRICH                                              */
/*==============================================================*/
create table CUSTRICH  (
   BRANCH_NO            CHAR(10)                        not null,
   YYYYMM               DATE                            not null,
   CNY_BAL              NUMBER,
   NONCNY_BAL           NUMBER,
   LOAN_TOT_CNY         NUMBER,
   LOAN_TOT_NONCNY      NUMBER,
   RICH_BALCASHUNIT     NUMBER,
   BDF10FR_TOT_BAL      NUMBER,
   FOUND_TOT            NUMBER,
   INSURANCEFEEAMT      NUMBER,
   CD03_CURR_BAL        NUMBER,
   FN1TON_COUNT         NUMBER,
   FNSETPLN_COUNT       NUMBER,
   TPCCACCBAL           NUMBER,
   APPLICATION_ID       NUMBER,
   JGDM                 NUMBER,
   ZCRMBHJ              NUMBER,
   "Reserve1"           NUMBER,
   ASSET_TOT_CNY        NUMBER,
   "Reserve3"           NUMBER,
   "Reserve4"           NUMBER,
   "Reserve5"           NUMBER,
   "Reserve6"           NUMBER,
   "Reserve7"           NUMBER,
   "Reserve8"           NUMBER,
   "Reserve9"           NUMBER,
   "Reserve10"          NUMBER,
   constraint PK_CUSTRICH primary key (BRANCH_NO, YYYYMM)
);

两个字段branch_no 和yyyymm 复合为一个主键

2. hibernate映射为两个java类文件  :Custrich.java和 CustrichId.java

Custrich.java   内容如下

package com.hljzr.bean;

import java.math.BigDecimal;

/**
 * Custrich entity. @author MyEclipse Persistence Tools
 */

public class Custrich implements java.io.Serializable {

 // Fields

 private CustrichId id;
 private BigDecimal cnyBal;
 private BigDecimal noncnyBal;
 private BigDecimal loanTotCny;
 private BigDecimal loanTotNoncny;
 private BigDecimal richBalcashunit;
 private BigDecimal bdf10frTotBal;
 private BigDecimal foundTot;
 private BigDecimal insurancefeeamt;
 private BigDecimal cd03CurrBal;
 private BigDecimal fn1tonCount;
 private BigDecimal fnsetplnCount;
 private BigDecimal tpccaccbal;
 private BigDecimal applicationId;
 private BigDecimal jgdm;
 private BigDecimal zcrmbhj;
 private BigDecimal reserve1;
 private BigDecimal assetTotCny;
 private BigDecimal reserve3;
 private BigDecimal reserve4;
 private BigDecimal reserve5;
 private BigDecimal reserve6;
 private BigDecimal reserve7;
 private BigDecimal reserve8;
 private BigDecimal reserve9;
 private BigDecimal reserve10;

 // Constructors

 /** default constructor */
 public Custrich() {
 }

 /** minimal constructor */
 public Custrich(CustrichId id) {
  this.id = id;
 }

 /** full constructor */
 public Custrich(CustrichId id, BigDecimal cnyBal, BigDecimal noncnyBal,
   BigDecimal loanTotCny, BigDecimal loanTotNoncny,
   BigDecimal richBalcashunit, BigDecimal bdf10frTotBal,
   BigDecimal foundTot, BigDecimal insurancefeeamt,
   BigDecimal cd03CurrBal, BigDecimal fn1tonCount,
   BigDecimal fnsetplnCount, BigDecimal tpccaccbal,
   BigDecimal applicationId, BigDecimal jgdm, BigDecimal zcrmbhj,
   BigDecimal reserve1, BigDecimal assetTotCny, BigDecimal reserve3,
   BigDecimal reserve4, BigDecimal reserve5, BigDecimal reserve6,
   BigDecimal reserve7, BigDecimal reserve8, BigDecimal reserve9,
   BigDecimal reserve10) {
  this.id = id;
  this.cnyBal = cnyBal;
  this.noncnyBal = noncnyBal;
  this.loanTotCny = loanTotCny;
  this.loanTotNoncny = loanTotNoncny;
  this.richBalcashunit = richBalcashunit;
  this.bdf10frTotBal = bdf10frTotBal;
  this.foundTot = foundTot;
  this.insurancefeeamt = insurancefeeamt;
  this.cd03CurrBal = cd03CurrBal;
  this.fn1tonCount = fn1tonCount;
  this.fnsetplnCount = fnsetplnCount;
  this.tpccaccbal = tpccaccbal;
  this.applicationId = applicationId;
  this.jgdm = jgdm;
  this.zcrmbhj = zcrmbhj;
  this.reserve1 = reserve1;
  this.assetTotCny = assetTotCny;
  this.reserve3 = reserve3;
  this.reserve4 = reserve4;
  this.reserve5 = reserve5;
  this.reserve6 = reserve6;
  this.reserve7 = reserve7;
  this.reserve8 = reserve8;
  this.reserve9 = reserve9;
  this.reserve10 = reserve10;
 }

 // Property accessors

 public CustrichId getId() {
  return this.id;
 }

 public void setId(CustrichId id) {
  this.id = id;
 }

 public BigDecimal getCnyBal() {
  return this.cnyBal;
 }

 public void setCnyBal(BigDecimal cnyBal) {
  this.cnyBal = cnyBal;
 }

 public BigDecimal getNoncnyBal() {
  return this.noncnyBal;
 }

 public void setNoncnyBal(BigDecimal noncnyBal) {
  this.noncnyBal = noncnyBal;
 }

 public BigDecimal getLoanTotCny() {
  return this.loanTotCny;
 }

 public void setLoanTotCny(BigDecimal loanTotCny) {
  this.loanTotCny = loanTotCny;
 }

 public BigDecimal getLoanTotNoncny() {
  return this.loanTotNoncny;
 }

 public void setLoanTotNoncny(BigDecimal loanTotNoncny) {
  this.loanTotNoncny = loanTotNoncny;
 }

 public BigDecimal getRichBalcashunit() {
  return this.richBalcashunit;
 }

 public void setRichBalcashunit(BigDecimal richBalcashunit) {
  this.richBalcashunit = richBalcashunit;
 }

 public BigDecimal getBdf10frTotBal() {
  return this.bdf10frTotBal;
 }

 public void setBdf10frTotBal(BigDecimal bdf10frTotBal) {
  this.bdf10frTotBal = bdf10frTotBal;
 }

 public BigDecimal getFoundTot() {
  return this.foundTot;
 }

 public void setFoundTot(BigDecimal foundTot) {
  this.foundTot = foundTot;
 }

 public BigDecimal getInsurancefeeamt() {
  return this.insurancefeeamt;
 }

 public void setInsurancefeeamt(BigDecimal insurancefeeamt) {
  this.insurancefeeamt = insurancefeeamt;
 }

 public BigDecimal getCd03CurrBal() {
  return this.cd03CurrBal;
 }

 public void setCd03CurrBal(BigDecimal cd03CurrBal) {
  this.cd03CurrBal = cd03CurrBal;
 }

 public BigDecimal getFn1tonCount() {
  return this.fn1tonCount;
 }

 public void setFn1tonCount(BigDecimal fn1tonCount) {
  this.fn1tonCount = fn1tonCount;
 }

 public BigDecimal getFnsetplnCount() {
  return this.fnsetplnCount;
 }

 public void setFnsetplnCount(BigDecimal fnsetplnCount) {
  this.fnsetplnCount = fnsetplnCount;
 }

 public BigDecimal getTpccaccbal() {
  return this.tpccaccbal;
 }

 public void setTpccaccbal(BigDecimal tpccaccbal) {
  this.tpccaccbal = tpccaccbal;
 }

 public BigDecimal getApplicationId() {
  return this.applicationId;
 }

 public void setApplicationId(BigDecimal applicationId) {
  this.applicationId = applicationId;
 }

 public BigDecimal getJgdm() {
  return this.jgdm;
 }

 public void setJgdm(BigDecimal jgdm) {
  this.jgdm = jgdm;
 }

 public BigDecimal getZcrmbhj() {
  return this.zcrmbhj;
 }

 public void setZcrmbhj(BigDecimal zcrmbhj) {
  this.zcrmbhj = zcrmbhj;
 }

 public BigDecimal getReserve1() {
  return this.reserve1;
 }

 public void setReserve1(BigDecimal reserve1) {
  this.reserve1 = reserve1;
 }

 public BigDecimal getAssetTotCny() {
  return this.assetTotCny;
 }

 public void setAssetTotCny(BigDecimal assetTotCny) {
  this.assetTotCny = assetTotCny;
 }

 public BigDecimal getReserve3() {
  return this.reserve3;
 }

 public void setReserve3(BigDecimal reserve3) {
  this.reserve3 = reserve3;
 }

 public BigDecimal getReserve4() {
  return this.reserve4;
 }

 public void setReserve4(BigDecimal reserve4) {
  this.reserve4 = reserve4;
 }

 public BigDecimal getReserve5() {
  return this.reserve5;
 }

 public void setReserve5(BigDecimal reserve5) {
  this.reserve5 = reserve5;
 }

 public BigDecimal getReserve6() {
  return this.reserve6;
 }

 public void setReserve6(BigDecimal reserve6) {
  this.reserve6 = reserve6;
 }

 public BigDecimal getReserve7() {
  return this.reserve7;
 }

 public void setReserve7(BigDecimal reserve7) {
  this.reserve7 = reserve7;
 }

 public BigDecimal getReserve8() {
  return this.reserve8;
 }

 public void setReserve8(BigDecimal reserve8) {
  this.reserve8 = reserve8;
 }

 public BigDecimal getReserve9() {
  return this.reserve9;
 }

 public void setReserve9(BigDecimal reserve9) {
  this.reserve9 = reserve9;
 }

 public BigDecimal getReserve10() {
  return this.reserve10;
 }

 public void setReserve10(BigDecimal reserve10) {
  this.reserve10 = reserve10;
 }

}

CustrichId.java  内容如下:

package com.hljzr.bean;

import java.util.Date;

/**
 * CustrichId entity. @author MyEclipse Persistence Tools
 */

public class CustrichId implements java.io.Serializable {

 // Fields

 private String branchNo;
 private Date yyyymm;

 // Constructors

 /** default constructor */
 public CustrichId() {
 }

 /** full constructor */
 public CustrichId(String branchNo, Date yyyymm) {
  this.branchNo = branchNo;
  this.yyyymm = yyyymm;
 }

 // Property accessors

 public String getBranchNo() {
  return this.branchNo;
 }

 public void setBranchNo(String branchNo) {
  this.branchNo = branchNo;
 }

 public Date getYyyymm() {
  return this.yyyymm;
 }

 public void setYyyymm(Date yyyymm) {
  this.yyyymm = yyyymm;
 }

 public boolean equals(Object other) {
  if ((this == other))
   return true;
  if ((other == null))
   return false;
  if (!(other instanceof CustrichId))
   return false;
  CustrichId castOther = (CustrichId) other;

  return ((this.getBranchNo() == castOther.getBranchNo()) || (this
    .getBranchNo() != null
    && castOther.getBranchNo() != null && this.getBranchNo()
    .equals(castOther.getBranchNo())))
    && ((this.getYyyymm() == castOther.getYyyymm()) || (this
      .getYyyymm() != null
      && castOther.getYyyymm() != null && this.getYyyymm()
      .equals(castOther.getYyyymm())));
 }

 public int hashCode() {
  int result = 17;

  result = 37 * result
    + (getBranchNo() == null ? 0 : this.getBranchNo().hashCode());
  result = 37 * result
    + (getYyyymm() == null ? 0 : this.getYyyymm().hashCode());
  return result;
 }

}

hashCode和equals方法是用来控制主键内容不能为空和不能重复的。

3.Custrich.hbm.xml的配置内容为:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.hljzr.bean.Custrich" table="CUSTRICH" schema="YHXM">
        <composite-id name="id" class="com.hljzr.bean.CustrichId">
            <key-property name="branchNo" type="java.lang.String">
                <column name="BRANCH_NO" length="10" />
            </key-property>
            <key-property name="yyyymm" type="java.util.Date">
                <column name="YYYYMM" length="7" />
            </key-property>
        </composite-id>
        <property name="cnyBal" type="java.math.BigDecimal">
            <column name="CNY_BAL" precision="22" scale="0" />
        </property>
        <property name="noncnyBal" type="java.math.BigDecimal">
            <column name="NONCNY_BAL" precision="22" scale="0" />
        </property>
        <property name="loanTotCny" type="java.math.BigDecimal">
            <column name="LOAN_TOT_CNY" precision="22" scale="0" />
        </property>
        <property name="loanTotNoncny" type="java.math.BigDecimal">
            <column name="LOAN_TOT_NONCNY" precision="22" scale="0" />
        </property>
        <property name="richBalcashunit" type="java.math.BigDecimal">
            <column name="RICH_BALCASHUNIT" precision="22" scale="0" />
        </property>
        <property name="bdf10frTotBal" type="java.math.BigDecimal">
            <column name="BDF10FR_TOT_BAL" precision="22" scale="0" />
        </property>
        <property name="foundTot" type="java.math.BigDecimal">
            <column name="FOUND_TOT" precision="22" scale="0" />
        </property>
        <property name="insurancefeeamt" type="java.math.BigDecimal">
            <column name="INSURANCEFEEAMT" precision="22" scale="0" />
        </property>
        <property name="cd03CurrBal" type="java.math.BigDecimal">
            <column name="CD03_CURR_BAL" precision="22" scale="0" />
        </property>
        <property name="fn1tonCount" type="java.math.BigDecimal">
            <column name="FN1TON_COUNT" precision="22" scale="0" />
        </property>
        <property name="fnsetplnCount" type="java.math.BigDecimal">
            <column name="FNSETPLN_COUNT" precision="22" scale="0" />
        </property>
        <property name="tpccaccbal" type="java.math.BigDecimal">
            <column name="TPCCACCBAL" precision="22" scale="0" />
        </property>
        <property name="applicationId" type="java.math.BigDecimal">
            <column name="APPLICATION_ID" precision="22" scale="0" />
        </property>
        <property name="jgdm" type="java.math.BigDecimal">
            <column name="JGDM" precision="22" scale="0" />
        </property>
        <property name="zcrmbhj" type="java.math.BigDecimal">
            <column name="ZCRMBHJ" precision="22" scale="0" />
        </property>
        <property name="reserve1" type="java.math.BigDecimal">
            <column name="RESERVE1" precision="22" scale="0" />
        </property>
        <property name="assetTotCny" type="java.math.BigDecimal">
            <column name="ASSET_TOT_CNY" precision="22" scale="0" />
        </property>
        <property name="reserve3" type="java.math.BigDecimal">
            <column name="RESERVE3" precision="22" scale="0" />
        </property>
        <property name="reserve4" type="java.math.BigDecimal">
            <column name="RESERVE4" precision="22" scale="0" />
        </property>
        <property name="reserve5" type="java.math.BigDecimal">
            <column name="RESERVE5" precision="22" scale="0" />
        </property>
        <property name="reserve6" type="java.math.BigDecimal">
            <column name="RESERVE6" precision="22" scale="0" />
        </property>
        <property name="reserve7" type="java.math.BigDecimal">
            <column name="RESERVE7" precision="22" scale="0" />
        </property>
        <property name="reserve8" type="java.math.BigDecimal">
            <column name="RESERVE8" precision="22" scale="0" />
        </property>
        <property name="reserve9" type="java.math.BigDecimal">
            <column name="RESERVE9" precision="22" scale="0" />
        </property>
        <property name="reserve10" type="java.math.BigDecimal">
            <column name="RESERVE10" precision="22" scale="0" />
        </property>
    </class>
</hibernate-mapping>
4.在配置文件applicationContext-common.xml中mapping上面的映射文件

<property name="mappingResources">
   <list>
    <value>com/hljzr/bean/Custrich.hbm.xml</value>
   </list>
  </property>
5.在前台jsp页面中

 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

    <c:if test="${!empty pm.list}">
     <c:set var = "sum" value = "0" />
    <c:forEach items="${pm.list}" var="cus">
     <tr>
      <td>
       ${cus.id.branchNo}    <!--如果写成cus.branchNo就不对了-->
      </td>
      <td>
       ${cus.id.yyyymm}
      </td>
      <td>
       ${cus.insurancefeeamt}
      </td>
      <td>
       ${cus.foundTot}
      </td>
      <td>
       ${cus.foundTot}
      </td>
      <td>
       ${cus.foundTot}
      </td>
     </tr>
     <c:set value="${sum+cus.foundTot}" var="sum" />
    </c:forEach>
   </c:if>

这里的pm是在action中设置的数据库查询结果集,这里就不详述啦

posted @ 2011-03-26 23:38 甜咖啡 阅读(573) | 评论 (0)编辑 收藏

一个客户可以对应多个订单。

表结构:两张表使用powerdesiner设计生成,产生引用错误。

出现问题:1.定义的级联关系只安一中方式生成,即双向的所以删除了parent表的set属性,同时删除映射文件的set集合,

               2.没有定义级联关系cascade属性

 

drop table if exists Customer1;

drop table if exists OrderC1;

/*==============================================================*/
/* Table: Customer1                                             */
/*==============================================================*/
create table Customer1
(
   id                   int not null auto_increment,
   name                 varchar(20),
   primary key (id)
)
type = InnoDB;

/*==============================================================*/
/* Table: OrderC1                                               */
/*==============================================================*/
create table OrderC1
(
   id                   int not null,
   order_id             varchar(20),
   customer_id          int not null,
   primary key (id)
)
type = InnoDB;

alter table OrderC1 add constraint FK_Reference_1111 foreign key (customer_id)
      references Customer1 (id) on delete restrict on update restrict;

注意:因为有外键约束,需要事务支持,在安装数据库的时候,需要配置mysql数据库服务器的参数。数据库的引擎应该用InnoDB

二、通过myeclipse生成实体和配置文件:
           

package many_one;

@SuppressWarnings("serial")
public class Customer1  implements java.io.Serializable {
     private Integer id;
     private String name;
    public Customer1() {
    }
    public Customer1(String name ) {
        this.name = name;
    }

    public Integer getId() {
        return this.id;
    }
   
    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }
   
    public void setName(String name) {
        this.name = name;
    }
}

 

@SuppressWarnings("serial")
public class Orderc1  implements java.io.Serializable {

     private Integer id;
     private Customer1 customer1;
     private String orderId;

    public Orderc1() {
    }

    public Orderc1(Customer1 customer1) {
        this.customer1 = customer1;
    }
   
    public Orderc1(Customer1 customer1, String orderId) {
        this.customer1 = customer1;
        this.orderId = orderId;
    }
    public Integer getId() {
        return this.id;
    }
   
    public void setId(Integer id) {
        this.id = id;
    }

    public Customer1 getCustomer1() {
        return this.customer1;
    }
   
    public void setCustomer1(Customer1 customer1) {
        this.customer1 = customer1;
    }

    public String getOrderId() {
        return this.orderId;
    }
   
    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }
}

配置文件

Customer1.hbm.xml

<hibernate-mapping>
    <class name="many_one.Customer1" table="customer1" catalog="test1" >
        <id name="id" type="integer" >
            <column name="id" not-null="false"/>
            <generator class="increment" />
        </id>
        <property name="name" type="string">
            <column name="name" length="20" />
        </property>
    </class>
</hibernate-mapping>

 

Orderc1.hbm.xml

<hibernate-mapping>
    <class name="many_one.Orderc1" table="orderc1" catalog="test1">
        <id name="id" type="integer">
            <column name="id" />
            <generator class="increment" />
        </id>
        <many-to-one name="customer1" class="many_one.Customer1" fetch="select" cascade="save-update">
            <column name="customer_id" not-null="true" />
        </many-to-one>
        <property name="orderId" type="string">
            <column name="order_id" length="20" />
        </property>
    </class>
</hibernate-mapping>

package many_one;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class tests {

 /**
  * @param args
  */
 public static void main(String[] args) {

  Configuration cfg = new Configuration().configure();
  SessionFactory sf  =cfg.buildSessionFactory();
  Session session =sf.openSession();
  
  Transaction ts = session.beginTransaction();
  
  Customer1 c = new Customer1("c1");
  Orderc1 o = new Orderc1();
  o.setOrderId("23");
  
  o.setCustomer1(c);
  
  session.save(o);
  
  ts.commit();
 
 }


}

posted @ 2011-03-26 23:37 甜咖啡 阅读(477) | 评论 (0)编辑 收藏

package org.hibernate.tutorial.domain;

import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Husband {
    private int id;
    private String name;
    private Wife wife;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Embedded
    public Wife getWife() {
        return wife;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setWife(Wife wife) {
        this.wife = wife;
    }

}

package org.hibernate.tutorial.domain;

import javax.persistence.Column;


public class Wife {
    private int id;
    private String name;
    
    @Column(name="wife_id") //注意映射的组件内属性名不应相同
    public int getId() {
        return id;
    }
    @Column(name="wife_name")
    public String getName() {
        return name;
    }
    public void setId(int id) {
        this.id = id;
    }
    public void setName(String name) {
        this.name = name;
    }

}

package org.hibernate.tutorial.test;

import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.Test;

/**
 * 测试
 * @author MyPC
 *
 */
public class TestHusband {
    @Test
    public void testHusband()
    {
        new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
    }
}

posted @ 2011-03-26 23:37 甜咖啡 阅读(402) | 评论 (0)编辑 收藏
自从ibatis 2.0.9以后,ibatis支持动态表名。 

以下为用Map做参数的动态表名实现方法: 

示例代码如下: 
Sample : 

< select  id ="getRighe"  
remapResults ="true" 
resultMap ="resultRighe"  
parameterClass ="java.util.Map" > 
select * from 
$tablePrefix$_righe 
where IDUser = #IDUser# 
</ select > 

and java code : 

param.put("IDUser", IDUser); 
param.put("tablePrefix", "NAG"); 
utente = (Riga)getSqlMapClientTemplate().queryForObject("getRighe", param); 


但 如果我们要插入一个对象,我们需传进一个POJO对象,由于Ibatis 只能接受一个参数,这时用Map来传对象,会比较麻烦 

可不可以用POJO对象里的一个属性来决定表名呢? 

答案是肯定的。 

在分表设计的数据库中,一般存在许多结构相同,但表名后缀不同的表。 

我们在插入一个新对象到表中里,由自己制定的路由规则是可以得到这个对象要插到那个表里的。即程序知道插到哪个表里,那么 

怎么让Ibatis也知道呢? 

当然你可以把Pojo对象属性全放到Map里,再在Map里加一个表名的属性,传给Ibatis,但这样比较麻烦 

我们可以为每一个POJO对象增加一个表名后缀的属性(或表名),在Ibatis里直接用这个属性做表名。 

不过,且记,用“$”来界定这个属性的名字,而不是“#” 

因为,在Ibatis里,每一个#,除了替换值,它都会加上一个单引号'. 

如下例所示:(假设,你在Pojo对象里,增加了一个suffix的属性,就可以这样来决定插入表名) 

INSERT INTO myTable$suffix$  
     (column1,column2)   
   VALUES (#column1#,#column2#) 
   
这时的parameterClass仍为你的Pojo类。 


Ibatis能比较方便地实现数据库的分表问题,Hibernate可以用NamingStrategy实现动态表名映射 


以下内容引自:http://jinguo.javaeye.com/blog/209642 

用一个配置文件,一个类去映射多个表,(每个表的结构相同)。按照平时的做法,有多少个表就要 
写多少个配置文件,岂不是很麻烦。怎样才能只写一个配置文件就能达到上述目的呢? 

   经过研究,发现Hibernate中的NamingStrategy可以达到这个目的。它是用来定义表名和列名映射规 
则的一个接口。我们要通过实现这个接口来实现自己的命名策略。这个接口中包含的十个方法,其中的 
public String classToTableName(String className)是通过类名来映射表名的。实现我们的想法就要用 
到这个方法。好了,下面来看怎么做: 

   1、自定义一个类MyNamingStrategy来实现NamingStrategy。(这样你要实现10个方法,如果其他方法 
不需要,我们可以通过继承它的一个适配器类DefaultNamingStrategy来只实现我们需要的方法)好了,我 
们就继承DefaultNamingStrategy 吧。 
   
      2、实现public String classToTableName(String className)方法来实现自己命名策略。 

      例如业务需要是每隔一个月就要换一个表。比如1月用biz_1,那么2月就用biz_2....但是这些表的结构是相同的。我们要做的就是通过获得月份来动态的选择表。我们从这个方法中这样写: 
    public class MyNamingStrategy extends DefaultNamingStrategy { 
        public static final MyNamingStrategy INSTANCE = new MyNamingStrategy(); 
        public String classToTableName(String className) { 
        return "biz_" + Calendar.getInstance().get(Calendar.DAY_OF_MONTH); 
        } 
    } 

       好了,这样就可以根据月份来动态的选择表名了。 

    3、使用命名策略。 
       要使用这个命名策略可以这样: 
       Configuration cfg = new Configuration() 
               .setNamingStrategy(MyNamingStrategy.INSTANCE) 
               .configure("hibernate.cfg.xml") 
               .addFile("biz.hbm.xml"); 
---------------------------------- 
for exemple 


package com.etong.common.hibernate; 

import net.sf.hibernate.cfg.NamingStrategy; 
import net.sf.hibernate.util.StringHelper; 

/** 
* <p>Title: TNamingStrategy</p> 
* <p>Description: </p> 
* <p>Copyright: Copyright (c) 2005</p> 
* <p>Company: </p> 
* <p>Created on 2005-5-30 </p> 
* @author jinguo 
* @version 1.0 
* 
*/ 

public class TNamingStrategy implements NamingStrategy { 

/** 
* @see net.sf.hibernate.cfg.NamingStrategy#classToTableName(java.lang.String) 
*/ 
public String classToTableName(String className) { 
return tableName(StringHelper.unqualify(className).toUpperCase()); 
} 

/** 
* @see net.sf.hibernate.cfg.NamingStrategy#propertyToColumnName(java.lang.String) 
* @todo 
*/ 
public String propertyToColumnName(String arg0) { 
return null; 
} 

/** 
* @see net.sf.hibernate.cfg.NamingStrategy#tableName(java.lang.String) 
*/ 
public String tableName(String tableName) { 
return "TBL_" + tableName.toUpperCase(); 
} 

/** 
* @see net.sf.hibernate.cfg.NamingStrategy#columnName(java.lang.String) 
*/ 
public String columnName(String columnName) { 
return "COL_" + columnName; 
} 

/** 
* @see net.sf.hibernate.cfg.NamingStrategy#propertyToTableName(java.lang.String, java.lang.String) 
* @todo 
*/ 
public String propertyToTableName(String arg0, String arg1) { 
return null; 
} 

}
posted @ 2011-03-26 23:36 甜咖啡 阅读(7205) | 评论 (0)编辑 收藏

一对一关联映射(单双向)


1 单向

主要是配置文件上的标签配置
比如对于person和idcard两个pojo类。
Person持有idcard的引用。在person.hbm.xml里,person的主键要来源于idcard类,也就是共享idcard的

主键。配置:<id name= "id">
<generator class="foreign(而不是原来的native)">
<param name="property(必须是这个)">idcard(用来关联到person类的idcard属性)</param>
</generator>
</id>
另外主要配置<one-to-one>标签,此标签的作用是指示hibernate怎么加载它的关联对象,默认根据主键加

载.
标签name属性是通过person类的idcard,关联到idcard类.
Constrained属性主要声明是外键约束.
<one-to-one name="idcard" constrained ="true">


2 双向
双向基本上是从单向演化而来.person.hbm.xml不变,在idcard.java里添加person引用,
在idcard.hbm.xml里加入<one-to-one>标签.
<one-to-one name="person"/>

二 多对一关联映射(单双向)


1 单向

多对一及其简单.
比如两个类,user和group.user为多的一方,group为一的一方,只要多的一方在类中持有一的一方的引用,

并且配置文件即user.hbm.xml里加入
<many-to-one name="group" column="groupid"/>
只这一句话便能建立起单向多对一关联映射.
但是,存储的时候要注意,先存一的一方,再存多的一方.
如果想让hibernate自动帮我们存储一的一方,那么就要修改上面的那句话:
<many-to-one name="group" column="groupid" cascade="all"/>
Cascade的意思是级联操作.有"all,save-update,delete,none",默认为none.
即如果要修改多的一方,那hibernate要先把一的一方改了.
这样我们只操作多的一方的增删查改就行了.

2 双向

看下面的一对多就知道,多对一和一对多是相对立的.
一对多关联映射利用了多对一关联映射原理

多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一
一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多

也就是说一对多和多对一的映射策略是一样的,只是站的角度不同

总的来说,在多的一方维护是比较好的.

三 一对多关联映射(单双向)


谁要对,那就在谁类里拿到对方的引用,那就再谁配置文件里配.


1 单向
还是两个类,class和student.

比起不用映射而言,student.hbm.xml不变,class.hbm.xml里多了的是:
<set name="students">
    <key column="classesid"/>
    <one-to-many class="Student"/>
   </set>
分析一下,用set标签的出发点是因为class类里持有student的引用(一个set集合),至于为什么是集合而不

是如以往的一个student直观的引用,是因为外键要设的不只是一个.如果不能理解,就直接理解为必须用

set标签就成了.
那么name属性是拿到引用,子标签key的column属性是在student里加一个字段,名字叫classesid,
而one-to-many标签是指向student类.
如果<hibernate-mapping package="com.bjsxt.hibernate">这样写,
那么在one-to-many标签直接跟类名.
需要注意的是,此时的one-to-many标签里不再像以前的one-to-one标签里用的是name属性而是class属性.

这两个属性的功能要分清楚.

单向一对多有缺点,因为要在一的一端维护,所以多的一段的表里的外键字段不可设为非空.
而且要发出多余的update语句.一般都设为双向的.下面来看双向.


2 双向
双向配置的话class.hbm.xml不变,在student类里持有class类的引用,student.hbm.xml文件配置添加:

<many-to-one name="classes" column="classesid(必须和class.hbm.xml里的<key

column="classesid"/>一致)"/>

这样配置就可以存储.
有三种存储方式.这是第一种.因为是一的一端维护,所以多发两条update.步骤是先挨个存student,再存

class.
第二种先存class,把classid字段存到student里,再挨个存student.也就是反转.class.hbm.xml里:
<set name="students" inverse="true">
第三种把classid字段存到student里,不存student.只存class. 也就是反转并级联操作.class.hbm.xml里

:<set name="students" inverse="true" cascade="all">

关于存储上,基本上就这三种.无论是一对多还是多对一.个人认为比较麻烦.具体应用的时候可以考虑改进

.
多对一的时候,因为站在多的立场,如果不级联,要先存一,把一的数据加到多里的引用,再存多.级联了,因

为不用考虑一的关系,所以只存多.
而一对多的时候,反转不级联,就站在多的立场.也要先存一再存多.反转只是立场转为多对一,所以同上.
反转并级联,也同上.不考虑一.
不反转也不级联,因为站在一的立场,就要先存多.把多加入到一的set集合,再存一.所以呢,立场和先存谁

是对立的.

请消化一下以上的总结.
下面来看多对多.

四 多对多关联映射(单双向)

1 单向.

多对多涉及到第三方表.hibernate会自动生成.一般权限上会用到,比如RBAC模型.
如以往一样,两个类,user和role.同样,user持有role的引用,是一个set集合.(如前面的一对多)
Role.hbm.xml没有变化, User.hbm.xml里多的是:
<set name="roles" table="t_user_role">
    <key column="userid"/>
    <many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/>
   </set>
分析一下,set标签不用多说,table属性是指让hibernate自动建立第三方表名字叫"t_user_role",key标签

是指在此表中生成一个关联到本类(user的)叫userid的字段,
<many-to-many>标签里class属性引入类Role,并在t_user_role里生成一个关联到role的roleid字段.

在t_user_role表里,userid和roleid一并叫做复合主键.因为两者的联合有不可重复性.

其存储流程:1,存入role,2,用一个set集合接住role放到user的set里,(这里交叉存入比较容易看晕)3,挨

个存user.与上面的第二种存储方案差不多.
Load时候就简单,加载进来,在user里用一个遍历挨个从set里拿出来.就得到role表里的值.
执行存入的时候,hibernate就把表t_user_role各个值赋予了.


2 双向


基本上与单向一致.
Role里要持有user的引用,也是set集合,
Role.hbm.xml和user.hbm.xml配置差不多.
<set name="users" table="t_user_role" order-by="userid">
    <key column="roleid"/>
    <many-to-many class="com.bjsxt.hibernate.User" column="userid"/>
   </set>
注意两类对比,保持column属性值一致.

table属性值必须和单向关联中的table属性值一致
<key>中column属性值要与单向关联中的<many-to-many>标签中的column属性值一致
在<many-to-many>中的column属性值要与单向关联中<key>标签的column属性值一致

order-by="userid"属性是用来排序,按照t_user_role表的字段来排.

基本上,hibernate映射关系就是这些了
posted @ 2011-03-26 23:35 甜咖啡 阅读(284) | 评论 (0)编辑 收藏
hibernate 多对多映射配置详解
2008-12-12 17:04

表关系 如图:

Teacher.java文件:
private int id;
private String name;
private Set teachers;

Student.java文件:
private int id;
private String name;
private Set students;

Teacher.hbm.xml 配置文件内容:
<hibernate-mapping>
<class name="com.bean.Teacher" table="teacher">
   <id name="id" type="int">
    <column name="id"></column>
    <generator class="native"></generator>
   </id>
   <property name="name" type="java.lang.String" column="name"></property>
   <set name="students" table="student_teacher" cascade="all">
    <key column="teacher_id"></key>
    <many-to-many class="com.bean.Student" column="student_id"></many-to-many>
   </set>
   </class>
</hibernate-mapping>

Student.hbm.xml 配置文件内容:
<hibernate-mapping>
<class name="com.bean.Student" table="student">
   <id name="id" type="int">
    <column name="id"></column>
    <generator class="native"></generator>
   </id>
   <property name="name" type="java.lang.String" column="name"></property>
<set name="teachers" table="student_teacher" cascade="all">
    <key column="student_id"></key>
    <many-to-many class="com.bean.Teacher" column="teacher_id"></many-to-many>
   </set>

</class>
</hibernate-mapping>

test测试类部分代码:
List list = session.createQuery("from Teacher").list();
   for(int i=0; i<list.size(); i++){
    Teacher teacher = (Teacher)list.get(i);
    System.out.println("Teacher_name: "+teacher.getName());
    Iterator it = teacher.getStudents().iterator();
    while(it.hasNext()){
     Student student =(Student) it.next();
     System.out.println("student_name: "+student.getName());
    }
    System.out.print("---------------------------\n");

}

posted @ 2011-03-26 23:34 甜咖啡 阅读(3526) | 评论 (1)编辑 收藏

一般属性映射

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!--
 package属性,表示当前配置中所写的类名如果没有包名,则默认是这个包中的。
 -->
<hibernate-mapping package="cn.rose.b_hbm">

 <!-- <class>元素表示哪个类与对应哪个表,一个class元素代表一个类的映射。
  name属性,类的全限定名(带包名)。
  table属性,对应的表名,这个属性可以不写,代表表名和对象的简单名称是一样的。
   -->
 <class name="User" table="itcast_user">
  <!-- 一、主键映射  -->
  <id name="id" type="int">
            <generator class="native"/>
  </id>
  <!-- 二、一般属性映射(值类型,在数据库中一个列可以存放的属性,例:int, varchar, date) -->
  <!--
   使用property元素映射值类型的属性。
   name属性:对象中的属性名,必须要有。
   column属性:对应的表中的列名,可以没有,默认为属性名。
   type属性:指定的是数据类型,有两种指定的方式:
      1,指定hibernate类型,例:string, int
      2,指定Java类型,例:java.lang.String, java.lang.Integer
   length属性:指定对应的表中的列的长度限制,可以不写。
         在类型为string,text等时,指定length有效;
         在类型为int,long等时,指定length无效。
   -->
  <property name="name" column="name" type="string" length="32" />
  
  <property name="gender" type="int" />
  <property name="birthday" type="date"  />
  <property name="photo" type="binary" length="512000" />
  <!-- 指定了length=5000,则生成的数据库表中的列的text类型会至少能存5000个字符 -->
  <property name="resume" type="text" length="5000" />
  
  <!-- 三、集合映射(数组、List、Set、Map) -->
  <!-- 四、关联关系映射(一对多,一对一,多对一、继承) -->
 </class>

</hibernate-mapping>

关于集合的映射

 

 

<hibernate-mapping package="cn.rose.d_hbm_collection" >

 <class name="User" table="itcast_user">
  <id name="id">
   <generator class="native"></generator>
  </id>
  <property name="name"></property>
  
  <!-- Set集合映射(addressSet属性) -->
  <set name="addressSet" table="rose_user_addressSet">
   <key column="userId"></key>
   <element column="address" type="string" length="128"></element>
  </set>
  
  <!-- List集合映射(addressList属性) -->
  <list name="addressList" table="rose_user_addressList">
   <key column="userId"></key>
   <list-index column="index_"></list-index>
   <element column="address" type="string" length="128"></element>
  </list>
  
  <!-- Bag集合映射(addressBag属性) -->
  <bag name="addressBag" table="rose_user_addressBag">
   <key column="userId"></key>
   <element column="address" type="string" length="128"></element>
  </bag>  
  
 </class>

</hibernate-mapping>

 

 

联合主键映射

<hibernate-mapping package="cn.rose.c_hbm_id2" >

 <class name="User" table="itcast_user" mutable="true" dynamic-insert="true" dynamic-update="true">
  
  <!-- 一、联合主键映射  -->
  <!--
  <composite-id>
   <key-property name="firstName" column="firstName" type="string" length="32"></key-property>
   <key-property name="lastName" column="lastName" type="string" length="32"></key-property>
  </composite-id>
   -->
  <composite-id name="name" class="Name">
   <key-property name="firstName" column="firstName" type="string" length="32"></key-property>
   <key-property name="lastName" column="lastName" type="string" length="32"></key-property>
  </composite-id>
  
  <property name="birthday" type="date"></property>
 </class>

</hibernate-mapping>
posted @ 2011-03-26 23:33 甜咖啡 阅读(603) | 评论 (0)编辑 收藏

以教师表为例,教师表中还有个Name类嵌套,但是这是如果想把Name表中的两个属性也加在Teacher表中,这时就需要用到组建关联。

package cn.itcast.hibernate.domain;

import java.util.Set;

public class Teacher {

private int id;
private Name name;
private Set<Student> students;
public int getId() {
   return id;
}
public void setId(int id) {
   this.id = id;
}
public String getName() {
   return name;
}
public void setName(String name) {
   this.name = name;
}
public Set<Student> getStudents() {
   return students;
}
public void setStudents(Set<Student> students) {
   this.students = students;
}


}

/**************************************************************************/

Name.java

package cn.itcast.hibernate.domain;

public class Name {

private String firstName;
private String lastName;
public String getFirstName() {
   return firstName;
}
public void setFirstName(String firstName) {
   this.firstName = firstName;
}
public String getLastName() {
   return lastName;
}
public void setLastName(String lastName) {
   this.lastName = lastName;
}


}

/*******************************************************************************/

这时需要在Teacher.hbm.xml映射文件里做如下配置:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.hibernate.domain">

<class name="Teacher">
  
   <id name="id" column="teacher_id">
    <generator class="native"/>
   </id>
    
   <!--<property name="name" column="teacher_name"/>
   -->
   <component name="name" class="Name">
    <property name="firstName" column="first_name"></property>
    <property name="lastName" column="last_name"></property>
   </component>


   <set name="students" table="teacher_student">
    <key column="teacher_id"></key>
    <many-to-many class="Student" column="student_id"></many-to-many>
   </set>

  
</class>

</hibernate-mapping>

/******************************************************************************/

这样就会在一个表里:

posted @ 2011-03-26 23:33 甜咖啡 阅读(313) | 评论 (0)编辑 收藏
Hibernate源代码包简要介绍

net.sf.hibernate.*

该包的类基本上都是接口类和异常类

net.sf.hibernate.cache.*

JCS的实现类

net.sf.hibernate.cfg.*

配置文件读取类

net.sf.hibernate.collection.*

Hibernate集合接口实现类,例如List,Set,Bag等等,Hibernate之所以要自行编写集合接口实现类是为了支持lazy loading

net.sf.hibernate.connection.*

几个数据库连接池的Provider

net.sf.hibernate.dialect.*

支持多种数据库特性,每个Dialect实现类代表一种数据库,描述了该数据库支持的数据类型和其它特点,例如是否有AutoIncrement,是否有Sequence,是否有分页sql等等

net.sf.hibernate.eg.*

Hibernate文档中用到的例子

net.sf.hibernate.engine.*

这个包的类作用比较散

net.sf.hibernate.expression.*

HQL支持的表达式

net.sf.hibernate.hq.*

HQL实现

net.sf.hibernate.id.*

ID生成器

net.sf.hibernate.impl.*

最核心的包,一些重要接口的实现类,如果Session,SessionFactory,Query等

net.sf.hibernate.jca.*

JCA支持,把Session包装为支持JCA的接口实现类

net.sf.hibernate.jmx.*

我不懂JMX,只知道JMX是用来编写App Server的管理程序的,大概是JMX部分接口的实现,使得App Server可以通过JMX接口管理Hibernate

net.sf.hibernate.loader.*

也是很核心的包,主要是生成sql语句的

net.sf.hibernate.lob.*

Blob和Clob支持

net.sf.hibernate.mapping.*

hbm文件的属性实现

net.sf.hibernate.metadata.*

PO的Meta实现

net.sf.hibernate.odmg.*

ODMG是一个ORM标准,这个包是ODMG标准的实现类

net.sf.hibernate.persister.*

核心包,实现持久对象和表之间的映射

net.sf.hibernate.proxy.*

Proxy和Lazy Loading支持

net.sf.hibernate.ps.*

该包是PreparedStatment Cache

net.sf.hibernate.sql.*

生成JDBC sql语句的包

net.sf.hibernate.test.*

测试类,你可以用junit来测试Hibernate

net.sf.hibernate.tool.hbm2ddl.*

用hbm配置文件生成DDL

net.sf.hibernate.transaction.*

Hibernate Transaction实现类

net.sf.hibernate.type.*

Hibernate中定义的持久对象的属性的数据类型

net.sf.hibernate.util.*

一些工具类,作用比较散

net.sf.hibernate.xml.*

XML数据绑定
posted @ 2011-01-23 16:31 甜咖啡 阅读(1140) | 评论 (0)编辑 收藏
以前听起hibernate总感觉是一个很奇怪的东西,不知道是用做什么,只知道是一个框架,今天对hibernate的学习,使我受益匪浅,知道了hibernate的作用。
以前在写程序的时候看,特别是在编写连接数据库程序的时候,总要用到jdbc,提前都感觉到jdbc是一个很好的手工方式,并没有想到更好的实现方法,也不知道jdbc的缺点是什么,因为在做大型项目的时候,必定会要写很多的程序,当然操作数据库的更不可缺,所以每次的有很多都是重复的,而且在对象模型和关系模型之间总会遇到很多的问题,也往往会转来转去的,当用了hibernate后,可以很方便的操作数据,不用写那么麻烦的代码,节省了很多的操作和代码的编写,这样大大提高了代码编写的效率,提高了开发的速度!现在将走向hibernate的世界:
一:首先要使用hibernate框架,必定要引入hibernate2.jar包,当然还要引入很多的包,然后写一个与数据表对应的JavaBean类,与数据库的字段对应,比如一个简单的java类如下:
package tmc.hibernat.domian;

import java.util.Date;

public class User {

private int id;
private String name;
private Date date;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}


}
然后编写一个映射的文件,
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="tmc.hibernat.domian">

<class name="User">
<id name="id">
<generator class="native" />
</id>

<property name="name" unique="true" />
<property name="date" />
</class>
</hibernate-mapping>

在写一个加载数据库和连接数据库的的配置文件:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql:///test</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<mapping resource="tmc/hibernat/domian/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>

在此,一切的准备都已经完成,接下来执行写一些service的java类对数据库进行操作,就可以实现对数据库的操做了
写一个service的java类:
package tmc.hibernate.service;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public final class HibernateUitl {

private static SessionFactory sessionFactory;
private HibernateUitl(){

}
/**
* 初始化代码
*/
static{

//配置的一个实例说明属性允许应用程序在测绘文件被用来当创造一个SessionFactory 
Configuration cfg = new Configuration();
cfg.configure();//读取配置文件
sessionFactory = cfg.buildSessionFactory();//找出配置文件的所有信息
}
/**
*  获取SessionFactory的方法
* @return
*/
    public static SessionFactory getSessionFactory(){
   
    return sessionFactory;
    }
    /**
     * 获取session的方法
     * @return
     */
    public static Session getSession(){
    return sessionFactory.openSession();
    }
}

然后写对数据库的各种操作:
1.写一个接口:
package tmc.hibernat.domian;

public interface UserDao {

public void saveUser(User user);
public User findUserById(int id);
public User findUserByName(String name);
public void updateUser(User user);
public void remove(User user);
}
2.实现接口:
package tmc.hibernate.service;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import tmc.hibernat.domian.User;
import tmc.hibernat.domian.UserDao;

public class UserHibernateImp implements UserDao{
   
/**
* 根据id获取查询数据库的内容
*/
@Override
public User findUserById(int id) {
Session s = null;
try{
s = HibernateUitl.getSession();
//Criteria c = s.createCriteria(User.class);
//c.add(Restrictions.eq("name",name));
User user =(User)s.get(User.class,id);//User.class方便找到映射文件
return user;
}finally{
if(s!=null){
s.close();
}

}
}
   /**
    * 根据用户名,查询用户的信息
    */
@Override
public User findUserByName(String name) {
Session s = null;
try{
s = HibernateUitl.getSession();
Criteria c = s.createCriteria(User.class);
c.add(Restrictions.eq("name",name));
User user =(User)c.uniqueResult();//映射是唯一的
return user;
}finally{
if(s!=null){
s.close();
}

}
}
/**
* 和上面的使用是一样的,只是用不同的查询方式而已
* @param name
* @return
*/
public User findUserByName1(String name) {
Session s = null;
try{
s = HibernateUitl.getSession();
//Criteria c = s.createCriteria(User.class);
//c.add(Restrictions.eq("name",name));
String hql = "from User as user where user.name=:n";
Query q = s.createQuery(hql);
q.setString("n",name);

User user =(User)q.uniqueResult();//映射是唯一的
return user;
}finally{
if(s!=null){
s.close();
}

}
}
    /**
     * 移除数据库一条记录
     * @see tmc.hibernat.domian.UserDao#remove(tmc.hibernat.domian.User)
     */
@Override
public void remove(User user) {
Session s = null;
//创建一个事务
Transaction tx = null;
try{
s = HibernateUitl.getSession();
tx = s.beginTransaction();
s.delete(user);
tx.commit();
}finally{
if(s!=null){
s.close();
}

}

}
    /**
     * 向数据库添加数据
     */
@Override
public void saveUser(User user) {
Session s = null;
//创建一个事务
Transaction tx = null;
try{
s = HibernateUitl.getSession();
tx = s.beginTransaction();
s.save(user);
tx.commit();
}finally{
if(s!=null){
s.close();
}

}
}
  /**
   * 修改数据库数据
   */
@Override
public void updateUser(User user) {
Session s = null;
//创建一个事务
Transaction tx = null;
try{
s = HibernateUitl.getSession();
tx = s.beginTransaction();
s.update(user);
tx.commit();
}finally{
if(s!=null){
s.close();
}

}

}

}
3.测试上面的类:
package tmc.hibernate.service;

import java.util.Date;

import tmc.hibernat.domian.User;
import tmc.hibernat.domian.UserDao;

public class TestDao {

public static void main(String[] args){
UserDao dao = new UserHibernateImp();
User user = new User();
user.setName("name");
user.setDate(new Date());
System.out.println("1111");
dao.saveUser(user);


user.setName("new name");
System.out.println("222");
dao.updateUser(user);

User u = dao.findUserByName(user.getName());
System.out.println("3333");
}
}

这样的话,就可以完成了对数据库的各种操作,这样写真的很方便,很灵活,减少了很多的重复代码,但就是配置文件的时候很麻烦,呵呵,反正很多都这样的,没有十全十美的东西,但只要好用,就足够了!
posted @ 2011-01-23 16:12 甜咖啡 阅读(5212) | 评论 (0)编辑 收藏
Hibernate Jar: hibernate3.jar,这个是hibernate3.0的核心jar包,必须的,呵呵,没的选,像我们常用的Session,Query,Transaction都位于这个jar文件中,必要。

  cglib-2.1.3.jar,CGLIB库,Hibernate用它来实现PO字节码的动态生成,非常核心的库,必要。

  asm.jar ASM字节码库 如果使用“cglib”则必要,必要

  asm-attrs.jar ASM字节码库 如果使用“cglib”则必要,必要

  ehcache.jar EHCache缓存 如果没有其它缓存,则必要,必要

  antlr.jar

  

  ANother Tool for Language Recognition是一个工具,必要

  jta.jar JTA规范,当Hibernate使用JTA的时候需要,不过App Server都会带上,所以也是多余的。但是为了测试方便建议还是带上。必要

  commons-logging.jar Apache Commons包中的一个,包含了日志功能,必须使用的jar包。必要

  commons-collections.jar Apache Commons包中的一个,包含了一些Apache开发的集合类,功能比java.util.*强大。必要

  dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。Hibernate用它来读写配置文件。必要

  上面的就是Hibernate的核心jar包,是配置ssh架构中必须的,下面这些就是可选的了。

  versioncheck.jar 版本检查 可选

  swarmcache.jar 可选

  jboss-cache.jar TreeCache 可选

  jgroups.jar 可选

  xalan.jar, xerces.jar, xml-apis.jar Xerces是XML解析器,Xalan是格式化器,xml-apis实际上是JAXP。一般App Server都会带上,JDK1.4也包含了解析器,不过不是Xerces,是Crimson,效率比较差,不过Hibernate用XML只不过是读取配置文件,性能没什么要紧的,所以也是多余的。可选

  c3p0-0.9.1.jar C3p0是一个数据库连接池,Hibernate可以配置为使用C3P0连接池。如果你准备用这个连接池,就需要这个jar包。

  可选

  connector.jar JCA API,如果你字啊App Server上把Hibernate配置为Connector的话,就需要这个Jar,不过实际上一般App Server肯定会带上这个包,所以也是多余的包 可选

  jboss-system.jar 可选

  jboss-system.jar 使用TreeCache时必要 可选

  jacc-1_0-fr.jar JACC库 可选

  checkstyle-all.jar 可选

  junit.jar 测试单元 可选

  javassist.jar Javassist字节码解释器 可选

  ant-lanuncher.jar 可选

  jaas.jar JAAS API 是用来进行权限验证的,已经包含在JDK1.4里面了,所以实际上是个多余的包 可选

  jdbc2_0-stdext.jar JDBC扩展API,一般来说数据库连接池会用上它,不过App Server都会带上,所以也是多余的。 可选

  ant-antlr.jar Ant anlr支持 可选

  jboss-jmx.jar 可选

  cleanimports.jar cleanimports 可选 xerces.jar SAX parser jdk本版低于1.4时必要 可选

  jaxen-1.1-beta-7.jar Jaxen 如果想提高启动性能则去使用 可选

  ant-junit.jar Ant junit support 可选

  ant-swing.jar ant swing support

  ant.jar Ant编译工具的jar包,可选

  proxool.jar Proxool JDBC连接池 可选

  concurrent.jar 使用TreeCache 需要

  syndiag2.jar 可选

  commons.collections.jar,commons-pool.jar, commons-dbcp.jar DBCP数据库连接池,Apache的Jakarta组织开发的,Tomcat的连接池也是DBCP.

  Spring jar 包

  spring.jar 是包含有完整发布模块的单个jar 包。但是不包括mock.jar, aspects.jar, spring-portlet.jar, and spring-hibernate2.jar。

  除了spring.jar文件,Spring还包括有其它21个独立的jar包,各自包含着对应的Spring组件,用户可以根据自己的需要来选择组合,而不必引入整个spring.jar的所有类文件。

  spring-core.jar 这个jar文件包含Spring框架基本的核心工具类。Spring其它的组件要都要使用到这个包里的类,是其它组件基本核心,当然你也可以在自己的系统中使用这些工具类。外部依赖(Commons Logging, Log4J)

  spring-beans.jar 这个jar文件是所有应用都要使用到的,它包含访问配置文件,创建和管理bean以及进行Inversion of Control / Dependency(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI支持,引入spring-core.jar及spring-beans.jar文件就可以了。

  spring-aop.jar 这个jar文件包含在应用中使用Spring的AOP特性时所需的类和源码级元数据的支持。使用基于AOP的Spring的特性,如声明型事务管理(Declaritive Transaction Management),也要在应用里包含这个jar包。外部依赖(spring-core, spring-bean , AOP Alliance, CGLIB, Commons Attributes).

  spring-context.jar 这个jar文件为Spring核心提供了大量的扩展,可以找到Spring ApplicationContext特性时所需的全部类,JNDI所需的全部类,instrumentation组件以及校验Validation方面的相关类。外部依赖spring-beans, spring-aop.

  spring-dao.jar 这个jar文件包含Spring DAO, Spring Transaction进行数据访问的所有类,为了使用声明型事务支持,还需在自己的应用里包含spring-aop.jar外部依赖spring-core, spring-aop, spring-context, JTA API.

  spring-jdbc.jar这个jar文件包含Spring对JDBC数据访问进行封装的所有类。外部依赖spring-beans, spring-dao.

  spring-support.jar 这个jar文件包含支持UI模板(Velocity, FreeMarker, JsperReports, BSH, Groovy, Jruby, Quartz, EHCache)

  spring-web.jar 这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入Web Application Context特性的类,Struts与JSF集成类,文件上传的支持类,Filter类和大量工具辅助类。外部依赖spring-context, Servlet API,(JSP API, JSTL, Commons FileUpload, COS).
spring-webmvc.jar 这个jar文件包含Spring MVC框架相关的所有类。包括框架的Servlets, Web MVC框架,控制器和视图支持。当然,如果你的应用使用了独立的框架,则无需这个JAR文件里的任何类。外部依赖spring-web, sping-support, Tiles, iText,POI.

  spring-portlet.jar spring自己实现的一个类似Spring MVC的框架,包括一个MVC框架和一个控制器。外部依赖spring-web, Portlet API, Spring-webmvc.

  spring-struts.jar Struts框架支持,可以更方便更容易的集成Struts框架,外部依赖spring-web, Struts.

  spring-remoting.jar 这个jar文件包支持EJB,远程调用Remoting(RMI,Hession, Burlap, Http Invoker, JAX-RPC)方面的类。外部依赖spring-aop, spring-context, spring-web,Hessian,Burlap,JAX-RPC,EJB API)。

  spring-jmx.jar 这个jar包提供了对JMX1.0/1.2的支持类。外部依赖spring-beans, spring-aop, JMX API.

  spring-jms.jar 这个jar包提供了对JMS1.0.2/1.1的支持类。

  spring-jca.jar 这个jar包提供了对JCA1.0的支持。

  spring-jdo.jar 这个jar包提供了对JDO1.0/2.0的支持。

  spring-hibernate2.jar 对Hibernate2.1的支持,已经不建议使用

  spring-hibernate3.jar 对Hibernate3.0/3.1/3.2的支持

  spring-toplink.jar对TopLink框架的支持 spring-ibatis.jar 对Ibatis SQL Maps的支持。

  另外的两个包

  spring-mock.jar 这个jar 文件包含Spring 一整套mock 类来辅助应用的测试。Spring 测试套件使用了其中大量mock 类,这样测试就更加简单。模拟HttpServletRequest 和HttpServletResponse 类在Web 应用单元测试是很方便的。并且提供了对JUnit的支持。外部依赖

  spring-aspects.jar 提供对AspectJ的支持,以便可以方便的将面向方面的功能集成进IDE中.

  Struts1.2包介绍:

  commons-digester.jar Digester基于规则的XML文档解析,主要用于XML到Java对象的映射(用来处理struts-config.xml配置文件,以达到通过XML生成相应的对象的功能)。

  commons-beanutils.jar 提供对Java反射和自省API的包装。

  struts的验证框架依赖以下的两个包

  commons-validator.jar(校验方法)和校验规则,支持校验规则的和错误消息的国际化。struts使用它对表单进行验证。

  jakarta-oro.jar 一套文本处理工具,能提供perl5.0兼容的正则表达式AWK-like正则表达式,glob表达式。还提供替换,分割,文件名过滤等功能。

  struts.jar struts的核心Jar包

  antlr.jar 它可以接受词文法语言描述,并能产生识别这些语言的语句的程序。

  Struts2.1.6jar包介绍

  struts2-core-2.1.6.jar struts2的核心jar包。

  freemarker-2.3.13.jar Freemarker是struts2默认的模版语言

  commons-logging-1.0.4.jar

  ognl-2.6.11.jar Struts2默认的表达式语言OGNL:对象图形化导航语言

  xwork-2.1.2.jar 也是Struts2核心包,毕竟struts2很大部分是来自webwork

  commons-io.jar (注意这个与2.0.x版本不同,即使不上传文件这个也是需要的)

  commons-fileupload-1.2.1.jar(注意这个与2.0.x版本不同,即使不上传文件这个也是需要的)。
posted @ 2011-01-23 16:07 甜咖啡 阅读(19419) | 评论 (2)编辑 收藏
今天下午和几个要好的同学在南湖旁的草地上聊天,感觉好就没有这样的心情舒畅,虽然各自有各自的决定与想法,但是在没有离开,没有毕业之前,我们能聚在一 起,感觉还是非常高兴的。回想起在大学的这一年半之间,除了一次和全体室友一块儿出去打篮球,别的就再也没有过集体“出游”了,我很想能和室友们和朋友们 一起留下在南工的“脚印”,但是没办法,有时也只有几个志同道合的人最终能走在一块儿,那些曾经的曾经也只是一个过客。晚上和东炬在大谈数据结构,不但为 考前复习了知识,也同样给自己留下了一段美好的回忆,现在回想起来,在南工的一年半的时间里,能让自己有回忆的事情屈指可数。希望在剩余的一个月里,能尽 可能多的在南工留下属于自己的记忆!
posted @ 2010-12-05 21:54 甜咖啡 阅读(175) | 评论 (0)编辑 收藏
TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
      UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
posted @ 2010-06-29 09:04 甜咖啡 阅读(220) | 评论 (0)编辑 收藏

导航

<2010年6月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

统计

常用链接

留言簿(1)

我参与的团队

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜