随笔:-4 文章:58 评论:4 引用:0
首页 发新随笔
发新文章 联系 聚合管理

2008年12月30日

volatile:
      Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。 这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。 而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。 使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。     由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。
Synchronized:
防止多个线程同时访问相同的代码段。
Transient:
表明类序列化时,变量不必序列化。
posted @ 2010-04-09 13:47 久久不醉 阅读(118) | 评论 (0)编辑 收藏
 

配置一个数据源
    Spring在第三方依赖包中包含了两个数据源的实现类包,其一是Apache的DBCP,其二是 C3P0。可以在Spring配置文件中利用这两者中任何一个配置数据源。

 DBCP数据源
    DBCP类包位于 <spring_home></spring_home>/lib/jakarta-commons/commons-dbcp.jar,DBCP是一个依赖 Jakarta commons-pool对象池机制的数据库连接池,所以在类路径下还必须包括<spring_home></spring_home>/lib/jakarta- commons/commons-pool.jar。下面是使用DBCP配置MySql数据源的配置片断:

xml 代码
  1. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"       
  2.         destroy-method="close">       
  3.     <property name="driverClassName" value="com.mysql.jdbc.Driver" />      
  4.     <property name="url" value="jdbc:mysql://localhost:3309/sampledb" />      
  5.     <property name="username" value="root" />      
  6.     <property name="password" value="1234" />      
  7. </bean>  

BasicDataSource提供了close()方法关闭数据源,所以必须设定destroy-method=”close”属性, 以便Spring容器关闭时,数据源能够正常关闭。除以上必须的数据源属性外,还有一些常用的属性:
    defaultAutoCommit:设置从数据源中返回的连接是否采用自动提交机制,默认值为 true;
    defaultReadOnly:设置数据源是否仅能执行只读操作, 默认值为 false;
    maxActive:最大连接数据库连接数,设置为0时,表示没有限制;
    maxIdle:最大等待连接中的数量,设置为0时,表示没有限制;
    maxWait:最大等待秒数,单位为毫秒, 超过时间会报出错误信息;
    validationQuery:用于验证连接是否成功的查询SQL语句,SQL语句必须至少要返回一行数据, 如你可以简单地设置为:“select count(*) from user”;
    removeAbandoned:是否自我中断,默认是 false ;
    removeAbandonedTimeout:几秒后数据连接会自动断开,在removeAbandoned为true,提供该值;
    logAbandoned:是否记录中断事件, 默认为 false;

C3P0数据源
    C3P0是一个开放源代码的JDBC数据源实现项目,它在lib目录中与Hibernate一起发布,实现了JDBC3和JDBC2扩展规范说明的 Connection 和Statement 池。C3P0类包位于<spring_home></spring_home>/lib/c3p0/c3p0-0.9.0.4.jar。下面是使用C3P0配置一个 Oracle数据源:

xml 代码
  1. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"       
  2.         destroy-method="close">      
  3.     <property name="driverClass" value=" oracle.jdbc.driver.OracleDriver "/>      
  4.     <property name="jdbcUrl" value=" jdbc:oracle:thin:@localhost:1521:ora9i "/>      
  5.     <property name="user" value="admin"/>      
  6.     <property name="password" value="1234"/>      
  7. </bean>  

ComboPooledDataSource和BasicDataSource一样提供了一个用于关闭数据源的close()方法,这样我们就可以保证Spring容器关闭时数据源能够成功释放。
    C3P0拥有比DBCP更丰富的配置属性,通过这些属性,可以对数据源进行各种有效的控制:
    acquireIncrement:当连接池中的连接用完时,C3P0一次性创建新连接的数目;
    acquireRetryAttempts:定义在从数据库获取新连接失败后重复尝试获取的次数,默认为30;
    acquireRetryDelay:两次连接中间隔时间,单位毫秒,默认为1000;
    autoCommitOnClose:连接关闭时默认将所有未提交的操作回滚。默认为false;
    automaticTestTable: C3P0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数,那么属性preferredTestQuery将被忽略。你 不能在这张Test表上进行任何操作,它将中为C3P0测试所用,默认为null;
    breakAfterAcquireFailure:获取连接失败将会引起所有等待获取连接的线程抛出异常。但是数据源仍有效保留,并在下次调   用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认为 false;
    checkoutTimeout:当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒,默认为0;
    connectionTesterClassName: 通过实现ConnectionTester或QueryConnectionTester的类来测试连接,类名需设置为全限定名。默认为 com.mchange.v2.C3P0.impl.DefaultConnectionTester; 
    idleConnectionTestPeriod:隔多少秒检查所有连接池中的空闲连接,默认为0表示不检查;
    initialPoolSize:初始化时创建的连接数,应在minPoolSize与maxPoolSize之间取值。默认为3;
    maxIdleTime:最大空闲时间,超过空闲时间的连接将被丢弃。为0或负数则永不丢弃。默认为0;
    maxPoolSize:连接池中保留的最大连接数。默认为15;
    maxStatements:JDBC的标准参数,用以控制数据源内加载的PreparedStatement数量。但由于预缓存的Statement属 于单个Connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素,如果maxStatements与 maxStatementsPerConnection均为0,则缓存被关闭。默认为0;
    maxStatementsPerConnection:连接池内单个连接所拥有的最大缓存Statement数。默认为0;
    numHelperThreads:C3P0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能,通过多线程实现多个操作同时被执行。默认为3;
    preferredTestQuery:定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个参数能显著提高测试速度。测试的表必须在初始数据源的时候就存在。默认为null;
    propertyCycle: 用户修改系统配置参数执行前最多等待的秒数。默认为300;
    testConnectionOnCheckout:因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都 将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
等方法来提升连接测试的性能。默认为false;
    testConnectionOnCheckin:如果设为true那么在取得连接的同时将校验连接的有效性。默认为false。

读配置文件的方式引用属性:

  1. <bean id="propertyConfigurer"     
  2.         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">      
  3.     <property name="location" value="/WEB-INF/jdbc.properties"/>      
  4. </bean>      
  5. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"       
  6.         destroy-method="close">      
  7.     <property name="driverClassName" value="${jdbc.driverClassName}" />      
  8.     <property name="url" value="${jdbc.url}" />      
  9.     <property name="username" value="${jdbc.username}" />      
  10.     <property name="password" value="${jdbc.password}" />      
  11. </bean>   

    在jdbc.properties属性文件中定义属性值:
    jdbc.driverClassName= com.mysql.jdbc.Driver
    jdbc.url= jdbc:mysql://localhost:3309/sampledb
    jdbc.username=root
    jdbc.password=1234
    提示 经常有开发者在${xxx}的前后不小心键入一些空格,这些空格字符将和变量合并后作为属性的值。如: <property name="username" value=" ${jdbc.username} "></property> 的属性配置项,在前后都有空格,被解析后,username的值为“ 1234 ”,这将造成最终的错误,因此需要特别小心。

 获取JNDI数据源
    如果应用配置在高性能的应用服务器(如WebLogic或Websphere等)上,我们可能更希望使用应用服务器本身提供的数据源。应用服务器的数据源 使用JNDI开放调用者使用,Spring为此专门提供引用JNDI资源的JndiObjectFactoryBean类。下面是一个简单的配置:

xml 代码
  1. <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">      
  2.     <property name="jndiName" value="java:comp/env/jdbc/bbt"/>      
  3. </bean>  

通过jndiName指定引用的JNDI数据源名称。
    Spring 2.0为获取J2EE资源提供了一个jee命名空间,通过jee命名空间,可以有效地简化J2EE资源的引用。下面是使用jee命名空间引用JNDI数据源的配置:

xml 代码
  1. <beans xmlns=http://www.springframework.org/schema/beans    
  2. xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance    
  3. xmlns:jee=http://www.springframework.org/schema/jee    
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans     
  5. http://www.springframework.org/schema/beans/spring-beans-2.0.xsd     
  6. http://www.springframework.org/schema/jee    
  7. http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">      
  8. <jee:jndi-lookup id="dataSource" jndi-name=" java:comp/env/jdbc/bbt"/>      
  9. </beans>  

Spring的数据源实现类
    Spring本身也提供了一个简单的数据源实现类DriverManagerDataSource ,它位于org.springframework.jdbc.datasource包中。这个类实现了javax.sql.DataSource接口,但 它并没有提供池化连接的机制,每次调用getConnection()获取新连接时,只是简单地创建一个新的连接。因此,这个数据源类比较适合在单元测试 或简单的独立应用中使用,因为它不需要额外的依赖类。
     下面,我们来看一下DriverManagerDataSource的简单使用:
当然,我们也可以通过配置的方式直接使用DriverManagerDataSource。

java 代码
  1. DriverManagerDataSource ds = new DriverManagerDataSource ();      
  2. ds.setDriverClassName("com.mysql.jdbc.Driver");      
  3. ds.setUrl("jdbc:mysql://localhost:3309/sampledb");      
  4. ds.setUsername("root");      
  5. ds.setPassword("1234");      
  6. Connection actualCon = ds.getConnection();  

 

小结

    不管采用何种持久化技术,都需要定义数据源。Spring附带了两个数据源的实现类包,你可以自行选择进行定义。在实际部署时,我们可能会直接采用应用服 务器本身提供的数据源,这时,则可以通过JndiObjectFactoryBean或jee命名空间引用JNDI中的数据源。

DBCP与C3PO配置的区别:

C3PO :DBCP:

xml 代码
  1. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">  
  2.     <property name="driverClass">  
  3.         <value>oracle.jdbc.driver.OracleDriver</value>  
  4.     </property>  
  5.     <property name="jdbcUrl">             
  6.         <value>jdbc:oracle:thin:@10.10.10.6:1521:DataBaseName</value>  
  7.      </property>  
  8.     <property name="user">  
  9.         <value>testAdmin</value>  
  10.     </property>  
  11.     <property name="password">  
  12.         <value>123456</value>  
  13.     </property>  
  14. </bean>  

 

xml 代码
  1. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  2.     <property name="driverClassName">  
  3.         <value>oracle.jdbc.driver.OracleDriver</value>  
  4.     </property>  
  5.     <property name="url">             
  6.         <value>jdbc:oracle:thin:@10.10.10.6:1521:DataBaseName</value>  
  7.      </property>  
  8.     <property name="username">  
  9.         <value>testAdmin</value>  
  10.     </property>  
  11.     <property name="password">  
  12.         <value>123456</value>  
  13.     </property>  
  14. </bean>  
posted @ 2010-03-03 14:12 久久不醉 阅读(173) | 评论 (0)编辑 收藏
 

oracle xe universal默认创建AL32UTF8字符集,这种字符集1个汉字占用3个字节,而
ZHS16GBK字符集1个汉字占用2个字节,为了节约空间,我尝试改变数据库的字符集,
但是失败了,因为新字符集不是旧字符集的超集。即使用restrict模式也不行。
考虑到oracle xe 安装时只是建一个空库,仅包含系统表空间等,设想通过手工执行
创建ZHS16GBK字符集数据库的办法实现。
从sybex的10g ocp教材中复制并修改得下面语句,其中E:\ORADATA\TEST是我们要存放
新数据库物理文件的目录,以和旧数据库区分。


CREATE DATABASE XE
CONTROLFILE REUSE
LOGFILE
GROUP 1 'E:\ORADATA\TEST\REDO01.LOG' SIZE 10M,
GROUP 2 'E:\ORADATA\TEST\REDO02.LOG' SIZE 10M,
GROUP 3 'E:\ORADATA\TEST\REDO03.LOG' SIZE 10M
DATAFILE 'E:\ORADATA\TEST\SYSTEM01.DBF' SIZE 400M
AUTOEXTEND ON NEXT 50M MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL
SYSAUX DATAFILE 'E:\ORADATA\TEST\SYSAUX01.DBF' SIZE 250M
AUTOEXTEND ON NEXT 50M MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL
DEFAULT TEMPORARY TABLESPACE temp
TEMPFILE 'E:\ORADATA\TEST\TEMP01.DBF' SIZE 100M
AUTOEXTEND ON NEXT 100M MAXSIZE 8000M
UNDO TABLESPACE undo
DATAFILE 'E:\ORADATA\TEST\undo01.DBF' SIZE 200M
AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL
CHARACTER SET ZHS16GBK
NATIONAL CHARACTER SET AL16UTF16
USER SYS IDENTIFIED BY SYS
USER SYSTEM IDENTIFIED BY SYS
;
在执行这个脚本以前,有3点要注意:
1 要修改F:\oraclexe\app\oracle\product\10.2.0\server\config\scripts\init.ora'

F:\oraclexe\app\oracle\product\10.2.0\server\config\scripts\test.ora'
把所有路径改成E:\ORADATA\TEST及其子目录,为此我们需要在E:\ORADATA\TEST下建立
bdump等目录,这些目录可以从现有的XE数据库F:\oraclexe\app\oracle\admin\XE复制得到。

2 要去掉EXTENT MANAGEMENT LOCAL语句否则执行出错。(没有找出原因)

CREATE DATABASE XE
*
第 1 行出现错误:
ORA-25146: EXTENT MANAGEMENT ?????

3 test.ora中的db_name不能改变,否则执行出错。(没有找出原因)
ORA-02778: Name given for the log directory is invalid

具体执行步骤(以Windows XP为例)
1在cmd命令行窗口执行 net start oracleservicexe
C:\Documents and Settings\Administrator>net start oracleservicexe
OracleServiceXE 服务正在启动 .........
OracleServiceXE 服务已经启动成功。

2 以sys用户登录
C:\Documents and Settings\Administrator>sqlplus /nolog

SQL*Plus: Release 10.2.0.1.0 - Production on 星期二 5月 30 22:07:45 2006

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

SQL> conn / as sysdba
已连接。
3 查看现有的字符集设置
SQL> set lines 140
SQL> select * from nls_database_parameters;

PARAMETER
------------------------------------------------------------
VALUE
-------------------------------------------------------------------
------------------------------------------------------------
NLS_LANGUAGE
AMERICAN

NLS_TERRITORY
AMERICA

NLS_CURRENCY
$

NLS_ISO_CURRENCY
AMERICA

NLS_NUMERIC_CHARACTERS
.,

NLS_CHARACTERSET
AL32UTF8

NLS_CALENDAR
GREGORIAN

NLS_DATE_FORMAT
DD-MON-RR

NLS_DATE_LANGUAGE
AMERICAN

NLS_SORT
BINARY

NLS_TIME_FORMAT
HH.MI.SSXFF AM

NLS_TIMESTAMP_FORMAT
DD-MON-RR HH.MI.SSXFF AM

NLS_TIME_TZ_FORMAT
HH.MI.SSXFF AM TZR

NLS_TIMESTAMP_TZ_FORMAT
DD-MON-RR HH.MI.SSXFF AM TZR

NLS_DUAL_CURRENCY
$

NLS_COMP
BINARY

NLS_LENGTH_SEMANTICS
BYTE

NLS_NCHAR_CONV_EXCP
FALSE

NLS_NCHAR_CHARACTERSET
AL16UTF16

NLS_RDBMS_VERSION
10.2.0.1.0


已选择20行。

SQL> select lengthb('择') from dual;

LENGTHB('择')
-------------
            3

已选择 1 行。

我们可以看到,当前AL32UTF8字符集1个汉字占用3个字节
4 关闭数据库,但不停止服务
QL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
5 用修改过的pfile test.ora启动数据库(nomount)
SQL> startup nomount pfile='F:\oraclexe\app\oracle\product\10.2.0\server\config\scripts\test.ora'
ORACLE 例程已经启动。

Total System Global Area  285212672 bytes
Fixed Size                  1287016 bytes
Variable Size              92277912 bytes
Database Buffers          188743680 bytes
Redo Buffers                2904064 bytes
6 执行建立数据库脚本
SQL> CREATE DATABASE XE
  2  CONTROLFILE REUSE
  3  LOGFILE
  4  GROUP 1 'E:\ORADATA\TEST\REDO01.LOG' SIZE 10M,
  5  GROUP 2 'E:\ORADATA\TEST\REDO02.LOG' SIZE 10M,
  6  GROUP 3 'E:\ORADATA\TEST\REDO03.LOG' SIZE 10M
  7  DATAFILE 'E:\ORADATA\TEST\SYSTEM01.DBF' SIZE 400M
  8  AUTOEXTEND ON NEXT 50M MAXSIZE UNLIMITED
  9  SYSAUX DATAFILE 'E:\ORADATA\TEST\SYSAUX01.DBF' SIZE 250M
 10  AUTOEXTEND ON NEXT 50M MAXSIZE UNLIMITED
 11  DEFAULT TEMPORARY TABLESPACE temp
 12  TEMPFILE 'E:\ORADATA\TEST\TEMP01.DBF' SIZE 100M
 13  AUTOEXTEND ON NEXT 100M MAXSIZE 8000M
 14  UNDO TABLESPACE undo
 15  DATAFILE 'E:\ORADATA\TEST\undo01.DBF' SIZE 200M
 16  AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED
 17  CHARACTER SET ZHS16GBK
 18  NATIONAL CHARACTER SET AL16UTF16
 19  USER SYS IDENTIFIED BY SYS
 20  USER SYSTEM IDENTIFIED BY SYS
 21  ;

数据库已创建。
7 执行创建数据字典和程序包的系统SQL脚本
@F:\oraclexe\app\oracle\product\10.2.0\server\RDBMS\ADMIN\catalog.sql
@F:\oraclexe\app\oracle\product\10.2.0\server\RDBMS\ADMIN\catproc.sql
大约需要10几分钟
8 关闭数据库,但不停止服务
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
9 用修改过的pfile test.ora启动数据库
SQL> startup  pfile='F:\oraclexe\app\oracle\product\10.2.0\server\config\scripts\test.ora'
ORACLE 例程已经启动。

Total System Global Area  285212672 bytes
Fixed Size                  1287016 bytes
Variable Size              92277912 bytes
Database Buffers          188743680 bytes
Redo Buffers                2904064 bytes
数据库装载完毕。
数据库已经打开。
10 查看新建数据库的字符集设置
SQL> set lines 140
SQL> select * from nls_database_parameters;

PARAMETER                      VALUE
------------------------------ -------------------------------------------------
-------------------------------
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               ZHS16GBK
NLS_CALENDAR                   GREGORIAN
NLS_DATE_FORMAT                DD-MON-RR
NLS_DATE_LANGUAGE              AMERICAN
NLS_SORT                       BINARY
NLS_TIME_FORMAT                HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT           DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT             HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT        DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY              $
NLS_COMP                       BINARY
NLS_LENGTH_SEMANTICS           BYTE
NLS_NCHAR_CONV_EXCP            FALSE
NLS_NCHAR_CHARACTERSET         AL16UTF16
NLS_RDBMS_VERSION              10.2.0.1.0

已选择20行。

SQL> select lengthb('A') from dual;

LENGTHB('A')
------------
           1

已选择 1 行。

SQL> select lengthb('择') from dual;

LENGTHB('择')
-------------
            2

已选择 1 行。
可见我们新的数据库的确是ZHS16GBK字符集,1个汉字占用2个字节
11 要启动旧数据库(因为新旧数据库同名,而且oracle xe限制同时只能打开一个数据库)
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup
ORACLE 例程已经启动。

Total System Global Area  285212672 bytes
Fixed Size                  1287016 bytes
Variable Size              96472216 bytes
Database Buffers          184549376 bytes
Redo Buffers                2904064 bytes
数据库装载完毕。
数据库已经打开。

----

如果以后要用spfile自动新建数据库
SQL> create spfile from pfile='D:\oraclexe\app\oracle\product\10.2.0\server\config\scripts\test.ora';

文件已创建。

SQL> shutdown immediate;
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup
ORACLE 例程已经启动。

Total System Global Area 285212672 bytes
Fixed Size 1287016 bytes
Variable Size 92277912 bytes
Database Buffers 188743680 bytes
Redo Buffers 2904064 bytes
数据库装载完毕。
数据库已经打开。
SQL> select lengthb('择') from dual;

LENGTHB('择')
-------------
2

已选择 1 行。

远程登录,客户端也需要10g
SQL> conn system/sys@//10.6.xx.xx:1521/XE
已连接。
SQL> conn sys/sys@//10.6.xx.xx:1521/XE as sysdba
已连接。

[url]http://www.itpub.net/558697.html[/url]
的问题也算得到了解决

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/l1t/archive/2006/05/31/765125.aspx

posted @ 2009-12-28 15:17 久久不醉 阅读(614) | 评论 (0)编辑 收藏
 

        数据字典dict总是属于Oracle用户sys的。
  1、用户:
   select username from dba_users;
  改口令
   alter user spgroup identified by spgtest;
  2、表空间:
   select * from dba_data_files;
   select * from dba_tablespaces;//表空间

   select tablespace_name,sum(bytes), sum(blocks)
    from dba_free_space group by tablespace_name;//空闲表空间

   select * from dba_data_files
    where tablespace_name='RBS';//表空间对应的数据文件

   select * from dba_segments
    where tablespace_name='INDEXS';
  3、数据库对象:
   select * from dba_objects;
   CLUSTER、DATABASE LINK、FUNCTION、INDEX、LIBRARY、PACKAGE、PACKAGE BODY、
   PROCEDURE、SEQUENCE、SYNONYM、TABLE、TRIGGER、TYPE、UNDEFINED、VIEW。
  4、表:
   select * from dba_tables;
   analyze my_table compute statistics;->dba_tables后6列
   select extent_id,bytes from dba_extents
   where segment_name='CUSTOMERS' and segment_type='TABLE'
   order by extent_id;//表使用的extent的信息。segment_type='ROLLBACK'查看回滚段的空间分配信息
   列信息:
    select distinct table_name
    from user_tab_columns
    where column_name='SO_TYPE_ID';
  5、索引: 
   select * from dba_indexes;//索引,包括主键索引
   select * from dba_ind_columns;//索引列
   select i.index_name,i.uniqueness,c.column_name
    from user_indexes i,user_ind_columns c
     where i.index_name=c.index_name
     and i.table_name ='ACC_NBR';//联接使用
  6、序列:
   select * from dba_sequences;
  7、视图:
   select * from dba_views;
   select * from all_views;
  text 可用于查询视图生成的脚本
  8、聚簇:
   select * from dba_clusters;
  9、快照:
   select * from dba_snapshots;
  快照、分区应存在相应的表空间。
  10、同义词:
   select * from dba_synonyms
    where table_owner='SPGROUP';
    //if owner is PUBLIC,then the synonyms is a public synonym.
     if owner is one of users,then the synonyms is a private synonym.
  11、数据库链:
   select * from dba_db_links;
  在spbase下建数据库链
   create database link dbl_spnew
   connect to spnew identified by spnew using 'jhhx';
   insert into acc_nbr@dbl_spnew
   select * from acc_nbr where nxx_nbr='237' and line_nbr='8888';
  12、触发器:
   select * from dba_trigers;
  存储过程,函数从dba_objects查找。
  其文本:select text from user_source where name='BOOK_SP_EXAMPLE';
  建立出错:select * from user_errors;
  oracle总是将存储过程,函数等软件放在SYSTEM表空间。
  13、约束:
  (1)约束是和表关联的,可在create table或alter table table_name add/drop/modify来建立、修改、删除约束。
  可以临时禁止约束,如:
   alter table book_example
   disable constraint book_example_1;
   alter table book_example
   enable constraint book_example_1;
  (2)主键和外键被称为表约束,而not null和unique之类的约束被称为列约束。通常将主键和外键作为单独的命名约束放在字段列表下面,而列约束可放在列定义的同一行,这样更具有可读性。
  (3)列约束可从表定义看出,即describe;表约束即主键和外键,可从dba_constraints和dba_cons_columns 查。
   select * from user_constraints
   where table_name='BOOK_EXAMPLE';
   select owner,CONSTRAINT_NAME,TABLE_NAME
    from user_constraints
    where constraint_type='R'
    order by table_name;
  (4)定义约束可以无名(系统自动生成约束名)和自己定义约束名(特别是主键、外键)
  如:create table book_example
    (identifier number not null);
    create table book_example
    (identifier number constranit book_example_1 not null);
  14、回滚段:
  在所有的修改结果存入磁盘前,回滚段中保持恢复该事务所需的全部信息,必须以数据库发生的事务来相应确定其大小(DML语句才可回滚,create,drop,truncate等DDL不能回滚)。
  回滚段数量=并发事务/4,但不能超过50;使每个回滚段大小足够处理一个完整的事务;
   create rollback segment r05
   tablespace rbs;
   create rollback segment rbs_cvt
   tablespace rbs
   storage(initial 1M next 500k);
  使回滚段在线
   alter rollback segment r04 online;
  用dba_extents,v$rollback_segs监测回滚段的大小和动态增长。
  回滚段的区间信息
   select * from dba_extents
   where segment_type='ROLLBACK' and segment_name='RB1';
  回滚段的段信息,其中bytes显示目前回滚段的字节数
   select * from dba_segments
    where segment_type='ROLLBACK' and segment_name='RB1';
  为事物指定回归段
   set transaction use rollback segment rbs_cvt
  针对bytes可以使用回滚段回缩。
   alter rollback segment rbs_cvt shrink;
   select bytes,extents,max_extents from dba_segments
    where segment_type='ROLLBACK' and segment_name='RBS_CVT';
  回滚段的当前状态信息:
   select * from dba_rollback_segs
    where segment_name='RB1';
  比多回滚段状态status,回滚段所属实例instance_num
  查优化值optimal
   select n.name,s.optsize
    from v$rollname n,v$rollstat s
     where n.usn=s.usn;
  回滚段中的数据
   set transaction use rollback segment rb1;/*回滚段名*/
   select n.name,s.writes
    from v$rollname n,v$rollstat s
     where n.usn=s.usn;
  当事务处理完毕,再次查询$rollstat,比较writes(回滚段条目字节数)差值,可确定事务的大小。
  查询回滚段中的事务
   column rr heading 'RB Segment' format a18
   column us heading 'Username' format a15
   column os heading 'Os User' format a10
   column te heading 'Terminal' format a10
   select r.name rr,nvl(s.username,'no transaction') us,s.osuser os,s.terminal te
    from v$lock l,v$session s,v$rollname r
     where l.sid=s.sid(+)
     and trunc(l.id1/65536)=R.USN
     and l.type='TX'
     and l.lmode=6
   order by r.name;
  15、作业
  查询作业信息
   select job,broken,next_date,interval,what from user_jobs;
   select job,broken,next_date,interval,what from dba_jobs;
  查询正在运行的作业
   select * from dba_jobs_running;
  使用包exec dbms_job.submit(:v_num,'a;',sysdate,'sysdate + (10/(24*60*60))')加入作业。间隔10秒钟
exec dbms_job.submit(:v_num,'a;',sysdate,'sysdate + (11/(24*60))')加入作业。间隔11分钟使用包exec dbms_job.remove(21)删除21号作业。

posted @ 2009-12-22 15:56 久久不醉 阅读(119) | 评论 (0)编辑 收藏
 
一、什么是Java事务
通常的观念认为,事务仅与数据库相关。
事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)的缩写。事务的原子性表示事务执行过程中的任何失败都将导致事务所做的任何修改失效。一致性表示当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态。隔离性表示在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见。持久性表示已提交的数据在事务执行失败时,数据的状态都应该正确。
通俗的理解,事务是一组原子操作单元,从数据库角度说,就是一组SQL指令,要么全部执行成功,若因为某个原因其中一条指令执行有错误,则撤销先前执行过的所有指令。更简答的说就是:要么全部执行成功,要么撤销不执行。
既然事务的概念从数据库而来,那Java事务是什么?之间有什么联系?
实际上,一个Java应用系统,如果要操作数据库,则通过JDBC来实现的。增加、修改、删除都是通过相应方法间接来实现的,事务的控制也相应转移到Java程序代码中。因此,数据库操作的事务习惯上就称为Java事务。
二、为什么需要事务
事务是为解决数据安全操作提出的,事务控制实际上就是控制数据的安全访问。具一个简单例子:比如银行转帐业务,账户A要将自己账户上的1000元转到B账户下面,A账户余额首先要减去1000元,然后B账户要增加1000元。假如在中间网络出现了问题,A账户减去1000元已经结束,B因为网络中断而操作失败,那么整个业务失败,必须做出控制,要求A账户转帐业务撤销。这才能保证业务的正确性,完成这个操走就需要事务,将A账户资金减少和B账户资金增加方到一个事务里面,要么全部执行成功,要么操作全部撤销,这样就保持了数据的安全性。
三、Java事务的类型
Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。
1、JDBC事务
JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。 java.sql.Connection 提供了以下控制事务的方法:
public void setAutoCommit(boolean)
public boolean getAutoCommit()
public void commit()
public void rollback()
使用 JDBC 事务界定时,您可以将多个 SQL 语句结合到一个事务中。JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。
2、JTA(Java Transaction API)事务
JTA是一种高层的,与实现无关的,与协议无关的API,应用程序和应用服务器可以使用JTA来访问事务。
JTA允许应用程序执行分布式事务处理--在两个或多个网络计算机资源上访问并且更新数据,这些数据可以分布在多个数据库上。JDBC驱动程序的JTA支持极大地增强了数据访问能力。
如果计划用 JTA 界定事务,那么就需要有一个实现 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驱动程序。一个实现了这些接口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个 XAConnection 对象的工厂。 XAConnection s 是参与 JTA 事务的 JDBC 连接。
您将需要用应用服务器的管理工具设置 XADataSource 。从应用服务器和 JDBC 驱动程序的文档中可以了解到相关的指导。
J2EE 应用程序用 JNDI 查询数据源。一旦应用程序找到了数据源对象,它就调用 javax.sql.DataSource.getConnection() 以获得到数据库的连接。
XA 连接与非 XA 连接不同。一定要记住 XA 连接参与了 JTA 事务。这意味着 XA 连接不支持 JDBC 的自动提交功能。同时,应用程序一定不要对 XA 连接调用 java.sql.Connection.commit() 或者 java.sql.Connection.rollback() 。相反,应用程序应该使用 UserTransaction.begin()、 UserTransaction.commit() 和 serTransaction.rollback() 。
3、容器事务
容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现。相对编码实现JTA事务管理,我们可以通过EJB容器提供的容器事务管理机制(CMT)完成同一个功能,这项功能由J2EE应用服务器提供。这使得我们可以简单的指定将哪个方法加入事务,一旦指定,容器将负责事务管理任务。这是我们土建的解决方式,因为通过这种方式我们可以将事务代码排除在逻辑编码之外,同时将所有困难交给J2EE容器去解决。使用EJB CMT的另外一个好处就是程序员无需关心JTA API的编码,不过,理论上我们必须使用EJB。
四、三种事务差异
1、JDBC事务控制的局限性在一个数据库连接内,但是其使用简单。
2、JTA事务的功能强大,事务可以跨越多个数据库或多个DAO,使用也比较复杂。
3、容器事务,主要指的是J2EE应用服务器提供的事务管理,局限于EJB应用使用。
五、总结
事务控制是构建J2EE应用不可缺少的一部分,合理选择应用何种事务对整个应用系统来说至关重要。一般说来,在单个JDBC 连接连接的情况下可以选择JDBC事务,在跨多个连接或者数据库情况下,需要选择使用JTA事务,如果用到了EJB,则可以考虑使用EJB容器事务。
参考资料:
《Pro Spring》
posted @ 2009-09-23 16:19 久久不醉 阅读(138) | 评论 (0)编辑 收藏
 
     摘要: 一、cookie机制和session机制的区别 *************************************************************************************        具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态...  阅读全文
posted @ 2009-09-22 15:54 久久不醉 阅读(117) | 评论 (0)编辑 收藏
 
在SQL语句优化过程中,经常会用到hint, 
以下是在SQL优化过程中常见Oracle中"HINT"的30个用法1. /*+ALL_ROWS*/ 
表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化. 
例如: 
SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT'; 

2. /*+FIRST_ROWS*/ 
表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化. 
例如: 
SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT'; 

3. /*+CHOOSE*/ 
表明如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量; 
表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法; 
例如: 
SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT'; 

4. /*+RULE*/ 
表明对语句块选择基于规则的优化方法. 
例如: 
SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT'; 

5. /*+FULL(TABLE)*/ 
表明对表选择全局扫描的方法. 
例如: 
SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO='SCOTT'; 

6. /*+ROWID(TABLE)*/ 
提示明确表明对指定表根据ROWID进行访问. 
例如: 
SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>='AAAAAAAAAAAAAA' 
AND EMP_NO='SCOTT'; 

7. /*+CLUSTER(TABLE)*/ 
提示明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效. 
例如: 
SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS 
WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO; 

8. /*+INDEX(TABLE INDEX_NAME)*/ 
表明对表选择索引的扫描方法. 
例如: 
SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M'; 

9. /*+INDEX_ASC(TABLE INDEX_NAME)*/ 
表明对表选择索引升序的扫描方法. 
例如: 
SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT'; 

10. /*+INDEX_COMBINE*/ 
为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合方式. 
例如: 
SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMS 
WHERE SAL<5000000 AND HIREDATE<SYSDATE; 

11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/ 
提示明确命令优化器使用索引作为访问路径. 
例如: 
SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE 
FROM BSEMPMS WHERE SAL<60000; 

12. /*+INDEX_DESC(TABLE INDEX_NAME)*/ 
表明对表选择索引降序的扫描方法. 
例如: 
SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT'; 

13. /*+INDEX_FFS(TABLE INDEX_NAME)*/ 
对指定的表执行快速全索引扫描,而不是全表扫描的办法. 
例如: 
SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305'; 

14. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/ 
提示明确进行执行规划的选择,将几个单列索引的扫描合起来. 
例如: 
SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHERE EMP_NO='SCOTT' AND DPT_NO='TDC306'; 

15. /*+USE_CONCAT*/ 
对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询. 
例如: 
SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M'; 

16. /*+NO_EXPAND*/ 
对于WHERE后面的OR 或者IN-LIST的查询语句,NO_EXPAND将阻止其基于优化器对其进行扩展. 
例如: 
SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M'; 

17. /*+NOWRITE*/ 
禁止对查询块的查询重写操作. 

18. /*+REWRITE*/ 
可以将视图作为参数. 

19. /*+MERGE(TABLE)*/ 
能够对视图的各个查询进行相应的合并. 
例如: 
SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO 
,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO 
AND A.SAL>V.AVG_SAL; 

20. /*+NO_MERGE(TABLE)*/ 
对于有可合并的视图不再合并. 
例如: 
SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL; 

21. /*+ORDERED*/ 
根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接. 
例如: 
SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 AND B.COL1=C.COL1; 

22. /*+USE_NL(TABLE)*/ 
将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表. 
例如: 
SELECT /*+ORDERED USE_NL(BSEMPMS)*/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO; 

23. /*+USE_MERGE(TABLE)*/ 
将指定的表与其他行源通过合并排序连接方式连接起来. 
例如: 
SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO; 

24. /*+USE_HASH(TABLE)*/ 
将指定的表与其他行源通过哈希连接方式连接起来. 
例如: 
SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO; 

25. /*+DRIVING_SITE(TABLE)*/ 
强制与ORACLE所选择的位置不同的表进行查询执行. 
例如: 
SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO; 

26. /*+LEADING(TABLE)*/ 
将指定的表作为连接次序中的首表. 

27. /*+CACHE(TABLE)*/ 
当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端 
例如: 
SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS; 

28. /*+NOCACHE(TABLE)*/ 
当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端 
例如: 
SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS; 

29. /*+APPEND*/ 
直接插入到表的最后,可以提高速度. 
insert /*+append*/ into test1 select * from test4 ; 

30. /*+NOAPPEND*/ 
通过在插入语句生存期内停止并行模式来启动常规插入. 
insert /*+noappend*/ into test1 select * from test4 ;

posted @ 2009-09-15 16:11 久久不醉 阅读(103) | 评论 (0)编辑 收藏
 
前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识。通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的。

总结如下:

Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。

DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问 时,DataSource实际为SessionFactory,TransactionManager的实现为 HibernateTransactionManager。



根据代理机制的不同,总结了五种Spring事务的配置方式,配置文件如下:

    第一种方式:每个Bean都有一个代理

Java代码
  1. <bean id="sessionFactory"    
  2.            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">    
  3.         <property name="configLocation" value="classpath:hibernate.cfg.xml" />    
  4.         <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />  
  5.     </bean>    
  6.   
  7.     <!-- 定义事务管理器(声明式的事务) -->    
  8.     <bean id="transactionManager"  
  9.        class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  10.         <property name="sessionFactory" ref="sessionFactory" />  
  11.     </bean>  
  12.      
  13.     <!-- 配置DAO -->  
  14.     <bean id="userDaoTarget" class="com.bluesky.spring.dao.UserDaoImpl">  
  15.         <property name="sessionFactory" ref="sessionFactory" />  
  16.     </bean>  
  17.      
  18.     <bean id="userDao"    
  19.        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">    
  20.            <!-- 配置事务管理器 -->    
  21.            <property name="transactionManager" ref="transactionManager" />       
  22.         <property name="target" ref="userDaoTarget" />    
  23.          <property name="proxyInterfaces" value="com.bluesky.spring.dao.GeneratorDao" />  
  24.         <!-- 配置事务属性 -->    
  25.         <property name="transactionAttributes">    
  26.             <props>    
  27.                 <prop key="*">PROPAGATION_REQUIRED</prop>  
  28.             </props>    
  29.         </property>    
  30.     </bean>    
  31. lt;/beans>  

第二种方式:所有Bean共享一个代理基类

Java代码
  1. <bean id="sessionFactory"    
  2.             class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">    
  3.          <property name="configLocation" value="classpath:hibernate.cfg.xml" />    
  4.          <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />  
  5.      </bean>    
  6.   
  7.      <!-- 定义事务管理器(声明式的事务) -->    
  8.      <bean id="transactionManager"  
  9.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  10.          <property name="sessionFactory" ref="sessionFactory" />  
  11.      </bean>  
  12.       
  13.      <bean id="transactionBase"    
  14.             class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"    
  15.              lazy-init="true" abstract="true">    
  16.          <!-- 配置事务管理器 -->    
  17.          <property name="transactionManager" ref="transactionManager" />    
  18.          <!-- 配置事务属性 -->    
  19.          <property name="transactionAttributes">    
  20.              <props>    
  21.                  <prop key="*">PROPAGATION_REQUIRED</prop>    
  22.              </props>    
  23.          </property>    
  24.      </bean>      
  25.      
  26.      <!-- 配置DAO -->  
  27.      <bean id="userDaoTarget" class="com.bluesky.spring.dao.UserDaoImpl">  
  28.          <property name="sessionFactory" ref="sessionFactory" />  
  29.      </bean>  
  30.       
  31.      <bean id="userDao" parent="transactionBase" >    
  32.          <property name="target" ref="userDaoTarget" />     
  33.      </bean>  
  34. </beans>

第三种方式:使用拦截器

Java代码
  1. <bean id="sessionFactory"    
  2.             class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">    
  3.          <property name="configLocation" value="classpath:hibernate.cfg.xml" />    
  4.          <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />  
  5.      </bean>    
  6.   
  7.      <!-- 定义事务管理器(声明式的事务) -->    
  8.      <bean id="transactionManager"  
  9.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  10.          <property name="sessionFactory" ref="sessionFactory" />  
  11.      </bean>   
  12.      
  13.      <bean id="transactionInterceptor"    
  14.         class="org.springframework.transaction.interceptor.TransactionInterceptor">    
  15.          <property name="transactionManager" ref="transactionManager" />    
  16.          <!-- 配置事务属性 -->    
  17.          <property name="transactionAttributes">    
  18.              <props>    
  19.                  <prop key="*">PROPAGATION_REQUIRED</prop>    
  20.              </props>    
  21.          </property>    
  22.      </bean>  
  23.         
  24.      <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">    
  25.          <property name="beanNames">    
  26.              <list>    
  27.                  <value>*Dao</value>  
  28.              </list>    
  29.          </property>    
  30.          <property name="interceptorNames">    
  31.              <list>    
  32.                  <value>transactionInterceptor</value>    
  33.              </list>    
  34.          </property>    
  35.      </bean>    
  36.     
  37.      <!-- 配置DAO -->  
  38.      <bean id="userDao" class="com.bluesky.spring.dao.UserDaoImpl">  
  39.          <property name="sessionFactory" ref="sessionFactory" />  
  40.      </bean>  
  41. </beans>  

第四种方式:使用tx标签配置的拦截器

Java代码
  1. <context:annotation-config />  
  2.     <context:component-scan base-package="com.bluesky" />  
  3.   
  4.     <bean id="sessionFactory"    
  5.            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">    
  6.         <property name="configLocation" value="classpath:hibernate.cfg.xml" />    
  7.         <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />  
  8.     </bean>    
  9.   
  10.     <!-- 定义事务管理器(声明式的事务) -->    
  11.     <bean id="transactionManager"  
  12.        class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  13.         <property name="sessionFactory" ref="sessionFactory" />  
  14.     </bean>  
  15.   
  16.     <tx:advice id="txAdvice" transaction-manager="transactionManager">  
  17.         <tx:attributes>  
  18.             <tx:method name="*" propagation="REQUIRED" />  
  19.         </tx:attributes>  
  20.     </tx:advice>  
  21.      
  22.     <aop:config>  
  23.         <aop:pointcut id="interceptorPointCuts"  
  24.             expression="execution(* com.bluesky.spring.dao.*.*(..))" />  
  25.         <aop:advisor advice-ref="txAdvice"  
  26.             pointcut-ref="interceptorPointCuts" />          
  27.     </aop:config>        
  28. </beans>

第五种方式:全注解

Java代码
  1. <context:annotation-config />  
  2.      <context:component-scan base-package="com.bluesky" />  
  3.   
  4.      <tx:annotation-driven transaction-manager="transactionManager"/>  
  5.   
  6.      <bean id="sessionFactory"    
  7.             class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">    
  8.          <property name="configLocation" value="classpath:hibernate.cfg.xml" />    
  9.          <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />  
  10.      </bean>    
  11.   
  12.      <!-- 定义事务管理器(声明式的事务) -->    
  13.      <bean id="transactionManager"  
  14.         class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  15.          <property name="sessionFactory" ref="sessionFactory" />  
  16.      </bean>  
  17.       
  18. </beans>  

此时在DAO上需加上@Transactional注解,如下:

Java代码
  1. package com.bluesky.spring.dao;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.hibernate.SessionFactory;  
  6. import org.springframework.beans.factory.annotation.Autowired;  
  7. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;  
  8. import org.springframework.stereotype.Component;  
  9.   
  10. import com.bluesky.spring.domain.User;  
  11.   
  12. @Transactional  
  13. @Component("userDao")  
  14. public class UserDaoImpl extends HibernateDaoSupport implements UserDao {  
  15.   
  16.     public List<User> listUsers() {  
  17.         return this.getSession().createQuery("from User").list();  
  18.      }  
  19.       
  20.       
posted @ 2009-09-10 14:22 久久不醉 阅读(148) | 评论 (0)编辑 收藏
 
     摘要: 利用xfire编写webservice的例子,内容如下 1. xfire + spring 发布webservice 2. 利用 javascript  调用发布的webservice 使用xfire+spring发布webservice其实很简单,遵循一下几个步骤即可 1. 想要发布成文webservice的类,必须实现接口 ...  阅读全文
posted @ 2009-09-02 16:38 久久不醉 阅读(3562) | 评论 (3)编辑 收藏
 
xfire+spring 实践记录(一) 
客户端代码: 
1、将服务端的com.sap.jco.ws.WebServiceSAP.java接口copy到本地 
2、新增spring的applicationcontext 
applicationContext-client.xml 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 

<beans  default-lazy-init="true"> 
<bean id="sapWebService" class="org.codehaus.xfire.spring.remoting.XFireClientFactoryBean"> 
<property name="serviceClass"> 
<value>com.sap.jco.ws.WebServiceSAP</value> 
</property> 
<property name="wsdlDocumentUrl"> 
<value>http://127.0.0.1:88/wssap/services/SAPService?WSDL</value> 
</property> 
</bean> 
</beans> 

3、applicationContext.xml中增加 
<import resource="classpath:org/codehaus/xfire/spring/xfire.xml" />   
<import resource="applicationContext-client.xml"/> 

4、调用: 
TestService client=(TestService)ServiceFactory.getBeanByName("testWebService"); 
    Map map=client.add(new HashMap(), 1, 2); 
    System.out.println("map value:"+map.get("p3")); 
可以返回结果
posted @ 2009-09-02 16:38 久久不醉 阅读(545) | 评论 (0)编辑 收藏
 
关键字: oracle的悲观锁和乐观锁
为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突。为了解决这个问题,大多数数据库用的方法就是数据的锁定。 

数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁。什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住。而乐观锁就是认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误的信息,让用户决定如何去做。 

先从悲观锁开始说。在SqlServer等其余很多数据库中,数据的锁定通常采用页级锁的方式,也就是说对一张表内的数据是一种串行化的更新插入机制,在任何时间同一张表只会插1条数据,别的想插入的数据要等到这一条数据插完以后才能依次插入。带来的后果就是性能的降低,在多用户并发访问的时候,当对一张表进行频繁操作时,会发现响应效率很低,数据库经常处于一种假死状态。而Oracle用的是行级锁,只是对想锁定的数据才进行锁定,其余的数据不相干,所以在对Oracle表中并发插数据的时候,基本上不会有任何影响。 

注:对于悲观锁是针对并发的可能性比较大,而一般在我们的应用中用乐观锁足以。 


Oracle的悲观锁需要利用一条现有的连接,分成两种方式,从SQL语句的区别来看,就是一种是for update,一种是for update nowait的形式。比如我们看一个例子。首先建立测试用的数据库表。 

Sql代码 
  1. CREATE TABLE TEST(ID,NAME,LOCATION,VALUE,CONSTRAINT test_pk PRIMARY KEY(ID))AS SELECT deptno, dname, loc, 1 FROM scott.dept  



这里我们利用了Oracle的Sample的scott用户的表,把数据copy到我们的test表中。首先我们看一下for update锁定方式。首先我们执行如下的select for update语句。 

Sql代码 
  1. select * from test where id = 10 for update  


通过这条检索语句锁定以后,再开另外一个sql*plus窗口进行操作,再把上面这条sql语句执行一便,你会发现sqlplus好像死在那里了,好像检索不到数据的样子,但是也不返回任何结果,就属于卡在那里的感觉。这个时候是什么原因呢,就是一开始的第一个Session中的select for update语句把数据锁定住了。由于这里锁定的机制是wait的状态(只要不表示nowait那就是wait),所以第二个Session(也就是卡住的那个sql*plus)中当前这个检索就处于等待状态。当第一个session最后commit或者rollback之后,第二个session中的检索结果就是自动跳出来,并且也把数据锁定住。不过如果你第二个session中你的检索语句如下所示。 

Sql代码 
  1. select * from test where id = 10  



也就是没有for update这种锁定数据的语句的话,就不会造成阻塞了。另外一种情况,就是当数据库数据被锁定的时候,也就是执行刚才for update那条sql以后,我们在另外一个session中执行for update nowait后又是什么样呢。比如如下的sql语句。由于这条语句中是制定采用nowait方式来进行检索,所以当发现数据被别的session锁定中的时候,就会迅速返回ORA-00054错误,内容是资源正忙, 但指定以 NOWAIT 方式获取资源。所以在程序中我们可以采用nowait方式迅速判断当前数据是否被锁定中,如果锁定中的话,就要采取相应的业务措施进行处理。 

Sql代码 
  1. select * from test where id = 10 for update nowait  



那这里另外一个问题,就是当我们锁定住数据的时候,我们对数据进行更新和删除的话会是什么样呢。比如同样,我们让第一个Session锁定住id=10的那条数据,我们在第二个session中执行如下语句。 

Sql代码 
  1. update test set value=2 where id = 10  



这个时候我们发现update语句就好像select for update语句一样也停住卡在这里,当你第一个session放开锁定以后update才能正常运行。当你update运行后,数据又被你update 语句锁定住了,这个时候只要你update后还没有commit,别的session照样不能对数据进行锁定更新等等。 

总之,Oracle中的悲观锁就是利用Oracle的Connection对数据进行锁定。在Oracle中,用这种行级锁带来的性能损失是很小的,只是要注意程序逻辑,不要给你一不小心搞成死锁了就好。而且由于数据的及时锁定,在数据提交时候就不呼出现冲突,可以省去很多恼人的数据冲突处理。缺点就是你必须要始终有一条数据库连接,就是说在整个锁定到最后放开锁的过程中,你的数据库联接要始终保持住。与悲观锁相对的,我们有了乐观锁。乐观锁一开始也说了,就是一开始假设不会造成数据冲突,在最后提交的时候再进行数据冲突检测。在乐观锁中,我们有3种 

常用的做法来实现。 

[1]第一种就是在数据取得的时候把整个数据都copy到应用中,在进行提交的时候比对当前数据库中的数据和开始的时候更新前取得的数据。当发现两个数据一模一样以后,就表示没有冲突可以提交,否则则是并发冲突,需要去用业务逻辑进行解决。 

[2]第二种乐观锁的做法就是采用版本戳,这个在Hibernate中得到了使用。采用版本戳的话,首先需要在你有乐观锁的数据库table上建立一个新的column,比如为number型,当你数据每更新一次的时候,版本数就会往上增加1。比如同样有2个session同样对某条数据进行操作。两者都取到当前的数据的版本号为1,当第一个session进行数据更新后,在提交的时候查看到当前数据的版本还为1,和自己一开始取到的版本相同。就正式提交,然后把版本号增加1,这个时候当前数据的版本为2。当第二个session也更新了数据提交的时候,发现数据库中版本为2,和一开始这个 session取到的版本号不一致,就知道别人更新过此条数据,这个 

时候再进行业务处理,比如整个Transaction都Rollback等等操作。在用版本戳的时候,可以在应用程序侧使用版本戳的验证,也可以在数据库侧采用Trigger(触发器)来进行验证。不过数据库的Trigger的性能开销还是比较的大,所以能在应用侧进行验证的话还是推荐不用 Trigger。 

[3]第三种做法和第二种做法有点类似,就是也新增一个Table的Column,不过这次这个column是采用timestamp型,存储数据最后更新的时间。在Oracle9i以后可以采用新的数据类型,也就是timestamp with time zone类型来做时间戳。这种Timestamp的数据精度在Oracle的时间类型中是最高的,精确到微秒(还没与到纳秒的级别),一般来说,加上数据库处理时间和人的思考动作时间,微秒级别是非常非常够了,其实只要精确到毫秒甚至秒都应该没有什么问题。和刚才的版本戳类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。如果不想把代码写在程序中或者由于别的原因无法把代码写在现有的程序中,也可以把这个时间戳乐观锁逻辑写在Trigger或者存储过程中。

Oracle锁表(网上抄来的)

锁定类型

               行级锁

               表级锁

行级锁

         ---- 行被排他锁定

         ----在某行的锁被释放之前,其他用户不能修改此行

         ----使用 commit 或 rollback 命令释放锁

         ----Oracle 通过使用 INSERT、UPDATE 和 SELECT…FOR UPDATE 语句自动获取行级锁

SELECT…FOR UPDATE 子句

―在表的一行或多行上放置排他锁

―用于防止其他用户更新该行

―可以执行除更新之外的其他操作

―select * from goods where gid=1001

―for update of gname;

―只有该用户提交事务,其他用户才能够更新gname

FOR UPDATE WAIT 子句

―Oracle9i 中的新增功能

―防止无限期地等待锁定的行

―等待间隔必须指定为数值文字

―等待间隔不能是表达式、赋值变量或 PL/SQL

变量

―select * from goods where gid=1001 for update of gname wait 3

―等待用户释放更新锁的时间为3秒,否则超时。

表级锁

―保护表的数据

―在多个用户同时访问数据时确保数据的完整性

―可以设置为三种模式:共享、共享更新和 排他

          语法:lock table<table_name>in<mode>;

共享锁

―锁定表

―仅允许其他用户执行查询操作

―不能插入、更新和删除

―多个用户可以同时在同一表中放置此锁

―lock table table_name

―in share mode [nowait];

― rollback 和commit 命令释放锁

― nowait 关键字告诉其他用户不用等待

共享更新锁

―锁定要被更新的行

―允许其他用户同时查询、插入、更新未被锁定的行

―在 SELECT 语句中使用“FOR UPDATE”子句,可以强制使用共享更新锁

―允许多个用户同时锁定表的不同行

加锁的两种方法

        1        lock table tab_name in share update mode;

        2         select column1,column2

            from goods

            where goods

            where gid=1001

            for update of column1,column2

排他锁

―与其他两种锁相比,排他锁是限制性最强的表锁

―仅允许其他用户查询数据

―不允许执行插入、删除和更新操作

―在同一时间仅允许一位用户在表上放置排他锁

―共享锁与此相反

         lock table tab_name in exclusive mode;

         lock table<表名>[<表名>]...

                   in share mode [nowait]

  

         lock table< 表名>[<表名>]...

         in exclusive mode [nowait]

         lock table<表名>[<表名>]...

         in share update mode[nowait]

posted @ 2009-08-18 09:31 久久不醉 阅读(289) | 评论 (0)编辑 收藏
 
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能。
结构:
HSSF - 提供读写Microsoft Excel格式档案的功能。 
XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。 
HWPF - 提供读写Microsoft Word格式档案的功能。 
HSLF - 提供读写Microsoft PowerPoint格式档案的功能。 
HDGF - 提供读写Microsoft Visio格式档案的功能。
创建Excel 文档
示例1将演示如何利用Jakarta POI API 创建Excel 文档。 
示例1程序如下:
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
import java.io.FileOutputStream;
public class CreateXL {
/** Excel 文件要存放的位置,假定在D盘下*/
public static String outputFile="D:\\test.xls";
public static void main(String argv[]){
try{
// 创建新的Excel 工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
// 在Excel工作簿中建一工作表,其名为缺省值
// 如要新建一名为"效益指标"的工作表,其语句为:
// HSSFSheet sheet = workbook.createSheet("效益指标");
HSSFSheet sheet = workbook.createSheet();
// 在索引0的位置创建行(最顶端的行)
HSSFRow row = sheet.createRow((short)0);
//在索引0的位置创建单元格(左上端)
HSSFCell cell = row.createCell((short) 0);
// 定义单元格为字符串类型
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
// 在单元格中输入一些内容
cell.setCellValue("增加值");
// 新建一输出文件流
FileOutputStream fOut = new FileOutputStream(outputFile);
// 把相应的Excel 工作簿存盘
workbook.write(fOut);
fOut.flush();
// 操作结束,关闭文件
fOut.close();
System.out.println("文件生成...");
}catch(Exception e) {
System.out.println("已运行 xlCreate() : " + e );
}
}
}
读取Excel文档中的数据
示例2将演示如何读取Excel文档中的数据。假定在D盘JTest目录下有一个文件名为test1.xls的Excel文件。
示例2程序如下:
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
import java.io.FileInputStream;
public class ReadXL {
/** Excel文件的存放位置。注意是正斜线*/
public static String fileToBeRead="D:\\test1.xls";
public static void main(String argv[]){ 
try{
// 创建对Excel工作簿文件的引用
HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(fileToBeRead));
// 创建对工作表的引用。
// 本例是按名引用(让我们假定那张表有着缺省名"Sheet1")
HSSFSheet sheet = workbook.getSheet("Sheet1");
// 也可用getSheetAt(int index)按索引引用,
// 在Excel文档中,第一张工作表的缺省索引是0,
// 其语句为:HSSFSheet sheet = workbook.getSheetAt(0);
// 读取左上端单元
HSSFRow row = sheet.getRow(0);
HSSFCell cell = row.getCell((short)0);
// 输出单元内容,cell.getStringCellValue()就是取所在单元的值
System.out.println("左上端单元是: " + cell.getStringCellValue()); 
}catch(Exception e) {
System.out.println("已运行xlRead() : " + e );
}
}
}
设置单元格格式
在这里,我们将只介绍一些和格式设置有关的语句,我们假定workbook就是对一个工作簿的引用。在Java中,第一步要做的就是创建和设置字体和单元格的格式,然后再应用这些格式:
1、创建字体,设置其为红色、粗体:
HSSFFont font = workbook.createFont();
font.setColor(HSSFFont.COLOR_RED);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
2、创建格式
HSSFCellStyle cellStyle= workbook.createCellStyle();
cellStyle.setFont(font);
3、应用格式 
HSSFCell cell = row.createCell((short) 0);
cell.setCellStyle(cellStyle);
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cell.setCellValue("标题 "); 
处理WORD文档
import java.io.*; 
import org.textmining.text.extraction.WordExtractor;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
public class TestPoi { 
public TestPoi() { 

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

FileInputStream in = new FileInputStream ("D:\\a.doc"); 
WordExtractor extractor = new WordExtractor(); 
String str = extractor.extractText(in); 
//System.out.println("the result length is"+str.length()); 
System.out.println(str); 

}

posted @ 2009-08-14 16:06 久久不醉 阅读(172) | 评论 (0)编辑 收藏
 
1. 参数文件(parameter file, *.ora)
两种类型pfile和spfile,推荐使用spfile,pfile是字符型文件可以使用编辑器编辑,spfile是二进制文件,要使用set parameter参数进行修改。 使用set parameter进行参数修改时可以增加注释,指定修改的作用范围(memory,spfile,或者both),其中both是默认值;使用reset parameter修改原来的参数设置,其中sid选项必选。
spfile和pfile可以互相生成,启动数据库时默认使用spfile,要使用pfile需要使用pfile='pfilename'进行指定; spfile保存在服务器,pfile保存在客户端,使用alter system改变的系统配置写入spfile,不写入pfile。

2. 调试文件(trace file, * .trc)
两种类型,一种是对调试应用有关系的文件,比如打开sql调试选项,就会在这些调试文件中增加信息;一种是内核产生错误时产生的调试文件,供orace支持人员使用。
我们使用的调试文件有两个存放位置,对于专属服务器存放在udump文件夹下,具体可见user_dump_dest参数;共享服务器的调试文件一般存放在bdump文件夹下,具体可见background_dump_dest参数。
从v$process, v$session, v$parameter, v$instance做关联查询可以知道目前session的trace文件。
可以设置参数tracefile_identifier为当前session的trace文件增加tag。

3. 数据文件(data file)
oracle支持的四种文件系统:os file system, raw partitions,automatic storage management,clustered file system;
段(segment),oracle中的每个对象都存储在一个segment之中,在创建对象的同时oracle自动创建不同的segment,每个段由一个或者多个簇(extents)组成;
簇(extent),extent是一个文件内逻辑上连续的存储空间,同一个segment内的extent可以属于不同的文件,最大空间为2G;
块(block),块是oracle中最小的存储空间,是实际存储数据对象的地方;extent由block构成;一般取值为2k/4k/8k/16k,在有些条件下也可以使用32k。
表空间(tablespace),由segment构成,一个segment不能跨越表空间。

4. 临时文件(temp files)
临时文件用于存放中间结果,它的显著特征是一般情况下,对数据对象的操作不产生回滚段,除非显式指定回滚要求。

5. 控制文件(control files)
控制文件是个小文件,最大64M;在参数文件中指明控制文件的位置;控制文件指明数据文件和在线重做日志文件的位置;控制文件记录发生过的检查点,数据库名字,创建数据库时的时间戳,归档日志的历史等;
控制文件应该在不同的磁盘上进行备份。

6. 日志文件(log files)
一般用于数据库恢复,也可用于系统崩溃时的例程恢复,分为在线日志(online log file)和归档日志(archived log file).
online redo log:
有两组或者多组在线重做日志,组内的每一个成员互为影射,组之间循环使用.
在线重做日志组间的切换称为log switch,这个时候如果数据库配置不好容易发生服务暂停的情况,因为数据库在切换日志组之前要确认该日志组已经没有脏数据,如果有脏数据就要先写入磁盘中,再进行切换。
oracle在修改数据后,会先写入SGA的对应区域,当commit的时候写入在线日志文件,在check point或者重新启动时由DBWn将修改写入磁盘。
设置online redo log的大小时要考虑:峰值的时候产生的日志规模;修改相同block的用户数量;对数据库恢复是否有时间要求。
archived redo log:
数据库在日志的处理分为两种类型:archivelog mode,在发生log switch时保存原来日志;noarchivelog,不保存原有日志,直接重用。
生产环境中要使用archivelog mode,保证数据不丢失。

7. 口令文件(password file)
可选文件,为远程启动oracle提供验证。

8. DMP文件(exp/imp files)
dmp文件用于oracle的导入导出,它和平台无关;是二进制文件;通过网络传输时要确保以二进制的格式进行传输,否则可能导致文件被转换;导入时向下兼容即新版本的oracle可导入老版本的dmp文件。
posted @ 2009-06-08 16:36 久久不醉 阅读(239) | 评论 (0)编辑 收藏
 
设立封锁机制主要是为了对并发操作进行控制,对干扰进行封锁,保证数据的一致性和准确性。Oracle数据库封锁方式有三种:共享封锁,独占封锁,共享更新封锁 
[b:8f4f63b9bb]封锁类型[/b:8f4f63b9bb] 
Oracle RDBMS的封锁类型可分为如下三类: 

1、内部级封锁 
内部级封锁是用于保护ORACLE内部结构,由系统内部实现,用户不能访问,因此我们不必对此做过多的了解。 

2、DDL级封锁(字典/语法分析封锁) 
DDL级封锁也是由ORACLE RDBMS来控制,它用于保护数据字典和数据定义改变时的一致性和完整性。它是系统在对SQL定义语句作语法分析时自动地加锁,无需用户干予。字典/语法分析封锁共分三类: 
(1)、字典操作锁:用于对字典操作时,锁住数据字典,此封锁是独占的,从而保护任何一个时刻仅能对一个字典操作。 
(2)、字典定义锁:用于防止在进行字典操作时又进行语法分析,这样可以避免在查询字典的同时改动某个表的结构。 
(3)、表定义锁:用于 一个SQL语句正当访问某个表时,防止字典中与该表有关的项目被修改。 

3、DML级封锁 
DML级封锁用于控制并发事务中的数据操纵,保证数据的一致性和完整性,其封锁对象可以是表或行。 
对用户的数据操纵,Oracle可以自动为操纵的数据进行封锁,但如果有操纵授权,则为满足并发操纵的需要另外实施封锁。DML封锁可由一个用户进程以显式的方式加锁,也可通过某些   SQL语句隐含方式实现。 
DML锁有如下三种封锁方式: 
(1)、共享封锁方式(SHARE) 
(2)、独占封锁方式(EXCLUSIVE) 
(3)、共享更新封锁(SHARE UPDATE) 

其中SHARE,EXCLUSIVE用于表封锁,SHARE UPDATE用于行封锁。 
1、共享方式的表封锁 
共享方式的表封锁是对表中的所有数据进行封锁,该锁用于保护查询数据的一致性,防止其它用户对已封锁的表进行更更新。其它用户只能对该表再施加共享方式的锁,而不能再对该表施加独占方式的封锁,共享更新锁可以再施加,但不允许持有共享更新封锁的进程做更新。共享该表的所有用户只能查询表中的数据,但不能更新。共享方式的表封锁只能由用户用SQL语句来设置,基语句格式如下: 
[quote:04b72348bd]LOCK TABLE <表名>[,<表名>]... 
IN SHARE MODE [NOWAIT] 
[/quote:04b72348bd] 
执行该语句,对一个或多个表施加共享方式的表封锁。当指定了选择项NOWAIT,若该封锁暂时不能施加成功,则返回并由用户决定是进行等待,还是先去执行别的语句。 
持有共享锁的事务,在出现如下之一的条件时,便释放其共享锁: 
A、执行COMMIT或ROLLBACK语句。 
B、退出数据库(LOG OFF)。 
C、程序停止运行。 
共享方式表封锁常用于一致性查询过程,即在查询数据期间表中的数据不发生改变。 

2、独占方式表封锁 
独占方式表封锁是用于封锁表中的所有数据,拥有该独占方式表封锁的用户,即可以查询该表,又可以更新该表,其它的用户不能再对该表施加任何封锁(包括共享、独占或共享更新封锁)。其它用户虽然不能更新该表,但可以查询该表。 
独占方式的表封锁可通过如下的SQL语句来显示地获得: 
LOCK TABLE <表名>[,<表名>].... 
IN EXCLUSIVE MODE [NOWAIT] 
独占方式的表封锁也可以在用户执行DML语句INSERT、UPDATE、DELETE时隐含获得。 
拥有独占方式表封锁的事务,在出现如下条件之一时,便释放该封锁: 
(1)、执行COMMIT或ROLLBACK语句。 
(2)、退出数据库(LOG OFF) 
(3)、程序停止运行。 
独占方式封锁通常用于更新数据,当某个更新事务涉及多个表时,可减少发生死锁。 

DML锁有如下三种封锁方式: 
(1)、共享封锁方式(SHARE) 
(2)、独占封锁方式(EXCLUSIVE) 
(3)、共享更新封锁(SHARE UPDATE) 
其中SHARE,EXCLUSIVE用于表封锁,SHARE UPDATE用于行封锁。 

1、共享方式的表封锁 
共享方式的表封锁是对表中的所有数据进行封锁,该锁用于保护查询数据的一致性,防止其它用户对已封锁的表进行更更新。其它用户只能对该表再施加共享方式的锁,而不能再对该表施加独占方式的封锁,共享更新锁可以再施加,但不允许持有共享更新封锁的进程做更新。共享该表的所有用户只能查询表中的数据,但不能更新。共享方式的表封锁只能由用户用SQL语句来设置,基语句格式如下: 
[quote:04b72348bd]LOCK TABLE <表名>[,<表名>]... 
IN SHARE MODE [NOWAIT] 
[/quote:04b72348bd] 
执行该语句,对一个或多个表施加共享方式的表封锁。当指定了选择项NOWAIT,若该封锁暂时不能施加成功,则返回并由用户决定是进行等待,还是先去执行别的语句。 
持有共享锁的事务,在出现如下之一的条件时,便释放其共享锁: 
A、执行COMMIT或ROLLBACK语句。 
B、退出数据库(LOG OFF)。 
C、程序停止运行。 
共享方式表封锁常用于一致性查询过程,即在查询数据期间表中的数据不发生改变。 

2、独占方式表封锁 
独占方式表封锁是用于封锁表中的所有数据,拥有该独占方式表封锁的用户,即可以查询该表,又可以更新该表,其它的用户不能再对该表施加任何封锁(包括共享、独占或共享更新封锁)。其它用户虽然不能更新该表,但可以查询该表。 
独占方式的表封锁可通过如下的SQL语句来显示地获得: 
LOCK TABLE <表名>[,<表名>].... 
IN EXCLUSIVE MODE [NOWAIT] 
独占方式的表封锁也可以在用户执行DML语句INSERT、UPDATE、DELETE时隐含获得。 
拥有独占方式表封锁的事务,在出现如下条件之一时,便释放该封锁: <BR>(1)、执行   COMMIT或ROLLBACK语句。 
(2)、退出数据库(LOG OFF) 
(3)、程序停止运行。 
独占方式封锁通常用于更新数据,当某个更新事务涉及多个表时,可减少发生死锁。 

3、共享更新封锁方式 
共享更新封锁是对一个表的一行或多行进行封锁,因而也称作行级封锁。表级封锁虽然保证了数据的一致性,但却减弱了操作数据的并行性。行级封锁确保在用户取得被更新的行到该行进行更新这段时间内不被其它用户所修改。因而行级锁即可保证数据的一致性又能提高数据操作的迸发性。 
可通过如下的两种方式来获得行级封锁: 
(1)、执行如下的SQL封锁语句,以显示的方式获得: 
LOCK TABLE <表名>[,<表名>].... 
IN SHARE UPDATE MODE [NOWAIT] 
(2)、用如下的SELECT ...FOR UPDATE语句获得: 
SELECT <列名>[,<列名>]... 
FROM <表名> 
WHERE <条件> 
FOR UPDATE OF <列名>[,<列名>].....[NOWAIT] 
一旦用户对某个行施加了行级封锁,则该用户可以查询也可以更新被封锁的数据行,其它用户只能查询但不能更新被封锁的数据行.如果其它用户想更新该表中的数据行,则也必须对该表施加行级锁.即使多个用户对一个表均使用了共享更新,但也不允许两个事务同时对一个表进行更新,真正对表进行更新时,是以独占方式封锁表,一直到提交或复原该事务为止。行锁永远是独占方式锁。 
当出现如下之一的条件,便释放共享更新锁: 
(1)、执行提交(COMMIT)语句; 
(2)、退出数据库(LOG OFF) 
(3)、程序停止运行。 
执行ROLLBACK操作不能释放行锁。 
从上面讲述可见,ORACLE RDBMS的加锁机制,解决了并发事务的相容与互斥问题。相容保证事务的并发性,互斥确保数据的一致性。不同用户锁的相容与互斥关系由下图给出。 

其中最后一行最后一列为其它用户提供在不同行上设置SHARE UPDATE锁。但当用户1在某行上进行更新操作时,用户2只有等待用户1提交事务后,才能更新自己所封锁的行。 

中最后一行最后一列为其它用户提供在不同行上设置SHARE UPDATE锁。但当用户1在某行上进行更新操作时,用户2只有等待用户1提交事务后,才能更新自己所封锁的行。 
死锁 

封锁虽然能够有效的解决并发操作,但是任何资源的独占都会有死锁的危险。例如:有两个事务T1,T2,T1对数据A施加独占封锁,T2对数据B施加了独占封锁。再假设T1要对数据B加锁,由于B已被T2独占封锁,因此T1置于等待状态,等待B被释放;现在若T2也要对A进行封锁,由于A已被T1独占封锁,因此T2也被置于等待状态。这样就形成了两个事务相互等待的状态,而且永远不能结束,此种情况称为死锁。 
在Oracle系统中能自动发现死锁,并选择代价最小的,即完成工作量最少的事务予以撤消,释放该事务所拥有的全部锁,记其它的事务继续工作下去。 
从系统性能上考虑,应该尽可能减少资源竞争,增大吞吐量,因此用户在给并发操作加锁时,应注意以下几点: 
1、对于UPDATE和DELETE操作,应只封锁要做改动的行,在完成修改后立即提交。 
2、当多个事务正利用共享更新的方式进行更新,则不要使用共享封锁,而应采用共享更新封锁,这样其它用户就能使用行级锁,以增加并行性。 
3、尽可能将对一个表的操作的并发事务施加共享更新锁,从而可提高并行性。 
4、在应用负荷较高的期间,不宜对基础数据结构(表、索引、簇和视图)进行修改
posted @ 2009-06-02 16:08 久久不醉 阅读(105) | 评论 (0)编辑 收藏
 
java中从oracle中取数据,转化为String和Double显示:
String------->.11
Double------->1.23456446412E10

decode(substr(to_char(CHARGE_AMOUNT/100),1,1),'.','0'||to_char(CHARGE_AMOUNT/100),to_char(CHARGE_AMOUNT/100)) chargeAmountYuan
posted @ 2009-04-08 12:23 久久不醉 阅读(76) | 评论 (0)编辑 收藏
 
create table test(name varchar2(8), password varchar2(12));
comment on table test is '表备注';
comment on column  test.name is '字段备注';
posted @ 2009-03-31 17:31 久久不醉 阅读(167) | 评论 (0)编辑 收藏
 
Ctrl+1 快速修复(最经典的快捷键,就不用多说了)
Ctrl+D: 删除当前行

Ctrl+Alt+↓ 复制当前行到下一行(复制增加)
Ctrl+Alt+↑ 复制当前行到上一行(复制增加)

Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)
Alt+↑ 当前行和上面一行交互位置(同上)
Alt+← 前一个编辑的页面
Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)

Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性

Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)
Shift+Ctrl+Enter 在当前行插入空行(原理同上条)

Ctrl+Q 定位到最后编辑的地方
Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)
Ctrl+M 最大化当前的Edit或View (再按则反之)
Ctrl+/ 注释当前行,再按则取消注释
Ctrl+O 快速显示 OutLine
Ctrl+T 快速显示当前类的继承结构
Ctrl+W 关闭当前Editer
Ctrl+K 参照选中的Word快速定位到下一个
Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)

Ctrl+/(小键盘) 折叠当前类中的所有代码

Ctrl+×(小键盘) 展开当前类中的所有代码

Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替)

Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)

Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)

Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)

Ctrl+Shift+F4 关闭所有打开的Editer

Ctrl+Shift+X 把当前选中的文本全部变味小写

Ctrl+Shift+Y 把当前选中的文本全部变为小写

Ctrl+Shift+F 格式化当前代码

Ctrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)

下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift开头的了)

Alt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)

Alt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)

Alt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)

Alt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)

Alt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)

Alt+Shift+I 合并变量(可能这样说有点不妥Inline)
Alt+Shift+V 移动函数和变量(不怎么常用)
Alt+Shift+Z 重构的后悔药(Undo)

posted @ 2009-03-31 14:49 久久不醉 阅读(86) | 评论 (0)编辑 收藏
 
 关联的两张表,当数据少的那张要在数据多的那张表字段里,显示为NULL时,就需要使用外连接。

  在讲外连接之前,先举例介绍内连接,也就是一般的相等连接。

  点击下载:理解oracle中的外连接.doc

  select * from a, b where a.id = b.id;

  对于外连接,Oracle中可以使用“(+)”来表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN,下面将配合实例一一介绍。

  1. LEFT OUTER JOIN:左外关联

  SELECT e.last_name, e.department_id, d.department_name

  FROM employees e

  LEFT OUTER JOIN departments d

  ON (e.department_id = d.department_id);

  等价于

  SELECT e.last_name, e.department_id, d.department_name

  FROM employees e, departments d

  WHERE e.department_id=d.department_id(+);

  结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录。

  2. RIGHT OUTER JOIN:右外关联

  SELECT e.last_name, e.department_id, d.department_name

  FROM employees e

  RIGHT OUTER JOIN departments d

  ON (e.department_id = d.department_id);

  等价于

  SELECT e.last_name, e.department_id, d.department_name

  FROM employees e, departments d

  WHERE e.department_id(+)=d.department_id;

  结果为:所有员工及对应部门的记录,包括没有任何员工的部门记录。

  3. FULL OUTER JOIN:全外关联

  SELECT e.last_name, e.department_id, d.department_name

  FROM employees e

  FULL OUTER JOIN departments d

  ON (e.department_id = d.department_id);

  结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录和没有任何员工的部门记录。

posted @ 2009-03-25 17:31 久久不醉 阅读(82) | 评论 (0)编辑 收藏
 

有关oracle 9i中的内连接,左外连接,右外连接问题                     

1. 内连接很简单
select A.*, B.* from A,B where A.id = B.id
select A.*, B.* from A inner join B on A.id = B.id
以上两句是完全等价的

2. 左外连接
select distinct(p.person_id) from t_pbase_info p, t_pcontact_info c where p.person_id = c.person_id(+)
select distinct(p.person_id) from t_pbase_info p left join t_pcontact_info c on p.person_id = c.person_id
以上两句是完全等价的

3. 右外连接
select distinct(p.person_id) from t_pbase_info p, t_pcontact_info c where p.person_id(+) = c.person_id
select distinct(p.person_id) from t_pbase_info p right join t_pcontact_info c on p.person_id = c.person_id
以上两句是完全等价的

也就是说在oracle中+号放在=右边相当于左连接,而+号放在=左边相当于右连接

posted @ 2009-03-24 14:41 久久不醉 阅读(253) | 评论 (0)编辑 收藏
 
 在处理数据时发现一个问题,Oracle对于小于1的小数,小数点前面的0是不显示的。
 
SQL> create table t1_number (num number);
Table created
 
SQL> insert into t1_number values(0.3268);
1 row inserted
 
SQL> insert into t1_number values(0.57965686);
1 row inserted
 
SQL> insert into t1_number values(52345234.5686);
1 row inserted
 
SQL> insert into t1_number values(4.552686);
1 row inserted
 
SQL> commit;
Commit complete
 
SQL> column num format 99999999999.9999999999999
SQL> select * from t1_number;
 
                       NUM
--------------------------
            .3268000000000
            .5796568600000
    52345234.5686000000000
           4.5526860000000
 
 
 
    使用PL/SQL DEV工具查看时是有前面的0的
    通过column num format 000000000000.99999999999设置也可以显示前面的0
 
    但是这些都只是显示的结果,而不是数据库保存结果
 
SQL> column num format 00000000000.9999999999999
SQL> select * from t1_number;
 
                       NUM
--------------------------
 00000000000.3268000000000
 00000000000.5796568600000
 00052345234.5686000000000
 00000000004.5526860000000
 00000000005.2920000000000
 
SQL> select substr(num,1,1) from t1_number;
 
SU
--
.
.
5
4
5
 
    可以看到,无论前面出现多少位,通过substr函数获取的第一位任然是'.'
 
 
    无论怎么转换,只要最终输出结果是数值型的,小数点前的0必然被丢弃,所以只有将数值转换为字符型,大致有两种方法:
 
 
1、直接使用to_char函数
 
    首先实验一下将小数点前和小数点后都加上99999999的格式:
 
SQL> select to_char(num,'999999999.999999999') from t1_number;
 
TO_CHAR(NUM,'9999999
--------------------
          .326800000
          .579656860
  52345234.568600000
         4.552686000
         5.292000000
 
    发现小数点前还是没有0,而小数点后的0多出来了
    再实验一下小数点前和小数点后都加上0000000000格式:
 
SQL> select to_char(num,'00000000000.000000000') from t1_number;
 
TO_CHAR(NUM,'000000000
----------------------
 00000000000.326800000
 00000000000.579656860
 00052345234.568600000
 00000000004.552686000
 00000000005.292000000
 
    发现小数点前是有0了,但是两边的0都多出来了,使用FM来去掉多于的0:
 
SQL> select to_char(num,'fm00000000000.000000000') from t1_number;
 
TO_CHAR(NUM,'FM0000000
----------------------
00000000000.326800000
00000000000.579656860
00052345234.568600000
00000000004.552686000
00000000005.292000000
 
    没有效果,说明FM只能去掉用9表示的格式中产生的0:
 
SQL> select to_char(num,'fm999999999.999999999') from t1_number;
 
TO_CHAR(NUM,'FM99999
--------------------
.3268
.57965686
52345234.5686
4.552686
5.292
 
    但是这样还是没有0,最后发现可以将小数点前的第一位置为0即可(注意9的个数要大于数值的位数):
 
SQL> select to_char(num,'fm999999990.999999999') from t1_number;
 
TO_CHAR(NUM,'FM99999
--------------------
0.3268
0.57965686
52345234.5686
4.552686
5.292
 
    检查一下第一位,没有问题:
 
SQL> select substr(to_char(num,'fm999999990.999999999'),1,1) from t1_number;
 
SU
--
0
0
5
4
5
 
 
2、使用decode函数
 
    既然小于1的小数首位必然是'.',那就判断首位是否为'.',是则在前面加上'0'即可
 
SQL> select decode(substr(num,1,1),'.','0'||num,num) from t1_number
 

DECODE(SUBSTR(NUM,1,1),'.','0'||NUM,NUM)
-----------------------------------------
0.3268
0.57965686
52345234.5686
4.552686
5.292
 
    同样检查一下第一位,没有问题
 
SQL> select substr(decode(substr(num,1,1),'.','0'||num,num),1,1) fro
m t1_number;
 
SU
--
0
0
5
4
5
 
 
    也可以写个函数来判断一下,不过可以用decode直接出来,感觉也没什么必要,暂时就这些吧。
posted @ 2009-03-16 17:06 久久不醉 阅读(1076) | 评论 (0)编辑 收藏
 
declare
  i integer;
begin
  i := 1;
  loop
    insert into trade_operation_check
      (ID, pay_charge, pay_manner, operate_sign)
    values
      (i,4,'SY','N');
    i := i + 1;
    exit when i > 10;
  end loop;
  commit;
end;
posted @ 2009-02-26 20:16 久久不醉 阅读(506) | 评论 (0)编辑 收藏
 

  数据库中 用户a  访问 用户b 中表t_department    

     首先在 库a中建立DBLinks 来链接两个库具体如下:

create database link TESTLINK1
connect to ACSYS//库b的某个用户名
identified by "djzcq"//对应的密码
using 'b';//所在服务器的库命名

      然后建立同义词 具体如下:

CREATE SYNONYM user1.t_dpt_01 FOR acsys.t_department@TESTLINK1;//t_department是库b中的表名

commit;

      最后可以在库a中访问到库b中的表了,具体如下:

select * from t_dpt_01 ;

值得主意的是:只能访问指定的用户所拥有访问权限的表,例如库a的用户user1只能访问库b中用户acsys所拥有权限的表或其它对象。

posted @ 2009-02-17 16:10 久久不醉 阅读(307) | 评论 (0)编辑 收藏
 
object.equals比较的是两个object的引用是否相等。
string用==比较的是引用是否相等。 
string.equals比较的是两个字符串的值是否相等.
posted @ 2009-02-04 11:44 久久不醉 阅读(109) | 评论 (0)编辑 收藏
 
1.首先需要在web.xml中添加tld
<taglib>
  <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
  <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
 </taglib>
 <taglib>
  <taglib-uri>/WEB-INF/gfs.tld</taglib-uri>
  <taglib-location>/WEB-INF/gfs.tld</taglib-location>
 </taglib>

2.其次需要新建gfs.tld

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>hyt</shortname>
<uri>http://jakarta.apache.org/struts/tags-html</uri>

<tag>
<name>optionDict</name>
<tagclass>com.alipay.gfs.web.jsptag.OptionDictValue</tagclass>
<bodycontent>JSP</bodycontent>
<attribute>
 <name>codeId</name>
 <required>true</required>
 <rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
 <name>subcodeId</name>
 <required>false</required>
 <rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
 <name>subsubcodeId</name>
 <required>false</required>
 <rtexprvalue>true</rtexprvalue>
</attribute>
</tag>

<tag>
<name>optionEaccount</name>
<tagclass>com.alipay.gfs.web.jsptag.OptionEaccountValue</tagclass>
<bodycontent>JSP</bodycontent>
</tag>

</taglib>

3.再次新建OptionDictValue

package com.alipay.gfs.web.jsptag;

import java.util.List;
import javax.servlet.jsp.JspException;
import org.apache.struts.taglib.html.Constants;
import org.apache.struts.taglib.html.OptionsCollectionTag;
import org.apache.struts.taglib.html.SelectTag;
import org.apache.struts.util.RequestUtils;
import org.apache.struts.util.ResponseUtils;
import com.alipay.gfs.common.GlobalVar;
import com.alipay.gfs.dao.DictDao;
import com.alipay.gfs.domain.Dict;

public class OptionDictValue extends OptionsCollectionTag {
    protected String codeId = "";
    protected String subcodeId = null;
    protected String subsubcodeId = null;
    
    public String getCodeId() {
  return codeId;
 }
 public void setCodeId(String codeId) {
  this.codeId = codeId;
 }
 public String getSubcodeId() {
  return subcodeId;
 }
 public void setSubcodeId(String subcodeId) {
  this.subcodeId = subcodeId;
 }
 public String getSubsubcodeId() {
  return subsubcodeId;
 }
 public void setSubsubcodeId(String subsubcodeId) {
  this.subsubcodeId = subsubcodeId;
 }
 public int doStartTag() throws JspException {

        // Acquire the select tag we are associated with
        SelectTag selectTag = (SelectTag) pageContext
                .getAttribute(Constants.SELECT_KEY);

        if (selectTag == null) {
            JspException e = new JspException(messages
                    .getMessage("optionsCollectionTag.select"));
            RequestUtils.saveException(pageContext, e);
            throw e;
        }

        DictDao dao = (DictDao)GlobalVar.wac.getBean("dictDao");
        Dict dict = new Dict();
        dict.setCodeId(codeId);
        dict.setSubcodeId(subcodeId);
        dict.setSubsubcodeId(subsubcodeId);
        List lstCode = dao.getCodes(dict);
        StringBuffer sb = new StringBuffer();
        for(int i=0; i<lstCode.size();i++)
        {
         Dict dct = (Dict)lstCode.get(i);
             addOption(sb, dct.getCodeName(), dct.getCodeValue(), selectTag
                     .isMatched(dct.getCodeValue()));
        }
        ResponseUtils.write(pageContext, sb.toString());
        return SKIP_BODY;
    }
}

 4.使用标签
<html:select property="revenueTypeTwo">
        <html:option value="">请选择</html:option>
        <gfs:optionDict codeId="102" subsubcodeId="notnull"></gfs:optionDict>
</html:select>

posted @ 2008-12-31 14:55 久久不醉 阅读(816) | 评论 (0)编辑 收藏
 
其实以前也有写过自定义标签, 但是没有注意到过<rtexprvalue>的用法, 最近这几天又用上自定义标签了, 突然发现<rtexprvalue>的用法是有讲究的.

rtexprvalue的全称是 Run-time Expression Value, 它用于表示是否可以使用JSP表达式.

当在<attribute>标签里指定<rtexprvalue>true</rtexprvalue>时, 表示该自定义标签的某属性的值可以直接指定或者通过动态计算指定,  example as follow:

<sql:query var="result" >
    select * from mytable order by nameid
</sql:query>
<%request.setAttribute("nameid", "2"); %>
<myTag:cupSize cupSize="1" cupSizes="${result}"></myTag:cupSize>
<myTag:cupSize cupSize="${nameid}" cupSizes="${result}"></myTag:cupSize>


当在<attribute>标签里指定<rtexprvalue>false</rtexprvalue>时, 表示该自定义标签的某属性的值只能直接指定,  example as follow:
<myTag:cupSize cupSize="1" cupSizes="${result}"></myTag:cupSize>
posted @ 2008-12-31 14:39 久久不醉 阅读(223) | 评论 (0)编辑 收藏
 

1. 在struts-config.xml里,以插件的形式

xml 代码
  1. < plug-in className="org.springframework.web.struts.ContextLoaderPlugIn" / >  
  2.     < set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" / >  
  3. < / plug-in >   

这种方式如果没有配置contextConfigLocation的值,则会自动加载xx-servlet.xml.

xx的值是和web.xml里的配置org.apache.struts.action.ActionServlet的servlet-name的值一样

如下:xx的值也就是 action,所以会自动加载action-servlet.xml

xml 代码
  1. < servlet >  
  2.     < servlet-name >action< / servlet-name >  
  3.     < servlet-class >org.apache.struts.action.ActionServlet< / servlet-class >  
  4.     < load-on-startup >1< / load-on-startup >  
  5.   < / servlet >  
  6.   < servlet-mapping >  
  7.     < servlet-name >action< / servlet-name >  
  8.     < url-pattern >*.do< / url-pattern >  
  9.   < / servlet-mapping >  

 如果sturts-config.xml里配置了contextConfigLocation的值,那么就不会自动加载xx-servlet.xml了,而只会加载contextConfigLocation所指定的xml.

 2. 第2种方式

在web.xml里配置Listener

xml 代码
  1. <listener>  
  2.         <  listener-class>org.springframework.web.context.ContextLoaderListener<listener-class>  
  3.     <  /  listener>  

 

如果在web.xml里给该Listener指定要加载的xml,如:

xml 代码
  1. <context-param>  
  2.         <param-name>contextConfigLocationparam-name>  
  3.         <param-value>classpath*:spring/*.xmlparam-value>  
  4.     context-param>  

则会去加载相应的xml,而不会去加载/WEB-INF/下的applicationContext.xml。。但是,如果没有指定的话,默认会去/WEB-INF/下加载applicationContext.xml。

 

3. 第三种方式:ContextLoaderServlet

xml 代码
  1. < servlet>    
  2.         < servlet-name>context< / servlet-name>    
  3.         < servlet-class>org.springframework.web.context.ContextLoaderServlet< / servlet-class>    
  4.         < load-on-startup>1< / load-on-startup>    
  5.     < / servlet>  

 

 这种方式和第二种Listener方式一样,唯一的区别就是用Listener方式初始化ApplicationContext,可以和用第一种方式(struts-config.xml里 plugin方式)同时存在,而ContextLoaderServlet则不可以和第一种方式同时存在

总结:

ContextLoaderServlet已经不推荐用了,它只是为了兼容低版本的servlet.jar才用的。

总的来说:Listerner要比Servlet更好一些,而且Listerner监听应用的启动和结束,而Servlet启动要稍微延迟一些。
用以下方法取得ApplicationContext:
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());

posted @ 2008-12-30 11:36 久久不醉 阅读(162) | 评论 (0)编辑 收藏
CALENDER
<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

留言簿

随笔档案(54)

文章分类

搜索

  •  

最新评论


Powered By: 博客园
模板提供沪江博客