N长时间没有来了.......
忙中偷闲,整理点代码。
/**
* 复制单个文件
* @param oldPath String 原文件路径 如:c:/fqf.txt
* @param newPath String 复制后路径 如:f:/fqf.txt
* @return boolean
*/
public void copyFile(String oldPath, String newPath)
{
try {
int bytesum = 0;
int byteread = 0;
File oldfile = new File(oldPath);
if (oldfile.exists()) { //文件存在时
InputStream inStream = new FileInputStream(oldPath); //读入原文件
FileOutputStream fs = new FileOutputStream(newPath);
byte[] buffer = new byte[1444];
int length;
while ( (byteread = inStream.read(buffer)) != -1) {
bytesum += byteread; //字节数 文件大小
System.out.println(bytesum);
fs.write(buffer, 0, byteread);
}
inStream.close();
}
}
catch (Exception e) {
System.out.println("复制单个文件操作出错");
e.printStackTrace();
}
}
//保存文件的方法
public String Savefiles(FormFile file,String path)
{
String fileName= file.getFileName();
String contentType = file.getContentType();
String size = (file.getFileSize() + " bytes");
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream stream = file.getInputStream();
OutputStream bos = new FileOutputStream(path+fileName);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.close();
stream.close();
}
catch (IOException e) {
return e.getMessage();
}
return "1";
}
//生成15位的字符串
public String GenTradeId()
{
String tradeId = "";
RandomStrg.setCharset("a-zA-Z0-9");
RandomStrg.setLength("15");
try
{
RandomStrg.generateRandomObject();
tradeId=RandomStrg.getRandom();
}
catch (Exception e)
{
}
return tradeId;
}
/**
* 删除字符串中的空格,至多只保留一个空格
*
* @String txt:输入需要处理的字符串
* @return String :返回处理后的字符串
*
*/
public String deleteWhitespace(String txt){
if((txt!=null)&&(txt.trim().length()>1)){
}
else{
return "";
}
txt = txt.replaceAll("\n"," ").replaceAll("\t"," ");
String temp="";
try{
int flag =0,num=0;
char c = 'x';
StringBuffer sb = new StringBuffer("");
for(int x=0;x<txt.length();x++){
c = txt.charAt(x);
if((c==' ')&&(flag==0)){
sb.append(c);
flag =1;
}
else if((c!=' ')){
sb.append(c);
flag =0;
}
}
temp = sb.toString().trim();
}
catch(Exception e){
;
}
return temp;
}
SQL语句中,IN、EXISTS、NOT IN、NOT EXISTS的效率较低,尤其是后两种语句,当数据量较大时,更常给人一种死机般的感觉。本文提供一种使用连接的方法代替以上的四种语句,可大副提高SQL语句的运行效率。以NOT
IN为例,当数据量达到一万时,效率可提高20倍,数据量越大,效率提高的幅度也就越大。
本文所举的例子在Oracle 7.0下运行通过,但本文所推荐的方法在各种大型数据库上皆适用。
为了能够更好的说明问题,我们采用示例的方式来说明问题。下面,我们将创建一些数据库表和数据,用于在举例时使用。
下面的语句将创建我们示例中将使用的表,并分别在表1(TAB1)中存入10000条数据,表2(TAB2)中存入5000条数据。
SQL语句如下:
CREATE TABLE TAB1
(
COL1 VARCHAR(20) NOT NULL,
COL2 INTEGER,
PRIMARY KEY(COL1)
);
CREATE TABLE TAB2
(
COL1 VARCHAR(20) NOT NULL,
PRIMARY KEY(COL1)
);
CREATE TABLE TAB3
(
COL1 VARCHAR(20) NOT NULL,
PRIMARY KEY(COL1)
);
CREATE OR REPLACE TRIGGER T_TAB3 BEFORE INSERT ON TAB3 FOR EACH
ROW
DECLARE
NUM1 NUMBER;
BEGIN
NUM1:=1;
LOOP
EXIT WHEN NUM1>10000;
INSERT INTO TAB1 VALUES (NUM1,NUM1);
IF NUM1<=5000 THEN INSERT INTO TAB2 VALUES (NUM1);
END IF;
NUM1:=NUM1+1;
END LOOP;
END;
INSERT INTO TAB3 VALUES('1');
下面,我们将举2个例子来具体说明使用连接替换IN、NOT IN、EXISTS、NOT EXISTS的方法。
读取表1中第2列(COL2)数据的总和,且其第1列数据存在于表2的第1列中。
1. 使用IN的SQL语句:
SELECT SUM(COL2) FROM TAB1 WHERE COL1 IN(SELECT COL1 FROM TAB2)
2. 使用EXISTS的SQL语句:
SELECT SUM(COL2) FROM TAB1 WHERE EXISTS(SELECT * FROM TAB2 WHERE
TAB1.COL1=TAB2.COL1)
3. 使用连接的SQL语句:
SELECT SUM(A.COL2) FROM TAB1 A,TAB2 B
WHERE A.COL1=B.COL1
读取表1中第2列(COL2)数据的总和,且其第1列数据不存在于表2的第1列中。
1. 使用NOT IN的SQL语句:
SELECT SUM(COL2) FROM TAB1 WHERE COL1 NOT IN(SELECT COL1 FROM TAB2)
2. 使用NOT EXISTS的SQL语句:
SELECT SUM(COL2) FROM TAB1 WHERE NOT EXISTS(SELECT * FROM TAB2 WHERE
TAB1.COL1=TAB2.COL1)
3. 使用外连接的SQL语句:
SELECT SUM(A.COL2) FROM TAB1 A,TAB2 B WHERE A.COL1=B.COL1(+) AND
B.COL1 IS NULL
下面介绍IN、NOT IN、EXIST、NOT EXIST在DELETE和UPDATE语句中的效率提高方法。
下面所举的例子在Microsoft SQL Server
7.0下运行通过,但所推荐的方法在各种大型数据库上皆适用。下面,我们将创建一些数据库表和数据,用于举例说明。我们将分别在表A(TA)中存入
10000条数据,表B(TB)中存入5000条数据。
SQL语句如下:
CREATE TABLE TA
(
CA INT
)
CREATE TABLE TB
(
CA INT
)
CREATE TABLE TC
(
CA INT
)
CREATE TRIGGER TRA ON TC
FOR INSERT
AS
DECLARE @MINT INT
BEGIN
SELECT @MINT=1
WHILE (@MINT<=5000)
BEGIN
INSERT INTO TA VALUES(@MINT)
INSERT INTO TB VALUES(@MINT)
SELECT @MINT=@MINT+1
END
WHILE (@MINT<=10000)
BEGIN
INSERT INTO TA VALUES(@MINT)
SELECT @MINT=@MINT+1
END
END
GO
INSERT INTO TC VALUES(1)
GO
删除表A中表A和表B相同的数据
1. 用IN的SQL语句:
DELETE FROM TA WHERE TA.CA IN (SELECT CA FROM TB)
2. 用EXISTS的SQL语句:
DELETE FROM TA WHERE EXISTS (SELECT * FROM TB WHERE TB.CA=TA.CA)
3. 使用连接的SQL语句:
DELETE TA FROM TA,TB WHERE TA.CA=TB.CA
删除表A中表A存在但表B中不存在的数据
1. 使用IN的SQL语句:
DELETE FROM TA WHERE TA.CA NOT IN (SELECT CA FROM TB)
2. 使用EXISTS的SQL语句:
DELETE FROM TA WHERE NOT EXISTS (SELECT CA FROM TB WHERE TB.CA=TA.CA)
3. 使用连接的SQL语句:
DELETE TA FROM TA LEFT OUTER JOIN TB ON TA.CA=TB.CA WHERE TB.CA
IS NULL
更新表A中表A和表B相同的数据
1. 使用IN的SQL语句:
UPDATE TA SET CA=CA+10000 WHERE CA IN (SELECT CA FROM TB)
2. 使用EXISTS的SQL语句:
UPDATE TA SET CA=CA+10000 WHERE EXISTS (SELECT CA FROM TB WHERE
TB.CA=TA.CA)
3. 使用连接的SQL语句:
UPDATE TA SET TA.CA=TA.CA+10000 FROM TA,TB WHERE TA.CA=TB.CA
更新表A中表A存在但表B中不存在的数据
1. 使用IN的SQL语句:
UPDATE TA SET CA=CA+10000 WHERE CA NOT IN (SELECT CA FROM TB)
2. 使用EXISTS的SQL语句:
UPDATE TA SET CA=CA+10000 WHERE NOT EXISTS (SELECT CA FROM TB WHERE
TB.CA=TA.CA)
3. 使用连接的SQL语句:
UPDATE TA SET TA.CA=TA.CA+10000 FROM TA LEFT OUTER JOIN TB ON TA.CA=TB.CA
WHERE TB.CA IS NULL
J2ee(Java 2 Enterprise Edition)是建立在Java 2平台上的企业级应用的解决方案。J2EE技术的基础便是Java 2平台,不但有J2SE平台的所有功能,同时还提供了对EJB,Servlet,JSP,XML等技术的全面支持,其最终目标是成为一个支持企业级应用开发的体系结构,简化企业解决方案的开发,部署和管理等复杂问题。事实上,J2EE已经成为企业级开发的工业标准和首选平台。
J2EE并非一个产品,而是一系列的标准。市场上可以看到很多实现了J2EE的产品,如BEA WebLogic,IBM WebSphere以及开源的JBoss等等。
J2EE,是sun公司提出的一个标准,符合这个标准的产品叫"实现";其中你下载的sun公司的j2ee开发包中就有一个这样的"实现",而
jboss,weblogic,websphere都是j2ee标准的一个"实现"。由于jboss,weblogic,websphere自身带有
j2ee的api,所以可以不使用sun的j2ee实现。
一. J2EE的概念
目前,Java 2平台有3个版本,它们是适用于小型设备和智能卡的Java 2平台Micro版(Java 2 Platform Micro Edition,J2ME)、适用于桌面系统的Java 2平台标准版(Java 2 Platform Standard Edition,J2SE)、适用于创建服务器应用程序和服务的Java2平台企业版(Java 2 Platform Enterprise Edition,J2EE)。
J2EE是一种利用Java 2平台来简化企业解决方案的开发、部署和管理相关的复杂问题的体系结构。J2EE技术的基础就是核心Java平台或Java 2平台的标准版,J2EE不仅巩固了标准版中的许多优点,例如"编写一次、随处运行"的特性、方便存取数据库的JDBC API、CORBA技术以及能够在Internet应用中保护数据的安全模式等等,同时还提供了对 EJB(Enterprise JavaBeans)、Java Servlets API、JSP(Java Server Pages)以及XML技术的全面支持。其最终目的就是成为一个能够使企业开发者大幅缩短投放市场时间的体系结构。
J2EE体系结构提供中间层集成框架用来满足无需太多费用而又需要高可用性、高可靠性以及可扩展性的应用的需求。通过提供统一的开发平台,J2EE降低了开发多层应用的费用和复杂性,同时提供对现有应用程序集成强有力支持,完全支持Enterprise JavaBeans,有良好的向导支持打包和部署应用,添加目录支持,增强了安全机制,提高了性能。
二. J2EE的优势
J2EE为搭建具有可伸缩性、灵活性、易维护性的商务系统提供了良好的机制:
保留现存的IT资产: 由于企业必须适应新的商业需求,利用已有的企业信息系统方面的投资,而不是重新制定全盘方案就变得很重要。这样,一个以渐进的(而不是激进的,全盘否定的)方式建立在已有系统之上的服务器端平台机制是公司所需求的。J2EE架构可
以充分利用用户原有的投资,如一些公司使用的BEA Tuxedo、IBM CICS, IBM Encina,、Inprise
VisiBroker 以及Netscape Application
Server。这之所以成为可能是因为J2EE拥有广泛的业界支持和一些重要的'企业计算'领域供应商的参与。每一个供应商都对现有的客户提供了不用废弃
已有投资,进入可移植的J2EE领域的升级途径。由于基于J2EE平台的产品几乎能够在任何操作系统和硬件配置上运行,现有的操作系统和硬件也能被保留使用。
高效的开发: J2EE允许公司把一些通用的、很繁琐的服务端任务交给中间件供应商去完成。这样开发人员可以集中精力在如何创建商业逻辑上,相应地缩短了开发时间。高级中间件供应商提供以下这些复杂的中间件服务:
状态管理服务 -- 让开发人员写更少的代码,不用关心如何管理状态,这样能够更快地完成程序开发。
持续性服务 -- 让开发人员不用对数据访问逻辑进行编码就能编写应用程序,能生成更轻巧,与数据库无关的应用程序,这种应用程序更易于开发与维护。
分布式共享数据对象CACHE服务 -- 让开发人员编制高性能的系统,极大提高整体部署的伸缩性。
支持异构环境:
J2EE能够开发部署在异构环境中的可移植程序。基于J2EE的应用程序不依赖任何特定操作系统、中间件、硬件。因此设计合理的基于J2EE的程序只需开
发一次就可部署到各种平台。这在典型的异构企业计算环境中是十分关键的。J2EE标准也允许客户订购与J2EE兼容的第三方的现成的组件,把他们部署到异构环境中,节省了由自己制订整个方案所需的费用。
可伸缩性:
企业必须要选择一种服务器端平台,这种平台应能提供极佳的可伸缩性去满足那些在他们系统上进行商业运作的大批新客户。基于J2EE平台的应用程序可被部署
到各种操作系统上。例如可被部署到高端UNIX与大型机系统,这种系统单机可支持64至256个处理器。(这是NT服务器所望尘莫及的)J2EE领域的供
应商提供了更为广泛的负载平衡策略。能消除系统中的瓶颈,允许多台服务器集成部署。这种部署可达数千个处理器,实现可高度伸缩的系统,满足未来商业应用的
需要。
稳定的可用性:
一个服务器端平台必须能全天候运转以满足公司客户、合作伙伴的需要。因为INTERNET是全球化的、无处不在的,即使在夜间按计划停机也可能造成严重损
失。若是意外停机,那会有灾难性后果。J2EE部署到可靠的操作环境中,他们支持长期的可用性。一些J2EE部署在WINDOWS环境中,客户也可选择健
壮性能更好的操作系统如Sun Solaris、IBM OS/390。最健壮的操作系统可达到99.999%的可用性或每年只需5分钟停机时间。这是实时性很强商业系统理想的选择。
三. J2EE 的四层模型
J2EE使用多层的分布式应用模型,应用逻辑按功能划分为组件,各个应用组件根据他们所在的层分布在不同的机器上。事实上,sun设计J2EE的初衷正是为了解决两层模式(client/server)的弊端,在传统模式中,客户端担
当了过多的角色而显得臃肿,在这种模式中,第一次部署的时候比较容易,但难于升级或改进,可伸展性也不理想,而且经常基于某种专有的协议――通常是某种数
据库协议。它使得重用业务逻辑和界面逻辑非常困难。现在J2EE
的多层企业级应用模型将两层化模型中的不同层面切分成许多层。一个多层化应用能够为不同的每种服务提供一个独立的层,以下是 J2EE 典型的四层结构:
运行在客户端机器上的客户层组件
运行在J2EE服务器上的Web层组件
运行在J2EE服务器上的业务逻辑层组件
运行在EIS服务器上的企业信息系统(Enterprise information system)层软件
J2EE应用程序组件
J2EE应用程序是由组件构成的.J2EE组件是具有独立功能的软件单元,它们通过相关的类和文件组装成J2EE应用程序,并与其他组件交互。J2EE说明书中定义了以下的J2EE组件:
应用客户端程序和applets是客户层组件.
Java Servlet和JavaServer Pages(JSP)是web层组件.
Enterprise JavaBeans(EJB)是业务层组件.
客户层组件
J2EE应用程序可以是基于web方式的,也可以是基于传统方式的.
web 层组件J2EE web层组件可以是JSP 页面或Servlets.按照J2EE规范,静态的HTML页面和Applets不算是web层组件。
正如下图所示的客户层那样,web层可能包含某些 JavaBean 对象来处理用户输入,并把
输入发送给运行在业务层上的enterprise bean 来进行处理。
业务层组件
业务层代码的逻辑用来满足银行,零售,金融等特殊商务领域的需要,由运行在业务层上的enterprise bean 进行处理.
下图表明了一个enterprise bean 是如何从客户端程序接收数据,进行处理(如果必要的话), 并发送到EIS
层储存的,这个过程也可以逆向进行。
有三种企业级的bean: 会话(session) beans, 实体(entity) beans, 和 消息驱
动(message-driven) beans. 会话bean 表示与客户端程序的临时交互. 当客户端程序执行完后, 会话bean
和相关数据就会消失. 相反, 实体bean 表示数据库的表中一行永久的记录. 当客户端程序中止或服务器关闭时,
就会有潜在的服务保证实体bean 的数据得以保存.消息驱动 bean 结合了会话bean 和 JMS的消息监听器的特性, 允许一个业务层组件异步接收JMS 消息.
企业信息系统层
企业信息系统层处理企业信息系统软件包括企业基础建设系统例如企业资源计划 (ERP), 大型机事务处理, 数据库系统,和其它的遗留信息系统. 例如,J2EE 应用组件可能为了数据库连接需要访问企业信息系统
我们就J2EE的各种组件、服务和API,进行更加详细的阐述,看看在开发不同类型的企业级应用时,根据各自需求和目标的不同,应当如何灵活使用并组合不同的组件和服务。
· Servlet
Servlet是Java平台上的CGI技术。Servlet在服务器端运行,动态地生成Web页面。与传统的CGI和许多其它类似CGI的技术相比,
Java Servlet具有更高的效率并更容易使用。对于Servlet,重复的请求不会导致同一程序的多次转载,它是依靠线程的方式来支持并发访问的。
· JSP
JSP(Java Server Page)是一种实现普通静态HTML和动态页面输出混合编码的技术。从这一点来看,非常类似Microsoft ASP、PHP等
技术。借助形式上的内容和外观表现的分离,Web页面制作的任务可以比较方便地划分给页面设计人员和程序员,并方便地通过JSP来合成。在运行时态,
JSP将会被首先转换成Servlet,并以Servlet的形态编译运行,因此它的效率和功能与Servlet相比没有差别,一样具有很高的效率。
· EJB
EJB定义了一组可重用的组件:Enterprise Beans。开发人员可以利用这些组件,像搭积木一样建立分布式应用。在装配组件时,所有的Enterprise Beans都需要配置到EJB服务器(一般的Weblogic、WebSphere等J2EE应用服务器都
是EJB服务器)中。EJB服务器作为容器和低层平台的桥梁管理着EJB容器,并向该容器提供访问系统服务的能力。所有的EJB实例都运行在EJB容器
中。EJB容器提供了系统级的服务,控制了EJB的生命周期。EJB容器为它的开发人员代管了诸如安全性、远程连接、生命周期管理及事务管理等技术环节,
简化了商业逻辑的开发。EJB中定义了三种Enterprise Beans:
◆ Session Beans
◆ Entity Beans
◆ Message-driven Beans
· JDBC
JDBC(Java Database Connectivity,Java数据库连接)API是一个标准SQL(Structured Query Language,
结构化查询语言)数据库访问接口,它使数据库开发人员能够用标准Java API编写数据库应用程序。JDBC
API主要用来连接数据库和直接调用SQL命令执行各种SQL语句。利用JDBC
API可以执行一般的SQL语句、动态SQL语句及带IN和OUT参数的存储过程。Java中的JDBC相当与Microsoft平台中的ODBC(Open Database Connectivity)。
· JMS
JMS(Java Message Service,Java消息服务)
是一组Java应用接口,它提供创建、发送、接收、读取消息的服务。JMS
API定义了一组公共的应用程序接口和相应语法,使得Java应用能够和各种消息中间件进行通信,这些消息中间件包括IBM
MQ-Series、Microsoft MSMQ及纯Java的SonicMQ。通过使用JMS
API,开发人员无需掌握不同消息产品的使用方法,也可以使用统一的JMS
API来操纵各种消息中间件。通过使用JMS,能够最大限度地提升消息应用的可移植性。 JMS既支持点对点的消息通信,也支持发布/订阅式的消息通信。
· JNDI
由于J2EE应用程序组件一般分布在不同的机器上,所以需要一种机制以便于组件客户使用者查找和引用组件及资源。在J2EE体系中,使用JNDI
(Java Naming and Directory
Interface)定位各种对象,这些对象包括EJB、数据库驱动、JDBC数据源及消息连接等。JNDI
API为应用程序提供了一个统一的接口来完成标准的目录操作,如通过对象属性来查找和定位该对象。由于JNDI是独立于目录协议的,应用还可以使用
JNDI访问各种特定的目录服务,如LDAP、NDS和DNS等。
· JTA
JTA(Java Transaction
API)提供了J2EE中处理事务的标准接口,它支持事务的开始、回滚和提交。同时在一般的J2EE平台上,总提供一个JTS(Java
Transaction Service)作为标准的事务处理服务,开发人员可以使用JTA来使用JTS。
· JCA
JCA(J2EE Connector Architecture)是J2EE体系架构的一部分,为开发人员提供了一套连接各种企业信息系统(EIS,包括ERP、SCM、CRM等)的体系架构,对于EIS开发商而言,它们只需要开发一套基于JCA的EIS连接适配器,开发人员就能够在任何的J2EE应用服务器中连接并使用它。基于JCA的连接适配器的实现,需要涉及J2EE中的事务管理、安全管理及连接管理等服务组件。
· JMX
JMX(Java Management Extensions)的前身是JMAPI。JMX致力于解决分布式系统管理的问题。JMX是一种应用编程接口、
可扩展对象和方法的集合体,可以跨越各种异构操作系统平台、系统体系结构和网络传输协议,开发无缝集成的面向系统、网络和服务的管理应用。JMX是一个完
整的网络管理应用程序开发环境,它同时提供了厂商需要收集的完整的特性清单、可生成资源清单表格、图形化的用户接口;访问SNMP的网络API;主机间远程过程调用;数据库访问方法等。
· JAAS
JAAS(Java Authentication and
Authorization Service)实现了一个Java版本的标准Pluggable Authentication
Module(PAM)的框架。JAAS可用来进行用户身份的鉴定,从而能够可靠并安全地确定谁在执行Java代码。同时JAAS还能通过对用户进行授
权,实现基于用户的访问控制。
· JACC
JACC(Java Authorization Service Provider
Contract for
Containers)在J2EE应用服务器和特定的授权认证服务器之间定义了一个连接的协约,以便将各种授权认证服务器插入到J2EE产品中去。
· JAX-RPC
通过使用JAX-RPC(Java API for XML-based
RPC),已有的Java类或Java应用都能够被重新包装,并以Web
Services的形式发布。JAX-RPC提供了将RPC参数(in/out)编码和解码的API,使开发人员可以方便地使用SOAP消息来完成RPC
调用。同样,对于那些使用EJB(Enterprise
JavaBeans)的商业应用而言,同样可以使用JAX-RPC来包装成Web服务,而这个Web
Servoce的WSDL界面是与原先的EJB的方法是对应一致的。JAX-RPC为用户包装了Web服务的部署和实现,对Web服务的开发人员而言,
SOAP/WSDL变得透明,这有利于加速Web服务的开发周期。
· JAXR
JAXR(Java API for XML
Registries)提供了与多种类型注册服务进行交互的API。JAXR运行客户端访问与JAXR规范相兼容的Web
Servcices,这里的Web Services即为注册服务。一般来说,注册服务总是以Web
Services的形式运行的。JAXR支持三种注册服务类型:JAXR Pluggable Provider、Registry-specific
JAXR Provider、JAXR Bridge Provider(支持UDDI Registry和ebXML
Registry/Repository等)。
· SAAJ
SAAJ(SOAP with Attachemnts API for Java)是JAX-RPC的一个增强,为进行低层次的SOAP消息操纵提供了支持。
四. J2EE 的结构
这种基于组件,具有平台无关性的J2EE 结构使得J2EE 程序的编写十分简单,因为业务逻辑被封装成可复用的组件,并且J2EE 服务器以容器的形式为所有的组件类型提供后台服务. 因为你不用自己开发这种服务, 所以你可以集中精力解决手头的业务问题.
容器和服务
容器设置定制了J2EE服务器所提供得内在支持,包括安全,事务管理,JNDI(Java Naming and Directory Interface)寻址,远程连接等服务,以下列出最重要的几种服务:
J2EE安全(Security)模型可以让你配置 web
组件或enterprise bean ,这样只有被授权的用户才能访问系统资源.
每一客户属于一个特别的角色,而每个角色只允许激活特定的方法。你应在enterprise
bean的布置描述中声明角色和可被激活的方法。由于这种声明性的方法,你不必编写加强安全性的规则。
J2EE 事务管理(Transaction
Management)模型让你指定组成一个事务中所有方法间的关系,这样一个事务中的所有方法被当成一个单一的单元.
当客户端激活一个enterprise bean中的方法,容器介入一管理事务。因有容器管理事务,在enterprise
bean中不必对事务的边界进行编码。要求控制分布式事务的代码会非常复杂。你只需在布置描述文件中声明enterprise
bean的事务属性,而不用编写并调试复杂的代码。容器将读此文件并为你处理此enterprise bean的事务。
JNDI 寻址(JNDI Lookup)服务向企业内的多重名字和目录服务提供了一个统一的接口,这样应用程序组件可以访问名字和目录服务.
J2EE远程连接(Remote Client Connectivity)模型管理客户端和enterprise bean间的低层交互. 当一个enterprise bean创建后, 一个客户端可以调用它的方法就象它和客户端位于同一虚拟机上一样.
生存周期管理(Life Cycle
Management)模型管理enterprise bean的创建和移除,一个enterprise
bean在其生存周期中将会历经几种状态。容器创建enterprise
bean,并在可用实例池与活动状态中移动他,而最终将其从容器中移除。即使可以调用enterprisebean的create及remove方法,容
器也将会在后台执行这些任务。
五、企业级应用示例
下面我们通过假设一个企业应用的J2EE实现,来了解各种组件和服务的应用。假设应用对象是计算机产品的生产商/零售商的销售系统,这个销售系统能够通过自己的网站发布产品信息,同时也能将产品目录传送给计算机产品交易市场。销售系统能够在线接受订单(来自自己的Web网站或者来自计算机产品交易市场),并随后转入内部企业管理系统进行相关的后续处理。
参见图1,这个企业应用可以这种方式架构。该企业应用的核心是产品目录管理和产品定购管理这两个业务逻辑,使用EJB加以实现,并部署在EJB容器中。由于产品目录和定购信息都需要持久化,因此使用JDBC连接数据库,并使用JTA来完成数据库存取事务。
图1 J2EE应用示例
然后使用JSP/Servlet来实现应用的Web表现:在线产品目录浏览和在线定购。为了将产品目录发送给特定的交易市场,使用JMS实现异步的基于消
息的产品目录传输。为了使得更多的其它外部交易市场能够集成产品目录和定购业务,需要使用Web
Services技术包装商业逻辑的实现。由于产品定购管理需要由公司内部雇员进行处理,因此需要集成公司内部的用户系统和访问控制服务以方便雇员的使
用,使用JACC集成内部的访问控制服务,使用JNDI集成内部的用户目录,并使用JAAS进行访问控制。由于产品订购事务会触发后续的企业ERP系统的
相关操作(包括仓储、财务、生产等),需要使用JCA连接企业ERP。
最后为了将这个应用纳入到企业整体的系统管理体系中去,使用Application Client架构了一个管理客户端(与其它企业应用管理应用部署在一台机器上),并通过JMX管理这个企业应用。
(
摘自中科永联
高级技术培训中心
)
//数据库中对于时间的查询操作
public static String getDateSql(Date sDate, String dateType) {
String start = sDate.getYear() + 1900 + "-" + (sDate.getMonth() + 1)
+ "-" + sDate.getDate() + " 00:00:00";
String end = sDate.getYear() + 1900 + "-" + (sDate.getMonth() + 1)
+ "-" + sDate.getDate() + " 23:59:59";
String sql = " and " + dateType + " >= TO_DATE('" + start
+ "','YYYY-MM-DD HH24:MI:SS') and " + dateType
+ " <= TO_DATE('" + end
+ "','YYYY-MM-DD HH24:MI:SS') order by " + dateType;
return sql;
}
//Java SWT中对于文本框只能输入数字的限制
/**
* 数字校验
*
* @param text
*/
private void checkNumber(Text text) {
text.addVerifyListener(new VerifyListener() {
public void verifyText(VerifyEvent e) {
e.doit = ("0123456789.".indexOf(e.text) >= 0);
if (e.keyCode == SWT.BS || e.keyCode == SWT.DEL
|| e.keyCode == SWT.HOME || e.keyCode == SWT.END)
e.doit = true;
}
});
}
//对于一些复杂的查询时可以用HashMap来处理
private String getHql(List<Long> respList,List<Long> customerList, Map<String, Object> map){
String hql = " from CrmFeedBack t where 1=1";
Object key, value;
if (respList != null && respList.size() > 0) {
hql += " and t.resp_Idx in (";
for (Long id : respList) {
hql += id + ",".trim();
}
hql += ")";
hql = hql.replace(",)", ")");
}
if (customerList != null && customerList.size() > 0) {
hql += " and t.client_Name in (";
for (Long id : customerList) {
hql += id + ",".trim();
}
hql += ")";
hql = hql.replace(",)", ")");
}
if (map != null && map.size() > 0) {
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
key = entry.getKey();
value = entry.getValue();
if (key.equals("resp_Idx") || key.equals("priority")) {
hql += " and t." + key + "= " + value;
} else {
hql += " and t." + key + " like '%" + value + "%'";
}
}
}
return hql;
}
///////////////
/**
* Creates the initial layout for a page.
*/
public void createInitialLayout(IPageLayout layout) {
String editorArea = layout.getEditorArea();
layout.setEditorAreaVisible(false);
IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
0.2f, editorArea);
left.addView(MyTreeView.ID);
left.addView(NavigationView.ID);
IFolderLayout right = layout.createFolder("right", IPageLayout.RIGHT,
0.8f, editorArea);
right.addView(MyTableView.ID);
addFastViews(layout);
addViewShortcuts(layout);
addPerspectiveShortcuts(layout);
}
//得到系统文件夹的方法
Image image=PlatformUI.getWorkbench().getSharedImages().getImage(
ISharedImages.IMG_OBJ_FOLDER);
private bool IsNumeric(string str)
{
System.Text.RegularExpressions.Regex reg
= new System.Text.RegularExpressions.Regex(@"^[-]?\d+[.]?\d*$");
return reg.IsMatch(str);
}
MarQuee的用法
基本语法
<marquee> ... </marquee>
移动属性的设置 ,这种移动不仅仅局限于文字,也可以应用于图片,表格等等
方向
<direction=#> #=left, right ,up ,down <marquee
direction=left>从右向左移!</marquee>
方式
<bihavior=#> #=scroll, slide, alternate <marquee
behavior=scroll>一圈一圈绕着走!</marquee>
<marquee behavior=slide>只走一次就歇了!</marquee>
<marquee behavior=alternate>来回走</marquee>
循环
<loop=#> #=次数;若未指定则循环不止(infinite) <marquee loop=3 width=50%
behavior=scroll>只走 3 趟</marquee> <P>
<marquee loop=3 width=50% behavior=slide>只走 3 趟</marquee>
<marquee loop=3 width=50% behavior=alternate>只走 3 趟!</marquee>
速度
<scrollamount=#> <marquee scrollamount=20>啦啦啦,我走得好快哟!</marquee>
延时
<scrolldelay=#> <marquee scrolldelay=500
scrollamount=100>啦啦啦,我走一步,停一停!</marquee>
外观(Layout)设置
对齐方式(Align)
<align=#> #=top, middle, bottom <font size=6>
<marquee align=# width=400>啦啦啦,我会移动耶!</marquee>
</font>
底色
<bgcolor=#> #=rrggbb 16 进制数码,或者是下列预定义色彩:
Black, Olive, Teal, Red, Blue, Maroon, Navy, Gray, Lime,
Fuchsia, White, Green, Purple, Silver, Yellow, Aqua <marquee
bgcolor=aaaaee>颜色!</marquee>
面积
<height=# width=#> <marquee height=40 width=50%
bgcolor=aaeeaa>面积!</marquee>
空白
(Margins)<hspace=# vspace=#>
<marquee hspace=20 vspace=20 width=150 bgcolor=ffaaaa
align=middle>面积!</marquee>
public void dndBuilder() {
Transfer[] type = new Transfer[] { TextTransfer.getInstance() };
int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK
| DND.DROP_NONE;
final DragSource source = new DragSource(tree, operations);
source.setTransfer(type);
final TreeItem[] dragSourceItem = new TreeItem[1];
source.addDragListener(new DragSourceListener() {
public void dragStart(DragSourceEvent event) {
TreeItem[] selection = tree.getSelection();
if (selection.length > 0) {
event.doit = true;
dragSourceItem[0] = selection[0];
} else {
event.doit = false;
}
};
public void dragSetData(DragSourceEvent event) {
event.data = dragSourceItem[0].getText();
}
public void dragFinished(DragSourceEvent event) {
if (event.detail == DND.DROP_MOVE) {
dragSourceItem[0].dispose();
dragSourceItem[0] = null;
}
}
});
DropTarget target = new DropTarget(tree, operations);
target.setTransfer(type);
target.addDropListener(new DropTargetAdapter() {
private TreeItem initTreeItem(TreeItem sitem, TreeItem ditem) {
ditem.setText(sitem.getText());
ditem.setData(sitem.getData());
for (int i = 0; i < sitem.getItemCount(); i++) {
TreeItem subitem = new TreeItem(ditem, SWT.NONE);
try {
subitem = initTreeItem(sitem.getItem(i), subitem);
} catch (Exception e) {
// e.printStackTrace();
}
}
return ditem;
}
private boolean checkValidate(TreeItem sitem, TreeItem ditem) {
if (ditem.equals(sitem))
return false;
TreeItem titem = ditem.getParentItem();
while (titem != null) {
if (sitem.equals(titem))
return false;
titem = titem.getParentItem();
}
return true;
}
public void dragOver(DropTargetEvent event) {
event.feedback = DND.FEEDBACK_NONE | DND.FEEDBACK_SCROLL;
if (event.item != null) {
TreeItem item = (TreeItem) event.item;
if (!checkValidate(dragSourceItem[0], item)) {
event.detail = DND.DROP_NONE;
return;
} else {
event.detail = DND.DROP_MOVE;
}
Point pt = shell.getDisplay().map(null, tree, event.x,
event.y);
Rectangle bounds = item.getBounds();
if (pt.y < bounds.y + bounds.height / 3) {
event.feedback |= DND.FEEDBACK_INSERT_BEFORE;
} else if (pt.y > bounds.y + 2 * bounds.height / 3) {
event.feedback |= DND.FEEDBACK_INSERT_AFTER;
} else {
event.feedback |= DND.FEEDBACK_SELECT;
}
}
}
public void drop(DropTargetEvent event) {
if (event.data == null) {
event.detail = DND.DROP_NONE;
return;
}
if (event.item == null) {
TreeItem item = new TreeItem(tree, SWT.NONE);
item = initTreeItem(dragSourceItem[0], item);
} else {
TreeItem item = (TreeItem) event.item;
Point pt = shell.getDisplay().map(null, tree, event.x,
event.y);
Rectangle bounds = item.getBounds();
TreeItem parent = item.getParentItem();
if (parent != null) {
TreeItem[] items = parent.getItems();
int index = 0;
for (int i = 0; i < items.length; i++) {
if (items[i] == item) {
index = i;
break;
}
}
if (pt.y < bounds.y + bounds.height / 3) {
TreeItem newItem = new TreeItem(parent, SWT.NONE,
index);
newItem = initTreeItem(dragSourceItem[0], newItem);
} else if (pt.y > bounds.y + 2 * bounds.height / 3) {
TreeItem newItem = new TreeItem(parent, SWT.NONE,
index + 1);
newItem = initTreeItem(dragSourceItem[0], newItem);
} else {
TreeItem newItem = new TreeItem(item, SWT.NONE);
newItem = initTreeItem(dragSourceItem[0], newItem);
}
} else {
TreeItem[] items = tree.getItems();
int index = 0;
for (int i = 0; i < items.length; i++) {
if (items[i] == item) {
index = i;
break;
}
}
if (pt.y < bounds.y + bounds.height / 3) {
TreeItem newItem = new TreeItem(tree, SWT.NONE,
index);
newItem = initTreeItem(dragSourceItem[0], newItem);
} else if (pt.y > bounds.y + 2 * bounds.height / 3) {
TreeItem newItem = new TreeItem(tree, SWT.NONE,
index + 1);
newItem = initTreeItem(dragSourceItem[0], newItem);
} else {
TreeItem newItem = new TreeItem(item, SWT.NONE);
newItem = initTreeItem(dragSourceItem[0], newItem);
}
}
}
tree.redraw();
}
});
}