与Java相伴的日子
相识,相知,相恋,到相守......我的日子因你的到来而充实,我的日子因你的存在而多姿!
posts - 4,comments - 31,trackbacks - 0
        J2EE 即Java2平台企业版,它提供了基于组件的方式来设计、开发、组装和部署企业应用。J2EE使用多层分布式的应用模型,这个多层通常通过三层或四层来实现:

         1、客户层,运行在客户计算机上的组件。
         2、Web 层,运行在J2EE服务器上的组件。
         3、业务层,同样是运行在J2EE服务器上的组件。
         4、企业信息系统层(EIS),是指运行在EIS服务器上的软件系统。
      
         以上层次一般也指三层应用,因分布在三个不同位置:客户计算机、J2EE服务器及后台的数据库或过去遗留下来的系统。请看图例:                                 

                         

          

                     
         J2EE组件

         J2EE应用程序是由组件构成的。J2EE组件是一个封装了功能的软件单元,能够与相关的一些类和文件一起组成J2EE应用程序。
         1、应用程序客户端和Applet是指运行在客户计算机上的组件。
         2、基于Java Servlet和JSP技术的组件叫Web组件,它们运行在服务器上。
         3、企业JavaBean(EJB)组件叫业务组件,同样运行在服务器上。

      J2EE客户端

         J2EE客户端可以是一个Web组件或者是一个应用程序客户端。
         1、Web客户端  
         包括两部分,首先是那些动态Web页面(HTML、XML等),这些组件运行在Web层;另一个是Web浏览器,由客户机上的浏览器从服务器接收并且解析和显示Web页面。
         2、小应用程序(Applet) 
         需要运行在客户端安装了Java虚拟机的Web浏览器上。
         3、应用程序客户端
         J2EE应用程序客户端运行在客户机上,能提供强大而灵活易用的用户界面,如使用Swing或AWT创建的图形化的用户界面(GUI)。应用程序可直接访问运行在业务层的企业Bean,如果需求允许,也可以打开HTTP连接来建立与运行在Web层上的Servlet之间的通讯。
         4、JavaBean组件架构
         在服务器和客户端两层中也可能包括了基于JavaBean的组件架构,通过JavaBean来实现数据的流动,可以是在应用程序客户或Applet与运行在J2EE服务器上的组件之间,或者是在J2EE服务器和后台数据库之间。(不过JavaBean组件并没有包含在J2EE规范里)
         5、J2EE服务的通讯
         客户层与J2EE服务器上运行的业务层之间的通讯可以是直接的,也可以通过运行在Web层中的Servlet和JSP来实现,在这种情况下,客户端运行在浏览器中。

         Web组件

         J2EE的Web组件可以是Servlet或JSP页面。在应用程序组装过程中,静态HTML页面和Applet也可以一起打包成Web组件,但这并不是J2EE规范所认可的Web组件。

         业务组件

         业务代码是指那些由位于业务层的企业Bean(EJB)执行的逻辑,它们能够解决或满足特定的商业领域的一些需求。有三种不同类型的企业Bean:会话Bean、实体Bean和消息驱动Bean。会话Bean代表客户一次短暂的会话过程,当客户执行完成后,会话Bean以及它所包含的数据也随之消失。实体Bean代表的是持久的数据,即存储在数据库表中的一行记录,即使客户终止或者服务器关闭,在J2EE底层的服务会确保实体Bean的数据被保存下来。

         企业信息系统层

         企业信息系统层处理企业信息系统的软件,包括企业组织结构系统,例如企业资源计划(ERP)、大型的事务处理、数据库系统及其他历史上遗留下来的信息系统。

         J2EE的主要技术
         
         JDBC(Java Database Connectivity): JDBC API 为访问数据库提供一种统一的方式,其接口包括在java.sql和javax.sql两个包中。
         JNDI(Java Name and Directory Interface):Java名称和目录服务,包含在javax.naming 及其子包中。它为应用程序提供标准的目录操作的方法 ,如获得对象的关联属性,根据它们的属性搜寻对象等。使用JNDI,一个J2EE应用程序可以存储和动态获取任何类型的命名Java对象。JNSI分为两种:应用程序编程接口(API)和服务供应商接口(SPI)。
         EJB(Enterprise JavaBean):参见上文。
         RMI(Remote Method Invoke):即远程方法调用,它使用了连续序列的方式在客户端和服务器端传递数据,将面向对象编程模型扩展到了客户机/服务器系统,使开发者可以用本地对象调用的语法进行远程调用。
         JSP(Java Server Pages):Java服务器页,可以在HTML代码中嵌入部分Java代码,这种文件由服务器编译成Servlet并执行,然后将产生的结果作为一个HTML文件传给浏览器。
         Servlet:Java Servlet实质上是一种小型的,与平台无关的Java类,它由容器管理并被编译成平台无关的字节代码,可以动态地加载到一个Web服务器上,并由该Web服务器运行。
         JMS(Java Message Service):Java 消息服务,是用于和企业消息传递系统相互通信的应用程序接口。企业消息传递系统又称为面向消息的中间件(Message Oriented Middle Ware, MOM),它使用松耦合的、非常灵活的方式来集成应用程序,在存储和转发的基础上支持应用程序间数据的异步传递;
每个应用程序都只与作为中介的MOM通信。
         JTA(Java Transaction API):指定事务管理与分布式事务中涉及的其他系统之间的各种高级接口。
         JavaMail:用于存取邮件服务器的API,提供了一套用于邮件服务的抽象类。
         JAXP(Java API for XML Processing):Java XML 处理API,支持使用DOM、SAX和XSLT对XML文档进行处理。
         J2EE Connector Architecture:J2EE工具提供商提供的J2EE连接体系结构,通过它可以建立支持访问企业信息系统的资源适配器。      

        归纳几个概念:

         EJB

         即Enterprise JavaBean,一种组件架构,用于开发和部署面向对象的、分布式的、企业级的应用程序。所开发的应用程序使用EJB架构来实现可扩展性及管理事务和安全。
         EJB包括会话Bean(session bean)、实体Bean(entity bean)和消息驱动Bean(message-driven bean)。其中会话Bean分为无状态会话Bean(stateless session bean)和有状态会话Bean(stateful session bean)。而实体Bean又分为Bean管理实体Bean和容器管理实体Bean。由于这种Bean对应于数据库中的记录,所以数据库记录的任何改变也被同步到组件池中的相关Bean中,这个过程叫做持久性(persistenced),这是实体Bean最重要的一个特征。根据持久性操作方式的不同分为:容器管理持久性(Container-Managed Persistence,CMP)和Bean管理持久性(Bean-Managed Persistence,BMP)。

         容器

         即container,一个实体,它管理着组件的生命周期、安全、部署和运行时服务。每个类型的容器都只提供与相应类型的组件相关的服务,如EJB、Web、JSP、Applet和应用程序客户端。其中,EJB容器和Web容器都运行在J2EE服务器中。

         J2EE

         即Java 2 Platform Enterprise Edition,Java 2 平台企业版。是开发和部署企业应用程序的一种平台或环境。它由一系列服务、应用程序编程接口(API)、提供多层开发的功能性的协议以及基于Web的应用程序组成。

         


 



 

posted @ 2006-04-16 01:28 南一郎 阅读(2759) | 评论 (0)编辑 收藏
     摘要: 以下是我用Swing 组件编写的记事本,功能是模仿微软的,使用了观感,自我觉得界面比Win的记事本更为好看(臭屁一下吧)。除了没有做字体选择之外,其他功能基本都有了吧。 /** **/ /**  *Author: Zhang Zhijian   *Mail: q...  阅读全文
posted @ 2006-04-15 01:06 南一郎 阅读(2873) | 评论 (14)编辑 收藏
     摘要: 我做过的一个项目,需要实现在线实时生成 Excel文件供客户端下载的需求,最初考虑的是先在服务器端生成真实的文件,然后在客户端下载该文件。后来发现这样做不但性能不够好、速度较慢,而且还要占用服务器空间。所以采取了在服务器端生成文件输出流(ServletOutputStream),通过HttpServletResponse对象设置相应的响应头,然后将此输出流传往客户端的方法实现。在实现过程中,用到了...  阅读全文
posted @ 2005-12-30 10:08 南一郎 阅读(10979) | 评论 (16)编辑 收藏

 

        我的一个项目使用了Hibernate3操作Oracle9i数据库,遇到一个很奇怪的问题,即在按某些使用了聚合函数的值的升序排序后,翻页到一定页数(通常是3或5)以后,显示的内容不会变化,即出现不是期望的查询结果.
        刚开始仔细排查,找不出原因.后来通过查Hibernate 包中的Oracle9Dialect及OracleDialect的源码,将Dialect换成 OracleDialect后问题解决.
       但是,问题虽解决了,根源何在呢?为什么Oracle9却要用到OracleDialect(源码注解中说这是兼容Oracle8i)的才能解决问题呢?!
      查看源码,发现两者取得分页查询字符串的方式是有点区别的(在 getlimitString()方法中).

    在Oracle9Dialect中:

   public  String getLimitString(String sql,  boolean  hasOffset)  {
  
  sql 
=  sql.trim();
  
boolean  isForUpdate  =   false ;
  
if  ( sql.toLowerCase().endsWith( "  for update " ) )  {
   sql 
=  sql.substring(  0 , sql.length() - 11  );
   isForUpdate 
=   true ;
  }

  
  StringBuffer pagingSelect 
=   new  StringBuffer( sql.length() + 100  );
  
if  (hasOffset)  {
   pagingSelect.append(
" select * from ( select row_.*, rownum rownum_ from (  " );
  }

  
else   {
   pagingSelect.append(
" select * from (  " );
  }

  pagingSelect.append(sql);
  
if  (hasOffset)  {
   pagingSelect.append(
"  ) row_ where rownum <= ?) where rownum_ > ? " );
  }

  
else   {
   pagingSelect.append(
"  ) where rownum <= ? " );
  }


  
if  (isForUpdate) pagingSelect.append( "  for update " );
  
  
return  pagingSelect.toString();
 }



        在OracleDialect中:

public  String getLimitString(String sql,  boolean  hasOffset)  {

  sql 
=  sql.trim();
  
boolean  isForUpdate  =   false ;
  
if  ( sql.toLowerCase().endsWith( "  for update " ) )  {
   sql 
=  sql.substring(  0 , sql.length() - 11  );
   isForUpdate 
=   true ;
  }

  
  StringBuffer pagingSelect 
=   new  StringBuffer( sql.length() + 100  );
  
if  (hasOffset)  {
   pagingSelect.append(
" select * from ( select row_.*, rownum rownum_ from (  " );
  }

  
else   {
   pagingSelect.append(
" select * from (  " );
  }

  pagingSelect.append(sql);
  
if  (hasOffset)  {
   pagingSelect.append(
"  ) row_ ) where rownum_ <= ? and rownum_ > ? " );
  }

  
else   {
   pagingSelect.append(
"  ) where rownum <= ? " );
  }


  
if  (isForUpdate) pagingSelect.append( "  for update " );
  
  
return  pagingSelect.toString();
 }



        两者的区别主要在于,前者:
row_ where rownum <= ?) where rownum_ > ?
后者:
where rownum_ <= ? and rownum_ > ?

我模拟了我的出问题的查询,使用前者问题重现,使用后者不出问题.
另外是,只在升序排序时才出问题,降序则不会.

我的语句分别如下:
*************************************************************************
第一种:

select   *   from  (

 
select  rownum row_num ,t. *    from (
 
select   Sum (b.disp_Count) ,  Sum (b.click_Count) , 
   
Sum (b.total_Price) ,  Sum (b.return_Cost) , 
   
avg (b.rank)  , b.sta_Date   , b.keyword_Name  , 
   b.union_Name  
   
from  Bid_Report b  
        
where   (b.sta_Date  = ' 20051129 ' )  
          
group   by   b.sta_Date,  b.keyword_Name,  b.union_Name 
          
order   by    Sum (b.click_Count), b.sta_Date 
        ) t  
where  rownum <= 60
  ) 
where  row_num  >   40


(在Hibernate3中,Oracle9Dialect的getLimitString()方法采取类似实现方式)

第二种:

select   *   from  (

 
select  rownum row_num ,t. *    from (
 
select   Sum (b.disp_Count) ,  Sum (b.click_Count) , 
   
Sum (b.total_Price) ,  Sum (b.return_Cost) , 
   
avg (b.rank)  , b.sta_Date   , b.keyword_Name  , 
   b.union_Name  
   
from  Bid_Report b  
        
where   (b.sta_Date  = ' 20051129 ' )  
          
group   by   b.sta_Date,  b.keyword_Name,  b.union_Name 
          
order   by    Sum (b.click_Count), b.sta_Date  
        ) t  
  ) 
where  row_num  <= 60   and  row_num > 40

(在Hibernate3中,OracleDialect的getLimitString()方法采取类似实现方式)

**********************************************************************

现在,问题是:为什么采取后者就可以解决问题了呢?这是不是Oracle9Dialect的一个bug呢?!
哪位高手能给我详析,感激不尽!!!!

posted @ 2005-12-30 09:41 南一郎 阅读(1213) | 评论 (0)编辑 收藏
仅列出标题