WADER

java,swt,hibernate,struts,xml,spring,ant,cvs,uml,db,server
随笔 - 15, 文章 - 0, 评论 - 0, 引用 - 0
数据加载中……

2005年11月23日

在LDAP中使用角色(Role)和组(Group)来管理用户

LDAP(轻量级目录服务器)越来越被广泛的使用,特别是在管理海量用户信息和管理身份认证信息的时候,LDAP被国内大多数企业所使用,从中国电信,中国移动,新浪,和许多省市政府部门都使用LDAP来管理用户身份的信息。下面重点介绍在LDAP中管理用户的一些概念和技巧。

LDAP服务器使用树状结构来存储和查找用户的信息。这种树状结构比较适合用户身份信息的存储,因为无论在社会还是在企业中,对人的管理是分层的。从地域上的国家、省市到区域,从企业的大部门到小部门,从总经理到小职员,所有的管理都是分层的。“人类的层次划分是社会活动的自然产物”,忘了这句话是谁说的了,但是我们观察自己的周围环境,树状结构的分层无处不在,这也是LDAP为什么在人员管理上这么流行的原因,也是LDAP最初设计的需求。当然,在这里我们不讨论人类社会活动现象,只讨论LDAP技术问题。

LDAP在存储树状结构的数据比关系型数据库有很大的优势。请试图想想在关系数据库中要实现这种树状的数据,需要费一番功夫,并且要定位层次比较深的节点的数据需要经过复杂的查询和转换。但是LDAP这种树状的结构也有一个重要的缺点,就是很难反映出除了结构层次之外的其他关系(例如在同一个组织之下的管理和被管理的关系),而且当组织结构经常发生变化的情况下,树状结构很难满足这种灵活性的要求。有树状结构特点决定,当一个组织变化的时候,这个组织下的所有节点都需要一一变化。

因此,在LDAP中出现了Group(组)和Role(角色)来动态的管理节点之间的关系。例如,建立一个“管理员”的组或角色,然后可以将不同组织结构下的人员放到“管理员”这个逻辑结构下。那么通过“管理员”这个虚拟的组织结构可以将不同物理组织下的人员动态的组合在一起。例如给“管理员”赋予特殊的权力,使他们能够修改本机构中的人员信息。过了一段时间,如果需要将“管理员”这个逻辑组织取消或者改动,只需要在LDAP的单个节点上操作,而实际“管理员”逻辑结构的成员们,不需要作任何的变化,原来是在哪个物理组织,现在也不用变化。这种Group(组)和Role(角色)的出现是增加了节点之间的关联程度。

Group(组)和Role(角色)的功能基本相同,操作起来也很类似。那么Group(组)和Role(角色)到底有什么区别呢?事实上,由于实现方法不同,Group(组)和Role(角色)在某些操作上体现出不同的性能。

Group(组)的实现机制很简单,每个Group本身就是LDAP的一个实体。这个实体有个member的属性。每次将一个成员添加到这个Group中就会在Member属性中添加一条记录(成员的DN)。如果这个Group有200个成员,那么它的member属性中会有200条记录。这种实现方式非常适合下面的操作:1. 列举当前Group下的所有成员。2.将一些成员从当前的Group中删除或添加。因为所有的成员都记录在Group实体的属性里;这种实现方式非常不适合下面的操作:查找某个用户所属的所有Group。这个操作可能要去每个Group中查找信息。

Role(角色)的实现机制就比较复杂了。其实每个LDAP实体本身都有一个“nsrole”的属性。如果某个角色赋予这个用户的话,就会在这个用户的“nsrole”(其实是nsroleDN,这个会在以后解释)的属性中添加一个角色的记录。如果当前用户有10个角色(例如,他又是领导,又是员工,又是管理员,又是教授....),那么在这个用户的"nsrole"属性中会有10条记录(Role的DN)。这种实现方式非常适合下面的操作: 列举当前用户拥有的所有的角色,因为在用户的“nsrole”属性中记录了所有的角色。因此给一个用户授权通常使用角色,这是因为从用户信息中就能很快获得当前用户所有的角色,以及相关的权限。

另外还有一些准则来帮助判断在设计时到底使用Group还是Role。

1 使用Group会很容易将用户从一系列“逻辑组织”中删除或添加。只要是Group的创建者,就有权限修改Group中的member属性。而角色(Role)的信息存在每个用户的“nsroleDN”中,需要特定的权限才能修改这个属性。

2 如果要使用分布式部署(例如使用Chaining的方式),要考虑到角色(Role)是无法跨越服务器的界限

3 如果成员数量巨大(超过20000)个,可以使用动态组的概念(FilterGroup),这个以后再将。

posted @ 2007-09-24 11:32 wader 阅读(5641) | 评论 (0)编辑 收藏

Lucene in Action(中文版)

     摘要: Lucene in Action 中文版  第一部分 Lucene核心 1.      接触Lucene  2.      索引 3.      为程序添加搜索 4.    ...  阅读全文

posted @ 2007-09-09 11:45 wader 阅读(1893) | 评论 (0)编辑 收藏

UI项目的团队组合(来自微软的借鉴)

UI项目的团队组合(来自微软的借鉴)


2006.06.11    

来源:ChinaUI

UI设计人员是对产品的使用界面进行设计和订正的人员。 Usability Engineer是检验UI设计的合理性的人员。

在很多团队,真正的界面设计都是由PM做完了Spec,才找UI设计人员来征求意见。像我们团队,我的设计规范书写完后,我才找UI设计人员来,他们所做的也就不过是对我的设计作小改动,如那些英语词句用得不妥,哪里的按钮该改变大小,等等。我所知道的其它视窗操作系统的团队,也是差不多。这主要是因为我们能自己进行界面设计——视窗操作系统部门的PM是微软PM中最厉害的。可是,这是不太正确的方法,因为如果你有很强的PM,你可用这种方法,要是你的 PM的设计能力不强,这样的流程就要出问题。你的项目的成功不应该寄托在几个强有力的PM上,而是要用完善的流程来保证。好的流程应该是,在产品开发的早期,在做设计时,PM就应该和UI设计人员一起来考虑产品设计的合理性。

这个问题在微软内部我们自己也有很大的争论。 UI设计人员就常常抱怨,在产品开发的早期,他们常常不被看重,被抛在一边。UI设计的领导人甚至在全公司的培训大会上讲,我们的这个文化有问题,领导对 UI设计人员在产品开发早期能起的作用不够重视。可是这个争论已有几年了,结果仍无改变。我想这主要还是跟我们这个行业的产品开发的特性有关系。因为软件开发是很技术性的,常常在早期的技术讨论中,UI设计人员对技术讨论说不出个所以然来(因为他们大多是学艺术设计的),渐渐地各开发团队对UI设计人员的作用就看轻了。在使用界面因素占很大比例的产品团队,像 Office 和 MSN ,这种情况要好一些。

Usability Engineer 所做的事和UI设计人员不同。他们是将UI设计的模型版,找客户来进行实用和使用性能的检验调查和测试,并根据调查结果对UI设计提出进行修改的意见。也就是说,他们的工作是检验UI设计的合理性,有点像测试人员对程序进行检验的功能。可以说,Usability Engineer 和UI设计人员的关系像测试人员与开发编程人员的关系。

User Education team 是编写使用说明书的编辑人员。

从大方面的来说,微软的产品组是公司的几大部门之一,其他还有市场/销售部门,服务部门,运作部门,还有研究院什么的。

合理的开发团队组合应该是什么? 允许我抛砖引玉,先谈一下微软的经验:

项目经理团队:(Program Management Team)
• 设计项目经理(Feature Design PM):负责具体的产品设计,写Design Spec,PM 队伍中,80%的PM是做这个。
• 发行项目经理 (Release PM):负责整个项目的流程和进度管理,制定进度表等,协调整个团队的工作。大的PM 队伍中有一人专门做这个。这是整个项目的领头人。大型的项目的成功与否,常常靠得力的发行经理的领导。
• 协助项目经理(Supporting PM):负责其它产品发行需要照顾到的事情,如客户交流、和市场开发人员交流、负责beta program(初版试行)等等。大的PM 队伍中少不了这样的人。20%的PM是做这个。

开发团队:(Development Team)
• 开发团队领导(Development Manager): 负责管理各个开发小组,并对开发编程的工作做总体的规划。
• 开发组长(Development Lead): 负责管理开发工程师,也参加对开发编程的工作做总体的规划。
• 开发工程师(Develop Engineer,or Developer):负责具体的编程开发。
• 构架师(Architect): 大的产品团队有一两个资深工程师专门做整体系统的设计规划。

测试团队:(Quality Assurance or Test Team)
• 测试团队领导(QA Manager): 负责管理测试小组。
• 测试组长(Test Lead): 负责管理测试工程师,制定测试计划等。
• 测试工程师(Tester or Test Engineer):负责具体的测试工作。
• 测试开发工程师(Developer in Test,or STED): 负责测试工具的开发。

产品可用性团队:(Usability Team)
• 产品可用性工程师(Usability Engineer): 做使用性能的调查和测试,采访客户或将客户邀请来做调查。
• 界面设计师(UI Designer): 负责具体的界面设计。
• 产品设计师 (Product Designer): 负责产品的总体设计,特别是硬件产品。

客户教育或文档团队:(User Education,or UE Team)
• 文档组长(UE Lead):负责管理文档小组。
• 文档编辑(UE Editor):负责具体的文档编辑和撰写。

以上只是一个大约的组合模式。不同的团队有各自的侧重点和变化。在很大程度上这些也受到具体的产品的影响。我想我在微软的产品部门的其他同事们会再做补充。希望这些信息能对国内的软件开发公司能有参考价值。我们希望通过这样的交流,我们能为中国软件开发事业的进一步发展尽我们的一点微薄之力。

posted @ 2006-06-12 09:47 wader 阅读(277) | 评论 (0)编辑 收藏

weblogic配置 (posted on 2005-01-13 16:21 )

WEBLOGIC是一个性能卓越的J2EE服务器,在我国的使用者在快速增长。但现在有关它的中文资料基本没有,更没有介绍使用经验方面的。下面是本人在学习使用WEBLOGIC6.0中得到的一些经验,写出来与大家分享。 
一、WEBLOGIC6.0的安装 
WEBLOGIC6.0自带了JDK1.3,所以不用预先安装JDK就可以直接安装它,在WIN2000平台是一个EXE文件,直接运行它即可;在UNIX平台上的安装包是一个*.bin文件,用sh运行它就可以了,最好是加 -i console的控制台选项(如果不加,可能会报CLASSNOFOUND等错误)如下所示: 
sh weblogic60_sol.bin -i console的控制台 
注意: 
1、UNIX系统的TMP目录(环境变量TMPDIR或TMP_DIR所指的路径)应有足够的空间,因为WEBLOGIC6.0安装时先解压文件到系统的TMP目录下,然后再进行安装。如果TMP目录空间不够安装会出错,这时你可以把TMPDIR设到要足够空间的目录下。 
2、如果用普通用户安装出错,可试着用ROOT用户安装。一般是环境变量及权限的问题。 
3、安装软件可到
http://commerce.bea.com/downloads/products.jsp下载,联机文档可到http://edocs.bea.com/wls/docs61/index.html下载。 

二、与ORACLE数据库的连接 
WEBLOGIC6.0通过ORACLE客户端访问ORACLE,所以在WEBLOGIC6.0所在的机器上要正确安装ORACLE客户端才行。WEBLOGIC6.0对ORACLE提供TYPE2的JDBC DRIVER支持,是一些动态连接库(NT 是.DLL,UNIX是.SO)文件,在$WL_HOME\bin下,以OCI开头的几个目录中。具体采用哪个目录下库文件,与ORACLE SERVER端及CLIENT端的版本及ORACLE API的版本有关,可参考WEBLOGIC6.0的联机文档。要把这些库所在的路径加到系统的环境变量中,否则访问数据库时,WEBLOGIC6.0会报以下错误: 
Java.sql.SQLException: System.loadLibrary threw java.lang.UnsatisfiedLinkError 
with the message 'no WEBLOGICoci37 in java.library.path'..... 
在WIN2000中要加到PATH环境变量中,如: 
set PATH= D:\WEBLOGIC6.0\wlserver6.0\bin\oci816_7;c:\ORANT816\bin;%PATH% 
在NIX平台,要到系统的LIBRARY PATH中,如在SUN上,要加到LD_LIBRARY_PATH环境变量中,方法如下: 
export LD_LIBRARY_PATH=/bea/weblogic6.0/oci816_8:$ORACLE_HOME/lib 
在HP平台上,要加到SHLIB_PATH环境变量中,如: 
export SHLIB_PATH=/bea/ weblogic6.0/lib/hpux11/oci816_8:$ORACLE_HOME/lib 

三、在WEBLOGIC6.0中设置资源的访问权限 
WEBLOGIC6.0几乎可以对它所管理的所有资源设置访问控制表,包括EJB、JSP、SERVLET、POOL、JMS、RMI、JNDI、JDBC等等。当用户第一次访问设置了访问控制表的资源时,WEBLOGIC6.0会弹出一个对话框要求输入口令及密码,如果连输3次都不对,会返回以下错误: 
Error 401--Unauthorized xxx 
From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1: 
10.4.2 401 Unauthorized 

对访问权限的设置有两种方式: 
1、 在WEBLOGIC6.O的控制台中设置,把结果保存到fileRealm.properties中,即采用WEBLOGIC6.0的file realm.感觉对DATABASE POOL,EJB等比较好用,对JSP,SERVER及某个目录设置访问控制表比较难。我试了很多次都没成功。它可对WEB用户(通过浏览器访问)和普通用户(通过JAVA客户端等访问)起作用。 
2、在WEB.XML,WEBLOGIC.XML中设置,只能对WEB用户起作用。下面举个例子说明这种方式。 
如:在一个名为OrderWebApp的WEB APPLICATION中,客户的定单文件都放到/orders目录下,只有manager能浏览该目录下的文件。其WEB.XML及WEBLOGIC.XML可设置如下: 

*************************WEB.XML************************* 
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 1.2//EN" "
http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> 
<web-app> 
<security-constraint> 

<web-resource-collection> 
<web-resource-name>SecureOrdersEast</web-resource-name> 
<description>Security constraint for resources in the orders directory</description> 
<url-pattern>/orders/*</url-pattern> 
<http-method>POST</http-method> 
<http-method>GET</http-method> 
</web-resource-collection> 

<auth-constraint> 
<description>constraint for orders</description> 
<role-name>manager</role-name> 
</auth-constraint> 

<user-data-constraint> 
<description>SSL not required</description> 
<transport-guarantee>NONE</transport-guarantee> 
</user-data-constraint> 

</security-constraint> 

<security-role> 
<description>managers</description> 
<role-name>manager</role-name> 
</security-role> 

</web-app> 

说明:<security-constraint>中定义资源的访问控制表。在<web-resource-collection>中定义资源及其存取方式;在<auth-constraint>中定义可访问该资源的角色;在 <user-data-constraint>中定义WEBLOGIC SERVER与CLIENT之间的开始通讯时,是否采用SSL建立连接。?lt;security-role>中定义角色名。

posted @ 2005-11-23 16:34 wader 阅读(488) | 评论 (0)编辑 收藏

weblogic.properties 设置(posted on 2005-01-13 16:16 )

以下的几个服务器可以免费下载或者进行开发:

Blazix (1.5 Megabytes, JSP, Servlets and EJBs)
来自
www.blazix.com/blazix.html

ServletExec (3.8 Megabytes, JSP and Servlets)
来自
www.unifyeware.com/servletExec/

所周知,发布一个由JSP/SERVLET开发的网站,除了需要相应的WEB服务器来响应普通网页的请求外还需要专门的应用服务器来响应动态网页JSP/SERVLET的请求。对于商业用户来说,目前最流行的应用服务器软件要数BEA公司开发的WebLogic,下面介绍的是WebLogic5.1的版本。
先将WebLogic解压到/usr目录下,需要修改WebLogic安装目录下的StartWebLogic.sh脚本文件来来设置你的CLASSPATH和JAVA_HOME,最后也是通过这个脚本文件来启动服务。现在启动的服务还不支持JSP/EJB/Servlet等技术,所以还需要修改WebLogic安装目录下的weblogic.properties文件。下面就详细介绍如何来配置这个文件。
------------------------------------------------------------------------------------------
第98行:
weblogic.system.listenPort=80
设置HTTP端口,默认是7001
第114行:
weblogic.password.system=11111111
设置启动Console的密码,默认密码长度为8位
第139行:
weblogic.system.SSLListenPort=7002
设置SSL端口,默认是7002
第236行:
weblogic.system.minPasswordLen=8
设置最小密码长度,默认为8位
第495行-第508行:
设置你自己的RMI,命令格式如下:
weblogic.system.startupClass.[virtualName]=[fullPackageName]
例如:
weblogic.system.startupClass.hello=examples.rmi.hello.HelloImpl
第524行:
#weblogic.ejb.deploy=
# /usr/WebLogic/myserver/Your_Ejb.jar,
默认情况是不允许使用EJB,如果要使用可以把前面的注释去掉,再设置你的EJB的路径
第539行-第543行:
增加用户列表,命令格式如下:
weblogic.password.[username]=XXX
例如:
weblogic.password.xxx=11111111
第604行:
weblogic.httpd.session.enable=true
允许在服务器端使用session;session在开发电子商务程序时非常有用
第663行-第674行:
663行:#weblogic.jdbc.connectionPool.db2Pool=
664行:# url=jdbc:db2//localhost/database,
665行:# driver=COM.ibm.db2.jdbc.net.DB2Driver,
666行:# loginDelaySecs=1,
667行:# initialCapacity=4,
668行:# maxCapacity=10,
669行:# capacityIncrement=2,
670行:# allowShrinking=true,
671行:# shrinkPeriodMins=15,
672行:# refreshMinutes=10,
673行:# testTable=table,
674行:# props=user=db2admin;password=db2admin
设置你要使用到的JDBC POOL,默认情况是不允许使用,如果要使用JDBC POOL可以将前面的注释去掉,不过首先你的JDBC驱动程序必须是在StartWebLogic.sh的CLASSPATH中已经存在的。其中663行是设置JDBC POOL的名字(如db2Pool);664和665行是注册JDBC驱动程序以及连接的数据库;667行为缺省的连接数;668行为连接池中最大连接数;674行为连接数据库的用户名和密码
第767行:
weblogic.httpd.register.*.shtml=weblogic.servlet.ServerSideIncludeServlet
允许使用SSI,即允许使用.shtml为后缀的扩展名
第790行:
weblogic.httpd.register.servlets=weblogic.servlet.ServletServlet
允许使用Servlet,例如URL:
http://localhost/servlets/foo/hello
则实际路径为:
/home/servlet/foo/hello.class
第814行:
weblogic.httpd.documentRoot=/home/www/
此行为设定WEB页面的发布目录
第831行:
weblogic.httpd.servlet.classpath=/home/servlet
此行用来设置放置Servlet等class文件的目录,当然这个目录还必须在StartWebLogic.sh的CLASSPATH中已经存在的
第861行-第868行:
861行:#weblogic.httpd.register.*.jhtml=
862行:# weblogic.servlet.jhtmlc.PageCompileServlet
863行:#weblogic.httpd.initArgs.*.jhtml=
864行:# pageCheckSeconds=1,
865行:# packagePrefix=examples.jhtml,
866行:# compileCommand=/usr/java/bin/javac,
867行:# workingDir=/home,
868行:# verbose=true
这几行是用来支持JHTML技术的,默认是不能使用JHTML扩展名,如果想使用JHTML,将前面的注释去掉即可。861行后面的*.jhtml用来注册使用扩展名为jhtml的任意文件;866行设置javac的目录
第878行-第884行:
878行:#weblogic.httpd.register.*.jsp=
879行:# weblogic.servlet.JSPServlet
880行:#weblogic.httpd.initArgs.*.jsp=
881行:# pageCheckSeconds=1,
882行:# compileCommand=/usr/java/bin/javac,
883行:# workingDir=/home,
884行:# verbose=true
这几行是用来支持JSP的,默认是不能使用JSP扩展名,如果想使用JSP,将前面的注释去掉即可。878行后面的*.jsp用来注册使用扩展名为jsp的任意文件;882行设置javac的目录;在WebLogic中如果要运行test.jsp文件,是先将这个文件编译成_test.class后在运行的,所以第883行设置的目录就是用来放编译后的.class文件用的


JRun (11 Megabytes, JSP, Servlets and EJBs)
来自
www.jrun.com/

WebLogic(44 Megabytes, JSP, Servlets and EJBs)
来自
www.beasys.com/

WebSphere (105 Megabytes, JSP, Servlets and EJBs)
来自www-4.ibm.com/sofeware/webservers/

以下的几个服务器可以免费下载或者进行开发:

Blazix (1.5 Megabytes, JSP, Servlets and EJBs)
来自
www.blazix.com/blazix.html

ServletExec (3.8 Megabytes, JSP and Servlets)
来自
www.unifyeware.com/servletExec/

JRun (11 Megabytes, JSP, Servlets and EJBs)
来自
www.jrun.com/

WebLogic(44 Megabytes, JSP, Servlets and EJBs)
来自
www.beasys.com/

WebSphere (105 Megabytes, JSP, Servlets and EJBs)
来自www-4.ibm.com/sofeware/webservers/

以下的几个服务器可以免费下载或者进行开发:

Blazix (1.5 Megabytes, JSP, Servlets and EJBs)
来自
www.blazix.com/blazix.html

ServletExec (3.8 Megabytes, JSP and Servlets)
来自
www.unifyeware.com/servletExec/

JRun (11 Megabytes, JSP, Servlets and EJBs)
来自
www.jrun.com/

WebLogic(44 Megabytes, JSP, Servlets and EJBs)
来自
www.beasys.com/

WebSphere (105 Megabytes, JSP, Servlets and EJBs)
来自www-4.ibm.com/sofeware/webservers/

posted @ 2005-11-23 16:32 wader 阅读(1122) | 评论 (0)编辑 收藏

WebLogic 的一些结构和特点 (posted on 2005-01-13 16:13 )

要学习好一套系统首先要了解它的结构,本文详细的介绍 WebLogic 的一些结构和特点:

WebLogic的大部分配置是在 weblogic.properties 里完成的,只要仔细的研究这个文件就可以清楚得知关于 WebLogic 的一些结构和特点,下面就对 weblogic.properties 文件里的一些配置项作一些说明:

weblogic.httpd.documentRoot=public_html/
这就是WebLogic 的WEB 服务器的根目录,即是目录/weblogic/myserver/public_html/

weblogic.password.system=sdfjkdshfds
这个前文已经提到,是设置管理员密码。

weblogic.system.listenPort=7001
这是设置 WebLogic 的 WEB 服务器端口。

weblogic.httpd.servlet.classpath=/weblogic/myserver/servletclasses
设置Servlet存放的路径

关于Servlet

出于安全的目的,在 WebLogic 下运行的 WebLogic 必须在 weblogic.properties 里登记后才能运行,例如上文的提到Servlet http://localhost:7001/helloWorld
它在weblogic.properties 里的登记项是
weblogic.httpd.register.helloWorld=examples.servlets.HelloWorldServlet
实际上,这个 Servlet 的实际路径是
/weblogic/myserver/servletclasses/examples/servlets/HelloWorldServlet.class
对照一下weblogic.properties里的登记项和HelloWorldServlet.class文件的路径,应该不难找出其登记Servlet的规律吧。

在weblogic.properties里有一下几个Servlet的登记项:

weblogic.httpd.register.AdminEvents=admin.AdminEvents
weblogic.httpd.register.AdminClients=admin.AdminClients weblogic.httpd.register.AdminConnections=admin.AdminConnections weblogic.httpd.register.AdminJDBC=admin.AdminJDBC
weblogic.httpd.register.AdminLicense=admin.AdminLicense
weblogic.httpd.register.AdminMain=admin.AdminMain
weblogic.httpd.register.AdminProps=admin.AdminProps
weblogic.httpd.register.AdminRealm=admin.AdminRealm
weblogic.httpd.register.AdminThreads=admin.AdminThreads weblogic.httpd.register.AdminVersion=admin.AdminVersion

这就是管理员管理 WebLogic 用的Servlet,通过URL访问http://localhost:7001/AdminMain,在弹出的身份验证对话框了输入 system 和在 weblogic.password.system= 设置的密码,就可以进入 WebLogic 的Web管理界面进行管理。

posted @ 2005-11-23 16:29 wader 阅读(296) | 评论 (0)编辑 收藏

WebLogic安装 (posted on 2005-01-13 16:07 )

WebLogic 是一套基于JAVA功能强大的电子商务套件,提供了许多功能强大的中间件以方便编程人员编写的JSP、SERVLET 等电子商务应用,可以为企业提供一个完整的商务应用解决方案。对于开发人员 WebLogic 可以在 www.bea.com 免费下载一套完整的 WebLogic,并得到一个限制了 IP 的license,用于学习和开发基于这个套件的代码。而要是需要正式的投入使用的话,那么就必须支付一定的费用获取没限制的license。由于这个套件基于这种发布方式,对于一般网站开发人员可以很轻易地得到 WebLogic 用于学习开发,当然投入使用是另一回事。

我获得的 WebLogic5.10是两个大大的zip文件,一个是WebLogic程序包,一个是资料文档。因为是基于JAVA,虽然在下载时有区分操作系统,但是我得到的那套经过实践发现在WINNT和LINUX都可以运行,下面主要是以LINUX的为例,WINNT的安装方法也差不多。

安装前准备:

在安装前,用户必须获得一套对应于用户的操作系统的JDK(在 www.sun.com 免费下载),安装好后把WebLogic5.10的压缩包解开,建议放在根目录上,这样会省去很多修改设置的麻烦,在linux下可以解在其他目录,然后在根目录再做一个硬连接也可以。

我的安装的文件目录是

/usr/local/jdk1.2/
/usr/local/weblogic/
ln -s / /usr/local/weblogic/

配置weblogic:

启动weblogic需要执行两个脚本文件:

linux:setEnv.sh和startWebLogic.sh

WINNT对应的是:setEnv.cmd和startWebLogic.cmd

1、weblogic.properties

打开/usr/local/weblogic/的 weblogic.properties 文件,找到这一行
weblogic.password.system=
这是设置管理员密码用的,这个设置项不能为空,所以必须设置一个可靠的管理员密码。
例如:weblogic.password.system=sdfjkdshfds

设置运行JSP:

# WEBLOGIC JSP PROPERTIES
# ------------------------------------------------
# Sets up automatic page compilation for JSP. Adjust init args for
# directory locations and uncomment to use.
#weblogic.httpd.register.*.jsp=#weblogic.servlet.JSPServlet
#weblogic.httpd.initArgs.*.jsp=#pageCheckSeconds=1,#compileCommand=c:/jdk1.2.1/bin/javac.exe, #workingDir=/weblogic/myserver/classfiles, #verbose=true


把那些注释删去,即改为


# WEBLOGIC JSP PROPERTIES
# ------------------------------------------------
# Sets up automatic page compilation for JSP. Adjust init args for
# directory locations and uncomment to use.
weblogic.httpd.register.*.jsp=weblogic.servlet.JSPServlet
weblogic.httpd.initArgs.*.jsp=pageCheckSeconds=1,compileCommand=c:/jdk1.2.1/bin/javac.exe, workingDir=/weblogic/myserver/classfiles, verbose=true


要注意的是还要配置好这一行:
compileCommand=/usr/local/jdk1.2/bin/javac, 这是JDK的JAVA编译器的路径。


2、setEnv.sh

打开/weblogic/setEnv.sh,找到这一行
JAVA_HOME=/usr/java
改为
JAVA_HOME=/usr/local/jdk1.2/

3、 startWebLogic.sh

找到一个全是大写的 "LINUX" 字符串,改为 "Linux",很奇怪是为何要这样是吗?这是因为启动时,脚本文件调用了uname 指令来得到系统的名字,再与"LINUX" 字符串比较确认是否是linux系统,但是uname 指令来返回的系统的名字是Linux,所以我们要改一下,这应该是这个启动脚本的一个小小的BUG,WINT就不用那么麻烦了。

运行weblogic:

经过简单的配置就试运行了。

在目录/weblogic/下执行

. ./setEnv.sh (大家请留意,我这里有两个 ".",因为我们需要在当前的shell下执行这个脚本 )

./startWebLogic.sh

当看到成功启动 WebLogic 的信息时,说明启动成功了。

服务器简单的测试:

WebLogic 默认的WEB端口为7001,我们可以在打开一个浏览器输入地址
http://localhost:7001/
测试是否能连接得上。

Servlet的测试

如果能连得上得话,那么就可以进行下一步的Servlet的测试,在浏览器输入地址
http://localhost:7001/helloWorld
这个就是WebLogic Servlet的演示(至于怎样安装 Servlet请看下文)

JSP的测试

在目录 /weblogic/myserver/public_html/下建立一个名为test.jsp的文件

test.jsp

<%

Out.print("test JSP");

%>

 

在浏览器输入地址
http://localhost:7001/test.jsp
测试能否看到正确的输出"test JSP"的信息。

posted @ 2005-11-23 16:25 wader 阅读(313) | 评论 (0)编辑 收藏

使用Hibernate的一个完整例子(发表于 2005-1-9 22:31:46 )

使用Hibernate的一个完整例子
配置
1、 下载安装Tomcat,并且下载Hibernate的运行环境(主要包含一些JAR包)。

2、 把要使用的数据库的JDBC驱动程序拷贝到%TOMCAT_HOME%\common\lib目录下。笔者使用的是MYSQL,对应的驱动程序的JAR包为mm.mysql-2.0.4-bin.jar。

3、 在Tomcat的Webapps目录下新建一个Web应用,名字为hibernate。

4、 把Hibernate提供的hibernate2.jar和一些第三方的运行库拷贝到hibernate\WEB\INF\lib目录下。(这些第三方的运行库包含在下载的Hibernate lib目录下)

5、 在%TOMCAT_HOME%\conf\server.xml中Web应用和数据源。在server.xml中加入以下的配置描述。
例程1 配置web应用


<Context path="/hibernate" docBase="hibernate" debug="0" reloadable="true" crossContext="true"> 
<Resource name="jdbc/hibernate" auth="Container" type="javax.sql.DataSource"/> 
<ResourceParams name="jdbc/hibernate"> 
<parameter> 
<name>factory</name> 
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value> 
</parameter>
<parameter> 
<name>driverClassName</name> 
<value>org.gjt.mm.mysql.Driver</value> 
</parameter> 
<parameter> 
<name>url</name> 
<value>jdbc:mysql:///test</value> 
</parameter> 
<parameter> 
<name>username</name> 
<value>root</value> 
</parameter> 
<parameter> 
<name>password</name> 
<value></value> 
</parameter> 
<parameter> 
<name>maxActive</name> 
<value>20</value> 
</parameter>
<parameter> 
<name>maxIdle</name> 
<value>10</value>
</parameter> 
<parameter> 
<name>maxWait</name> 
<value>-1</value> 
</parameter> 
</ResourceParams> 
</Context>

在这里,配置了一个名为hibernate的Web应用,并且配置了一个数据源,数据源的JNDI名称为jdbc/hibernate。您需要根据情况修改数据源的链接属性。

6、 下一步就是书写Hibernate的配置描述符。可以使用XML的配置描述,也可以使用基于属性的配置描述。在这里使用基于XML的配置描述。在hibernate\WEB-INF\classes目录下新建一个hibernate.cfg.xml文件。然后加入例程2所示的内容。



<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"
http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd";>

<hibernate-configuration>
<session-factory>
<property name="connection.datasource">java:comp/env/jdbc/hibernate</property>
<property name="show_sql">false</property>
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>

<!-- Mapping files -->

</session-factory>

</hibernate-configuration>

注意connection.datasource属性必须和server.xml中配置的数据源的属性一样。如果不是使用MYSQL,那么需要更改dialect属性。

到现在,配置基本完成,下面我们来开发一个最简单的应用。

开发持久对象、编写映射描述
我们使用hibernate来封装一个简单的数据表。这个表的名字为Courses,它有两个字段,一个是ID,它是Courses表的主键;另一个是name,表示Courses的名字。在数据库中使用以下的脚本来创建这个表:

create table Courses(CourseId varchar(32) not null, name varchar(32), constraint pk_Courses primary key (CourseId) );

接下来的任务就是为Courses表书写持久对象,如例程3所示。

例程3 Courses的持久对象(Courses.java)


package com.hellking.study.hibernate;

import java.util.Set;

/**
*在hibernate中代表了Course表的类。
*/
public class Course 
{
/**每个属性和表的一个字段对应**/
private String id;
private String name;

/**students表示course中的学生,在后面才会用到,暂时不管**/
private Set students;

/**属性的访问方法**/
public void setId(String string) {
id = string;
}

public String getId() {
return id;
}

public void setName(String name)
{
this.name=name;
}
public String getName()
{
return this.name;
}
public void setStudents(Set stud)
{
this.students=stud;
}
public Set getStudents()
{
return this.students;
}
}

可以看出,在Course类中也包含了两个属性,id和name,它的属性和表Courses的字段是一一对应的,并且类型一致。
书写好了持久对象,接下来的任务就是书写对象、关系映射描述。在hibernate\WEB-INF\classes目录下新建一个Course.hbm.xml描述文件,内容如例程4所示。
例程4 Course.hbm.xml


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN" 
"
http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd";>

<hibernate-mapping>
<class
name="com.hellking.study.hibernate.Course"
table="Courses"
dynamic-update="false"
>

<id
name="id"
column="CourseId"
type="string"
unsaved-value="any"
>
<generator class="assigned"/>
</id>

<property
name="name"
type="string"
update="true"
insert="true"
column="Name"
/> 
</class>
</hibernate-mapping>

在Course.hbm.xml映射文件中,指定了要映射的类和映射的表,并且指定了表的各个字段和Java对象中各个字段的映射关系,比如Course对象中的id属性对应了Courses表的courseId字段。

接下来的任务就是在hibernate.cfg.xml中指定这个映射关系。如下所示:



<session-factory>

<!-- Mapping files --> 
<mapping resource="Course.hbm.xml"/>
</session-factory>

编写业务逻辑
到此,我们已经封装了一个名为Courses的表,并且配置完成。接下来的任务就是在Web应用开发中使用它们,为了演示在Hibernate中对数据库的不同类型的操作,我们开发的Web应用有以下的功能:


增加一个Course;

删除一个Course;

按照Course的名字进行模糊搜索;

查看系统中所有的Course。


虽然我们可以直接在JSP中使用hibernate,但是往往我们不这样,而是把这些业务逻辑封装在JavaBean中,然后在JSP中通过调用JavaBean以访问Hibernate封装的对象。

由于访问通过使用hibernate有一些共性的操作,在这里我们把这些共性的操作封装在一个专门的类中,这样其它的类可以继承它,如例程5所示。

例程5 HibernateBase.java


package com.hellking.study.hibernate;

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
import java.util.*;
import java.io.IOException;
import java.io.PrintWriter;

public abstract class HibernateBase 
{
protected SessionFactory sessionFactory;//会话工厂,用于创建会话
protected Session session;//hibernate会话
protected Transaction transaction; //hiberante事务

public HibernateBase()throws HibernateException
{
this.initHibernate();
}
// 帮助方法
protected void initHibernate()
throws HibernateException {

// 装载配置,构造SessionFactory对象
sessionFactory = new Configuration().configure().buildSessionFactory();
}

/**
*开始一个hibernate事务
*/
protected void beginTransaction()
throws HibernateException {

session = sessionFactory.openSession();
transaction = session.beginTransaction();
}

/**
*结束一个hibernate事务。
*/
protected void endTransaction(boolean commit)
throws HibernateException {

if (commit) {
transaction.commit();
} else {
//如果是只读的操作,不需要commit这个事务。
transaction.rollback();
}
session.close();
}
}

下面编写业务逻辑类,新建一个名为CourseBean的JavaBean,并且CourseBean继承HibernateBase类,代码如例程6所示。

例程6 CourseBean.java


package com.hellking.study.hibernate;

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
import java.util.*;

/**
*和course相关的业务逻辑
*/
public class CourseBean extends HibernateBase
{
public CourseBean()throws HibernateException
{
super();
}
/**
*增加一个Course
*/
public void addCourse(Course st)throws HibernateException
{
beginTransaction();
session.save(st); 
endTransaction(true);
}

/**
*查询系统中所有的Course,返回的是包含有Course持久对象的Iterator。
*/
public Iterator getAllCourses()throws HibernateException
{
String queryString = "select courses from Course as courses";
beginTransaction();
Query query = session.createQuery(queryString);
Iterator it= query.iterate();
return it;
}

/**
*删除给定ID的course
*/
public void deleteCourse(String id)throws HibernateException
{
beginTransaction(); 
Course course=(Course)session.load(Course.class,id); 
session.delete(course);
endTransaction(true);
}

/**
*按course的名字进行模糊查找,返回的是包含有Course持久对象的Iterator。
*/
public Iterator getSomeCourse(String name)throws HibernateException
{
String queryString = "select c from Course as c where c.name like :name" 
beginTransaction();
Query query = session.createQuery(queryString);
query.setString("name", "%"+name+"%");
Iterator it= query.iterate();
return it;

}

在CourseBean封装了4个业务方法,你可以根据情况增加其它的业务方法。在CourseBean中,通过Hibernate来操作潜在的数据库资源。

要保存Course数据到数据库,可以通过:



session.save(Course);

方法来保存,它相当于使用在JDBC中执行以下语句:



Connection con=…
Statement stmt=con.createStatement();
stmt.executeUpdate("insert into courses values('"+course.getId(),+"','"+course.getName()+"')");
con.close();

可以看出,通过使用Hibernate,可以大大减少数据访问的复杂度。

在JSP中调用业务逻辑
添加数据
CourseBean这个业务对象封装了和Hibernate的交互关系,从而使JSP和Hibernate关系的解藕。我们来看测试主页面的部分代码,如例程7所示。

例程7 测试Hibernate开发的应用(course.jsp)


<%@ page import="java.sql.*,java.util.*" errorPage="error.jsp"%> 
<jsp:useBean id="course" class="com.hellking.study.hibernate.Course" scope="page">
<jsp:setProperty name="course" property="*"/>
</jsp:useBean>
<jsp:useBean id="courseBusiness" class="com.hellking.study.hibernate.CourseBean" scope="page"/>
<html><body><center>
<% 
try
{
if(course.getId().equals(null)||course.getId().equals(""));
else courseBusiness.addCourse(course);

%>
成功添加了Course:<br>
name:<%=course.getName()%>
Id:<%=course.getId()%>
<%
}
catch(Exception e)
{

%> 

<hr>
<br>::增加一个course::<br>
<form action="course.jsp" method="get" name="add">
id:<input type=text name="id"><br>
name:<input type=text name="name"><br>
<input type=submit value="submit"><br>
</form>
<hr>
::按名字模糊查找::<br>
<form action="queryCourse.jsp" method="get" name="queryByName">
name:<input type=text name="name"><br>
<input type=submit value="query"><br>
</form>
<hr>
::删除一个Course::<br>
<form action="deleteCourse.jsp" method="get" name="queryByName">
id:<input type=text name="id"><br>
<input type=submit value="delete"><br>
</form>
<hr>
<a href=viewAll.jsp>::查看所有Course::<a>
</body>
</html>

首先通过一个值对象Course(这个类正好是Hibernate使用的持久对象,这里作为值对象来传递数据)接收获得的参数,然后CourseBean的addCourse(Course)方法把数据保存到数据库。可以看出,通过使用Hibernate,把数据从表单中添加到数据库非常简单。

查询
下面来看模糊查找的JSP代码,如例程8所示。
例程8 按名字模糊查找Course


<%@ page import="java.sql.*,java.util.*,com.hellking.study.hibernate.Course" errorPage="error.jsp"%> 
<jsp:useBean id="courseBusiness" class="com.hellking.study.hibernate.CourseBean" scope="page"/>

<% try
{
Iterator it=courseBusiness.getSomeCourse((String)request.getParameter("name"));
while(it.hasNext())
{
Course temp=(Course)it.next();
out.println("<tr><td>"+temp.getId()+"</td>");
out.println("<td>"+temp.getName()+"</td></tr>");
}
}
catch(Exception e)
{
out.println(e.getMessage());
}
%>
….

它实际上调用的是CourseBean的Iterator getSomeCourse(String name)方法。我们来回顾一下这个方法中的代码:



/**
*按course的名字进行模糊查找
*/
public Iterator getSomeCourse(String name)throws HibernateException
{
String queryString = "select c from Course as c where c.name like :name" 
beginTransaction();
Query query = session.createQuery(queryString);
query.setString("name", "%"+name+"%");
Iterator it= query.iterate();
return it;
}

在查询前,首先调用beginTransaction方法启动新的Hibernate事务,然后创建一个Query对象,在创建这个对象时,同时指定查询的语句。

注意,在查询语句:


select c from Course as c where c.name like :name"

中,它虽然和普通的SQL语句相似,但是不同,在数据库中,使用的表的名字是Courses,而在这个查询语句中使用的是Course,它和持久对象的名字一致,也就是说,这个查询的概念是查询持久对象,而不是数据库的记录。

创建了查询对象Query后,需要设置查询的参数,它和在JDBC中PreparedStatement对象中设置参数的方法相似。通过"Iterator it= query.iterate()"语句来执行查询,并且返回一个Iterator对象。在这里使用了Hibernate提供的查询机制,一般的JDBC查询返回的是ResultSet对象,而这里返回的是包含了CourseBean对象的Iterator。

要查询系统中所有的Course,也同样非常简单,可以通过例程9所示的代码实现。

例程9 查询数据库中所有的Course



<jsp:useBean id="courseBusiness" class="com.hellking.study.hibernate.CourseBean" scope="page"/>

<% try
{
Iterator it=courseBusiness.getAllCourses();
while(it.hasNext())
{
Course temp=(Course)it.next();
out.println("<tr><td>"+temp.getId()+"</td>");
out.println("<td>"+temp.getName()+"</td></tr>");
}
}
catch(Exception e)
{
out.println(e.getMessage());
}
%>


实际上调用的是CourseBean的getAllCourses方法,它和getSomeCourse方法机制一样,就不再介绍了。

删除数据
在JSP中,使用以下的代码来执行删除操作。
例程10 删除数据库中Courses表的记录


<jsp:useBean id="courseBusiness" class="com.hellking.study.hibernate.CourseBean" scope="page"/>

删除id为:<%=request.getParameter("id")%>的course::::<br>

<% try
{
courseBusiness.deleteCourse(request.getParameter("id"));
out.println("删除成功");

catch(Exception e)
{
out.println("不存在这个记录");
}
%>

我们来看CourseBean中执行删除操作的具体代码:


/**
*删除给定ID的course
*/
public void deleteCourse(String id)throws HibernateException
{
beginTransaction(); 
Course course=(Course)session.load(Course.class,id); 
session.delete(course);
endTransaction(true);
}

在这个方法中,首先开始一个事务,然后通过session.load(Course.class,id)方法来装载指定ID的持久对象,接下来通过"session.delete(course)"来删除已经装载的course,并且结束Hibernate事务。

总结
下面总结一下使用Hibernate的开发过程:

1、 配置Hibernate(一次即可);
2、 确定数据表;

3、 创建持久对象;

4、 编写对象和数据表的映射描述;

5、 编写和业务逻辑。

实际上,上面的过程和使用EJB没有什么区别:在使用EJB时,首先当然也是配置环境,初始化数据表;然后创建实体Bean(对象于Hibernate的持久对象);接下来编写部署描述符(ejb-jar.xml,厂商专有的部署描述),在这些部署描述符里,指定了EJB和数据表的映射关系,如果多个实体Bean存在关联关系,需要描述它们之间的关系,这些描述对应于Hibernate中持久对象的描述,如Course.hbm.xml;往往我们并不在应用程序中直接操作实体Bean,而是通过业务对象(如会话Bean)来操作,这里的会话Bean可以简单的和Hibernate中执行业务逻辑的JavaBean对应。这里只是简单的类比,不是绝对的,比如我们同样可以在会话Bean中访问Hibernate持久对象,也就是说使用Hibernate,同样可以把业务逻辑放在会话Bean中。

通过本文的学习,相信读者对Hibernate已经有了初步的认识,并且能够使用Hibernate开发简单的应用。在下一篇中,我们将学习怎么使用Hibernate来为复杂的数据表进行映射,并且维护它们之间的关系。


参考资料

http://www.apache.org 下载Tomcat。
Hibernate的官方网站,
http://hibernate.bluemars.net/ ,包含了Hibernate最新资料。

Hibernate中文论坛,hibernate.fankai.com包含了Hibernate较多的参考资料。

包含了Hibernate技术讨论网站,www.jdon.com,

于Hibernate、JDO、CMP等技术的热烈讨论1:
http://www.jdon.com/jive/thread.jsp?forum=16&thread=6062&start=0&msRange=15

于Hibernate、JDO、CMP等技术的热烈讨论2:
http://www.theserverside.com/discussion/thread.jsp?thread_id=19732

Hibernate2 Reference document.tion,可以从Hibernate官方网站获得,非常好的参考资料。

Hibernate In Action,一本非常专业的Hibernate参考书,由Hibernate项目主要开发人员Gavin King 等著,Manning出版社出版。您可以从 
http://www.theserverside.com 获得本书的部分章节。

posted @ 2005-11-23 16:24 wader 阅读(398) | 评论 (0)编辑 收藏

Hibernate查询语言:HQL(API文档)(2005-05-12 11:38 )

Hibernate查询语言:HQL


    HQL:Hibernate Qusery Language,如果你已经熟悉它,就会发现它跟SQL非常相像。不过 你不要被表面的假象迷惑,HQL是面向对象的(OO,用生命的眼光看待每一个对象,他们是如此 鲜活)。如果你对JAVA和SQL语句有一定了解的话,那么HQL对你简直易如反掌,你完全可以利用在公车上的时间掌握它。
   
         以下从几个方面进行慢慢深入:
        
        
1。大小些敏感
         大家知道Query是对大小写不敏感的,但是在HQL(前面提到它是OO的)中那么对象类的名称和属性确实大小写敏感的(符合java编程语法)。
       如:sElect cat.name from Cat as cat和select cat.name from Cat as cat是一样的
       但是:
           sElect cat.name from CAT as cat和select cat.name from Cat as cat确实不一样的。
          
      
2。from语句
       最简单的:
        from eg.Cat
        它只是简单的返回所有eg.Cat的实例
        通常我们此时会为eg.Cat其个别名,因为在query的其余部分可能会用到(参看上边关于大小写
        敏感时的例子情形),如:
        from eg.Cat as cat 这里as可以省略。
        上边只是单表查询,多表的情况如下写法:
        from eg.Cat,eg.Dog
        from eg.Cat as cat,eg.Dog as dog
       
       
3。join相关
        (inner) join
        left (outer) join
        right (outer) join
        full join
        HQL同样对SQL中的这些特性支持
         下面插播一个小话题,关于上边的那些特性,我一直都没怎么用,今天既然说到这里,就想
        把上边的几个特性的用法说一下,也算对自己的一个补充:
         假设有两个表:部门、员工,下面列举一些数据:
         员工(Employee):
         ID      Name    DepNo
         001     Jplateau  01
         002     Jony      01
         003     Camel    02
         部门(Department):
         ID      Name
         01     研发部
         02     营销部
         
         在Hibernate中我们操纵的都是对象,所以我们操纵的是部门类和员工类
         1).(inner) join
         select employee.ID as id1,employee.Name as name1,department.ID as id2,department.Name
          as name2 from Employee as employee join Department as department on employee.DepNo=
          department.ID  (注意到条件语句我用on 没有用where)
         那么执行结果是什么呢?
         id1 name1 id2 name2
         ++++++++++++++++++++++++++++++++++++++
         001 Jplateau 01 研发部
         002 Jony     01 研发部
         
         2).left (outer) join
         select employee.ID as id1,employee.Name as name1,department.ID as id2,department.Name
          as name2 from Employee as employee left join Department as department on employee.DepNo=
          department.ID
         那么执行结果又该是什么呢?
         id1 name1 id2 name2
         ++++++++++++++++++++++++++++++++++++++
         001 Jplateau 01 研发部
         002 Jony     01 研发部
         003 Camel    null null  
         {就是说此时我要已第一个表的记录多少为准,第二个表中没有相应纪录的时候填充null}  
         3).  right (outer) join
         select employee.ID as id1,employee.Name as name1,department.ID as id2,department.Name
          as name2 from Employee as employee right join Department as department on employee.DepNo=
          department.ID
         那么执行结果又该是什么呢?
         id1 name1 id2 name2
         ++++++++++++++++++++++++++++++++++++++
         001 Jplateau 01 研发部
         002 Jony     01 研发部
         null null     02 营销部  
         {就是说此时我要已第二个表的记录多少为准,第一个表中没有相应纪录的时候填充null} 
         
       
4。select语句
           就是要确定你要从查询中返回哪些对象或者哪些对象的属性。写几个例子吧:
           select employee form Employee as employee
           select employee form Employee as employee where employee.Name like 'J%'
           select employee.Name form Employee as employee where employee.Name like 'J%'
           select employee.ID as id1,employee.Name as name1,department.ID as id2,department.Name
          as name2 from Employee as employee right join Department as department on employee.DepNo=
          department.ID
         
           select elements(employee.Name) from Employee as employee
           (不明白elements到底是做什么用的?望给于说明)
          
           等等
       
5。数学函数
           JDO目前好像还不支持此类特性。
           avg(...), sum(...), min(...), max(...)

            count(*)

     count(...), count(distinct ...), count(all...)
    
     其用法和SQL基本相同
    
     select distinct employee.name from Employee as employee
     select count(distinct employee.name),count(employee) from Employee as employee
    
  
6。polymorphism (暂时不知道如何解释?)
     from com.test.Animal as animal
     不光得到所有Animal得实例,而且可以得到所有Animal的子类(如果我们定义了一个子类Cat)
     一个比较极端的例子
     from java.lang.Object as o
     可以得到所有持久类的实例
    
   7。where语句
     定义查询语句的条件,举几个例子吧:
     from Employee as employee where employee.Name='Jplateau'
     from Employee as employee where employee.Name like 'J%'
     from Employee as employee where employee.Name like '%u'
     在where语句中“=”不光可以比较对象的属性,也可以比较对象,如:
     select animal from com.test.Animal as animal  where animal.name=dog
    
   
8。表达式
   
    在SQL语句中大部分的表达式在HQL中都可以使用:
    mathematical operators +, -, *, /

           binary comparison operators =, >=, <=, <>, !=, like

           logical operations and, or, not

           string concatenation ||

           SQL scalar functions like upper() and lower()
          
           Parentheses ( ) indicate grouping

           in, between, is null

           JDBC IN parameters ?

           named parameters :name, :start_date, :x1 (这种应该是另一种"?"的变通解决方法)

           SQL literals 'foo', 69, '1970-01-01 10:00:01.0'

           Java public static final constants eg.Color.TABBY
          
           其他不必解释了,在这里我只想对查询中的参数问题说明一下:
           大家知道在SQL中进行传递参数进行查询的时候,我们通常用PreparedStatement,在语句中写一大堆的“?”,
           在hql中也可以用这种方法,如:
           List mates = sess.find(
                    "select employee.name from Employee as employee " +
                    "where employee.Name=? ",
                    name,
                    Hibernate.STRING
                   );
           (说明:上面利用Session里的find方法,在hibernate的api Session中重载了很多find方法,它可以满足你多种形式的查询)
           上边是一个参数的情形,这种情况下紧接着引入参数和定义参数的类型,当为多个参数,调用另一个find方法,它的后两个
           参数都是数组的形式。
          
           还有另外一种方法来解决上边的问题,JDO也有这样的方法,不过和hibernate的表现形式上有差别,但他们两个骨子里却是
           一样的,如:
           Query q = sess.createQuery("select employee.name from Employee as employee where employee.Name=:name");
           q.setString("name", "Jplateau");
           //当有多个参数的时候在此逐一定义
           Iterator employees = q.iterate();  
          
          
9。order 语句
           和sql语句没什么差别,如:
           select employee.name from Employee as employee where employee.Name like 'J%'  order by employee.ID desc (或者asc)
          
          
10。group by 语句
           同样和sql语句没什么差别,如:
          
           select employee.name,employee.DepNo from Employee as employee group by employee.DepNo
          
          
select foo.id, avg( elements(foo.names) ), max( indices(foo.names) ) from eg.Foo foo group by foo.id
           {Note: You may use the elements and indices constructs inside a select clause, even on databases with no subselects.}
           谁帮我解释一下上边两句,谢过!

          
          
11。子查询
           hibernate同样支持子查询,写几个例子:
          
           from eg.Cat as fatcat where fatcat.weight > ( select avg(cat.weight) from eg.DomesticCat cat )

posted @ 2005-11-23 16:14 wader 阅读(2408) | 评论 (0)编辑 收藏

Configuration的其他用法(转贴)(2005-05-27 18:22)

Configuration的其他用法

  Configuration的configure ()方法还支持带参数的访问方式,你可以指定hbm.xml文件的位置,而不是使用默认的classpath下面的hibernate.cfg.xml这种方式,例如:

Configuration cfg = new Configuration().configure("myexample.xml");

  同时Configuration还提供了一系列方法用来定制hibernate的加载配置文件的过程,让你的应用更加灵活,常用的是以下几种:

addProperties(Element)
addProperties(Properties)
setProperties(Properties)
setProperty(String, String)

  通过以上几个方法,除了使用默认的hibernate.properties文件,你还可以提供多个.properties配置文件,使用Hibernate的时候根据不同的情况使用不同的配置文件,例如:

Properties properties = Properties.load("my.properties");
Configuration config = new Configuration().setProperties(properties).configure();

  除了指定.properties文件之外,还可以指定.hbm.xml文件,下面列出几个常用的方法:

addClass(Class)
addFile(File)
addFile(String)
addURL(URL)

  前面我们已经讲了,configure()方法默认是通过访问hibernate.cfg.xml的<mapping>元素来加载我们提供的.hbm.xml文件,上面列出的方法可以直接指定hbm.xml文件,例如addClass()方法可以直接通过指定class来加载对应的映射文件,hibernate会将提供的class的全名(包括package)自动转化为文件路径,如net.sf.hibernate.examples.quickstart.Cat.class对应了net/sf/hibernate/examples/quickstart/Cat.hbm.xml,还可以用addFile方法直接指定映射文件。

  例一:

Configuration config = new Configuration().addClass(Cat.class);

  例二:

Configuration config = new Configuration().addURL(Configuration.class.getResource ("Cat.hbm.xml"));

  例三:

Configuration config = new Configuration().addFile("Cat.hbm.xml");

  5、总结

  Configuration提供的这些方法的好处如下:

  1) 一个应用中往往有很多.hbm.xml映射文件,开发的过程中如果只是为了测试某个或几个Java PO(Persistence Object),我们没有必要把所有的.hbm.xml都加载到内存,这样可以通过addClass或者addFile直接,显得非常灵活。

  2) 学习Hibernate的过程中,往往需要通过练习来体会Hibernate提供的各种特征,而很多特征是需要修改配置文件的,如果要观察相同的代码在不同的特征下的表现,就需要手工改配置文件,这样太麻烦了,而且容易出错,我们可以提供多个配置文件,每个配置文件针对需要的特征而配置,这样我们在调用程序的时候,把不同的配置文件作为参数传递进去,而程序代码里面使用setProperties和addFile指定传入的配置文件参数就可以了。

  3) 在单元测试中,特别是在集成测试里面,整个过程是自动化的,我们不能手工干预测试过程,往往需要准备多个配置文件针对不同的测试案例,这个时候setProperties和addFile方法就显得特别有用了,在不同的测试案例中用这些方法来指定相应的配置文件,这样就可以做到自动化测试,保证了持续性。

posted @ 2005-11-23 16:09 wader 阅读(737) | 评论 (0)编辑 收藏

概要设计怎么写(你想成为软件设计师吗) (转贴)( 2005-08-10 11:41)

发表者付:
做软件到一定层次了,就要考虑到设计了,设计了很久,就是不系统,系统的设计需要一个记录,记录就用文档,那么对项目所有包括技术上的设计都记录下来,我们就可以理解为软件的概要设计了。


在需求明确、准备开始编码之前,要做概要设计,而详细设计可能大部分公司没有做,有做的也大部分是和编码同步进行,或者在编码之后。因此,对大部分的公司来说,概要设计文档是唯一的设计文档,对后面的开发、测试、实施、维护工作起到关键性的影响。
  一、问题的提出
  概要设计写什么?概要设计怎么做?
  如何判断设计的模块是完整的?
  为什么说设计阶段过于重视业务流程是个误区?
  以需求分析文档还是以概要设计文档来评估开发工作量、指导开发计划准确?
  结构化好还是面向对象好?
  以上问题的答案请在文章中找。
  二、概要设计的目的
  将软件系统需求转换为未来系统的设计;
  逐步开发强壮的系统构架;
  使设计适合于实施环境,为提高性能而进行设计;
  结构应该被分解为模块和库。
  三、概要设计的任务
   制定规范:代码体系、接口规约、命名规则。这是项目小组今后共同作战的基础,有了开发规范和程序模块之间和项目成员彼此之间的接口规则、方式方法,大家就有了共同的工作语言、共同的工作平台,使整个软件开发工作可以协调有序地进行。
  总体结构设计:
  功能(加工)->模块:每个功能用那些模块实现,保证每个功能都有相应的模块来实现;
  模块层次结构:某个角度的软件框架视图;
  模块间的调用关系:模块间的接口的总体描述;
  模块间的接口:传递的信息及其结构;
  处理方式设计:满足功能和性能的算法
  用户界面设计;
  数据结构设计:
  详细的数据结构:表、索引、文件;
  算法相关逻辑数据结构及其操作;
  上述操作的程序模块说明(在前台?在后台?用视图?用过程?······)
  接口控制表的数据结构和使用规则
  其他性能设计。
  四、概要设计写什么
  结构化软件设计说明书结构(因篇幅有限和过时嫌疑,在此不作过多解释)
  任务:目标、环境、需求、局限;
  总体设计:处理流程、总体结构与模块、功能与模块的关系;
  接口设计:总体说明外部用户、软、硬件接口;内部模块间接口(注:接口≈系统界面)
  数据结构:逻辑结构、物理结构,与程序结构的关系;
  模块设计:每个模块“做什么”、简要说明“怎么做”(输入、输出、处理逻辑、与其它模块的接口,与其它系统或硬件的接口),处在什么逻辑位置、物理位置;
  运行设计:运行模块组合、控制、时间;
  出错设计:出错信息、处错处理;
  其他设计:保密、维护;
  OO软件设计说明书结构
  1 概述
  系统简述、软件设计目标、参考资料、修订版本记录
  这部分论述整个系统的设计目标,明确地说明哪些功能是系统决定实现而哪些时不准备实现的。同时,对于非功能性的需求例如性能、可用性等,亦需提及。需求规格说明书对于这部分的内容来说是很重要的参考,看看其中明确了的功能性以及非功能性的需求。
这部分必须说清楚设计的全貌如何,务必使读者看后知道将实现的系统有什么特点和功能。在随后的文档部分,将解释设计是怎么来实现这些的。
  2 术语表
  对本文档中所使用的各种术语进行说明。如果一些术语在需求规格说明书中已经说明过了,此处不用再重复,可以指引读者参考需求说明。
  3 用例
  此处要求系统用用例图表述(UML),对每个用例(正常处理的情况)要有中文叙述。
  4 设计概述
  4.1 简述
  这部分要求突出整个设计所采用的方法(是面向对象设计还是结构化设计)、系统的体系结构(例如客户/服务器结构)以及使用到的相应技术和工具(例如OMT、Rose)
  4.2 系统结构设计
  这部分要求提供高层系统结构(顶层系统结构、各子系统结构)的描述,使用方框图来显示主要的组件及组件间的交互。最好是把逻辑结构同物理结构分离,对前者进行描述。别忘了说明图中用到的俗语和符号。
  4.3 系统界面
  各种提供给用户的界面以及外部系统在此处要予以说明。如果在需求规格说明书中已经对用户界面有了叙述,此处不用再重复,可以指引读者参考需求说明。如果系统提供了对其它系统的接口,比如说从其它软件系统导入/导出数据,必须在此说明。
  4.4 约束和假定
  描述系统设计中最主要的约束,这些是由客户强制要求并在需求说明书写明的。说明系统是如何来适应这些约束的。
  另外如果本系统跟其它外部系统交互或者依赖其它外部系统提供一些功能辅助,那么系统可能还受到其它的约束。这种情况下,要求清楚地描述与本系统有交互的软件类型以及这样导致的约束。
  实现的语言和平台也会对系统有约束,同样在此予以说明。
  对于因选择具体的设计实现而导致对系统的约束,简要地描述你的想法思路,经过怎么样的权衡,为什么要采取这样的设计等等。
  5 对象模型
  提供整个系统的对象模型,如果模型过大,按照可行的标准把它划分成小块,例如可以把客户端和服务器端的对象模型分开成两个图表述。在其中应该包含所有的系统对象。这些对象都是从理解需求后得到的。要明确哪些应该、哪些不应该被放进图中。所有对象之间的关联必须被确定并且必须指明联系的基数。聚合和继承关系必须清楚地确定下来。每个图必须附有简单的说明。
  6 对象描述
  在这个部分叙述每个对象的细节,它的属性、它的方法。在这之前必须从逻辑上对对象进行组织。你可能需要用结构图把对象按子系统划分好。
  为每个对象做一个条目。在系统对象模型中简要的描述它的用途、约束(如只能有一个实例),列出它的属性和方法。如果对象是存储在持久的数据容器中,标明它是持久对象,否则说明它是个临时对象(transient object)。
  对每个对象的每个属性详细说明:名字、类型,如果属性不是很直观或者有约束(例如,每个对象的该属性必须有一个唯一的值或者值域是有限正整数等)。
  对每个对象的每个方法详细说明:方法名,返回类型,返回值,参数,用途以及使用的算法的简要说明(如果不是特别简单的话)。如果对变量或者返回值由什么假定的话,Pre-conditions和Post-conditions必须在此说明。列出它或者被它调用的方法需要访问或者修改的属性。最后,提供可以验证实现方法的测试案例。
  7 动态模型
  这部分的作用是描述系统如何响应各种事件。一般使用顺序图和状态图。
  确定不同的场景(Scenario)是第一步,不需要确定所有可能的场景,但是必须至少要覆盖典型的系统用例。不要自己去想当然地创造场景,通常的策略是描述那些客户可以感受得到的场景。
  7.1 场景(Scenarios)
  对每个场景做一则条目,包括以下内容:
  场景名:给它一个可以望文生义的名字
  场景描述:简要叙述场景是干什么的以及发生的动作的顺序。
  顺序图:描述各种事件及事件发生的相对时间顺序。
  7.2 状态图
  这部分的内容包括系统动态模型重要的部分的状态图。可能你想为每个对象画一个状态图,但事实上会导致太多不期望的细节信息,只需要确定系统中一些重要的对象并为之提供状态图即可。
  8 非功能性需求
  五、概要设计怎么做
  结构化软件设计方法:
  详细阅读需求规格说明书,理解系统建设目标、业务现状、现有系统、客户需求的各功能说明;
  分析数据流图,弄清数据流加工的过程;
  根据数据流图决定数据处理问题的类型(变换型、事务型、其他型);
  通过以上分析,推导出系统的初始结构图;
  对初始结构图进行改进完善:所有的加工都要能对应到相应模块(模块的完整性在于他们完成了需求中的所有加工),消除完全相似或局部相似的重复功能(智者察同),理清模块间的层次、控制关系,减少高扇出结构,随着深度增大扇入,平衡模块大小。
  由对数据字典的修改补充完善,导出逻辑数据结构,导出每种数据结构上的操作,这些操作应当属于某个模块。
  确定系统包含哪些应用服务系统、客户端、数据库管理系统;
  确定每个模块放在哪个应用服务器或客户端的哪个目录、哪个文件(库),或是在数据库内部建立的对象。
  对每个筛选后的模块进行列表说明。
  对逻辑数据结构进行列表说明。
  根据结构化软件设计说明书结构对其他需要说明的问题进行补充说明,形成概要设计说明书。
  OO软件设计方法:
  在OOA基础上设计对象与类:在问题领域分析(业务建模和需求分析)之后,开始建立系统构架。
  第一步是抽取建立领域的概念模型,在UML中表现为建立对象类图、活动图和交互图。对象类就是从对象中经过“察同”找出某组对象之间的共同特征而形成类:
  对象与类的属性:数据结构;
  对象与类的服务操作:操作的实现算法;
  对象与类的各外部联系的实现结构;
  设计策略:充分利用现有的类;
  方法:继承、复用、演化;
  活动图用于定义工作流,主要说明工作流的5W(Do What、Who Do、When Do、Where Do、Why Do)等问题,交互图把人员和业务联系在一起是为了理解交互过程,发现业务工作流中相互交互的各种角色。
  第二步是构建完善系统结构:对系统进行分解,将大系统分解为若干子系统,子系统分解为若干软件组件,并说明子系统之间的静态和动态接口,每个子系统可以由用例模型、分析模型、设计模型、测试模型表示。软件系统结构的两种方式:层次、块状
  层次结构:系统、子系统、模块、组件(同一层之间具有独立性);
  块状结构:相互之间弱耦合
  系统的组成部分:
  问题论域:业务相关类和对象(OOA的重点);
  人机界面:窗口、菜单、按钮、命令等等;
  数据管理:数据管理方法、逻辑物理结构、操作对象类;
  任务管理:任务协调和管理进程;
  第三步是利用“4+1”视图描述系统架构:用例视图及剧本;说明体系结构的设计视图;以模块形式组成包和层包含概要实现模型的实现视图;说明进程与线程及其架构、分配和相互交互关系的过程视图;说明系统在操作平台上的物理节点和其上的任务分配的配置视图。在RUP中还有可选的数据视图。
  第四步是性能优化(速度、资源、内存)、模型清晰化、简单化(简单就是享受)。
  六、概要设计的原则
  总体原则和方法:由粗到细的原则,互相结合的原则,定性分析和定量分析相结合的方法,分解和协调的方法和模型化方法。
  要系统考虑系统的一般性、关联性、整体性和层次性。
  分解协调:目的是为了创造更好的系统。系统分解是指将一个复杂的系统分解为若干个子系统,系统协调一是系统内协调,即根据系统的总结构、总功能、总任务和总目标的要求,使各个子系统之间互相协调配合,在各个子系统局部优化基础上,通过内部平衡的协调控制,实现系统的整体优化;
  屏蔽抽象:从简单的框架开始,隐含细节;
  一致性:统一的规范、统一的标准、统一的文件模式;
  每个模块应当有一个统一命名的容易理解的名字;
  编码:由外向内(界面->核心);
  面向用户:概要设计是对于按钮按下后系统“怎么做”的简要说明;
  模块、组件的充分独立性、封闭性;
  同时考虑静态结构与动态运行;
  每个逻辑对象都应当说明其所处物理对象(非一一对应);
  每个物理对象都有合适的开发人员,并且利于分工与组装。(详细说明见本人另一篇文章:系统构架设计应考虑的因素);
  确立每个构架视图的整体结构:视图的详细组织结构、元素的分组以及这些主要分组之间的接口;
  软件构架与使用的技术平台密切相关,目前常用的平台有J2EE、.NET、CORBA等等,因此具体的软件构架人员应当具备使用这些平台的软件开发经验;
  通过需求功能与设计模块之间的列表对应,检查每个需求功能是否都有相应的模块来实现,保证需求功能的可追溯性和需求实现(模块)的完整性,同时可以检查重复和不必要的模块。
  在需求调研分析过程中对业务处理过程了解的完整性和准确性非常重要。调查了解清楚所有的业务流程才能设计出适合各流程业务节点用户业务特点和习惯的软件,使开发出来的软件更受欢迎。当然在进行软件概要设计时,要尽量排除业务流程的制约,即把流程中的各项业务结点工作作为独立的对象,设计成独立的模块,充分考虑他们与其他各种业务对象模块的接口,在流程之间通过业务对象模块的相互调用实现各种业务,这样,在业务流程发生有限的变化时(每个业务模块本身的业务逻辑没有变的情况下),就能够比较方便地修改系统程序模块间的调用关系而实现新的需求。如果这种调用关系被设计成存储在配置库的数据字典里,则连程序代码都不用修改,只需修改数据字典里的模块调用规则即可。
  七、概要设计的重要输出
  编码规范:信息形式、接口规约、命名规则;
  物理模型:组件图、配置图;
  不同角度的构架视图:用例视图、逻辑视图、进程视图、部署视图、实施视图、数据视图(可选);
  系统总体布局:哪些部分组成、各部分在物理上、逻辑上的相互关系;
  两个不可忽视的输出:
  与需求功能的关系:对于需求中的每一个功能,用哪一层、哪个模块、哪个类、哪个对象来实现(一对多关系);反过来,应当说明将要创建的系统每一层、每个模块、每个对象、每一个类“做什么”,他们是为了帮助实现哪些功能(一对多关系)。(需求的颗粒度在一开始往往是比较粗的,因此根据功能点对于整体项目规模的估计或得到项目WBS其误差范围也是比较大的。更为重要的原因是,需求往往不是编码工作分解的准确依据,因为一个需求的功能点可能对应多个代码模块,而多个需求的功能点也可能只对应一个或少数代码模块,同时还有软件复用等因素要考虑,因此只有在概要设计完成以后才能准确地得到详细设计或编码阶段的二次WBS,并估计较为准确的整体项目规模。)
  逻辑与物理位置:每个对象在逻辑上分别落在哪一层、哪个模块、哪个类;在物理上每个模块、每个对象、每一个类放在哪个应用服务器或客户端的哪个目录、哪个文件(库),或者是建立在数据库管理系统中的什么东东(过程、函数、视图、触发器等等)。
  八、结构化与面向对象方法特点比较
  1. 从概念方面看,结构化软件是功能的集合,通过模块以及模块和模块之间的分层调用关系实现;面向对象软件是事物的集合,通过对象以及对象和对象之间的通讯联系实现;
  2. 从构成方面看,结构化软件=过程+数据,以过程为中心;面向对象软件=(数据+相应操作)的封装,以数据为中心;
  3. 从运行控制方面看,结构化软件采用顺序处理方式,由过程驱动控制;面向对象软件采用交互式、并行处理方式,由消息驱动控制;
  4. 从开发方面看,结构化方法的工作重点是设计;面向对象方法的工作重点是分析;但是,在结构化方法中,分析阶段和设计阶段采用了不相吻合的表达方式,需要把在分析阶段采用的具有网络特征的数据流图转换为设计阶段采用的具有分层特征的结构图,在面向对象方法中则不存在这一问题。
  5. 从应用方面看,相对而言,结构化方法更加适合数据类型比较简单的数值计算和数据统计管理软件的开发;面向对象方法更加适合大型复杂的人机交互式软件和数据统计管理软件的开发;
  参考文献:
  《实用软件工程》第二版,郑人杰、殷人昆、陶永雷等著
  《微软项目:求生法则》Steve McConnell著,余孟学译
  《软件工程:实践者的研究方法》(第5版)Roger S.Pressman著
  《软件构架实践》SEI软件工程译丛,林·巴斯著
  《RUP2000》电子版;
  《UML与系统分析设计》张龙祥著;
  《面向对象的分析与设计》杨正甫著;

posted @ 2005-11-23 16:03 wader 阅读(1307) | 评论 (1)编辑 收藏

Oracle开发人员 JAVA存储过程(转贴)(2005-07-12 17:51 )

Oracle开发人员 JAVA存储过程
利用Java存储过程简化数据库操作
作者:Kuassi Mensah
利用Java存储过程沟通SQL、XML、Java、J2EE和Web服务。
存储过程(stored procedure)允许将运行于数据库层中的持久性逻辑与运行于中间层中的商务逻辑有效地分离开来。这种分离可以降低整个应用程序的复杂性,并提供其重用性、安全性、性能和可伸缩性。

但是,妨碍存储过程广泛采用的一个主要障碍是不同数据库厂商使用各种专有的、且依赖于数据库的实现语言。使用基于Java的存储过程可以解决这一问题。Oracle已经实现了ANSI标准,这些标准规定了从SQL中将静态Java方法作为过程或函数进行调用的能力。这种实现被简单地称作"Java存储过程"。

在本文中,你将了解基于Java的存储过程如何帮助简化商务逻辑、提高其性能,并扩展数据库的功能。本文将介绍Oracle如何在数据库内启用基于Java的存储过程。还会介绍Java存储过程如何访问数据,以及如何创建基本Java存储过程。

选择PL/SQL还是Java

在考虑Oracle存储过程时,你可能会想到PL/SQL。不过,从Oracle8i开始,Oracle已经在数据库中支持Java,从而为存储过程提供了不同于PL/SQL的开放式和可移植的方法。我可以听到"$64 000问题":"我如何在PL/SQL和Java之间做出选择?我是否应当忘记已经学习的所有PL/SQL相关知识,而变为一个Java天地的新手?"

两种语言都适用于数据库编程,都有自己的优点和弱点。在决定选择哪一种语言时,可以参考下面根据经验得出的通用规则:

对于要求与SQL进行无缝集成的数据库中心来说则逻辑使用PL/SQL,从而完成对数据库对象、类型和特性的访问。
出于与数据库的无关性考虑时,可以选择Java作为开放式的语言来取代PL/SQL,同时也为了集成和沟通SQL、XML、J2EE和Web服务等各个领域。
OralceJVM使得Java可以运行在数据库中

从Oracle8i版本1(Oralce8.1.5)开始,Oracle便提供紧密集成的Java虚拟机(JVM),JVM支持Oralce的数据库会话期结构。任何数据库对话期都可以在第一Java代码调用时启动一个虚拟上专用的JVM,后续的用户可以使用这一已经存在的支持Java的会话期。事实上,所有会话共享同一JVM代码并保持"仅静态"的私有状态,而垃圾则收集在单个对话期空间内,从而为各个Java对话期提供了和SQL操作相同的对话期隔离和数据完整性能力。这里,不需要为了数据完整性而进行单独的Java支持的过程。这一基于对话期的结构提供了较小的内存占用率,并使OracleJVM具有与Oracle数据库一样的线性SMP可伸缩性。

创建Java存储过程

要将Java方法转换为Java存储过程需要几个步骤,包括:用loadjava实用程序将Java类加载到数据库中,利用调用规范(Call Spec)发布Java方法,将Java方法、参数类型和返回类型映射到其SQL的对应部分。下面部分说明如何完成这些步骤。

我将使用一个简单的Hello类,它有一个方法Hello.world(),返回字符串"Hello world":
public class Hello { public static String world () { return "Hello world"; } }
Loadjava 实用程序

Loadjava是加载Java源文件、Java类文件和Java资源文件的实用程序,它可以用来验证字节码,并将Java类和JAR文件布置到数据库中。它既可以通过命令行调用,也可以通过包含于DBMS_JAVA类中的loadjava()方法调用。为了加载我们的Hello.class示例,输入:
loadjava -user scott/tiger Hello.class

从Oracle9i版本2开始,loadjava允许通过为包含在被处理的类中的方法创建相应的Call Specs来自动将Java类发布为存储过程。Oracle为开发、测试、调试和布置Java存储过程提供了Oracle9i JDeveloper。

The Resolver Spec

基于JDK的JVM在列于CLASSPATH中的目录中查找类引用,并对其进行解析。因为Oracle数据库类存在于数据库模式中,所以OracleJVM利用数据库解析器(resolver)通过列于Resolver Spec中的模式查找并解析类引用。与CLASSPATH不同(CLASSPATH可以应用于所有的类),Resover Spec根据每类的情况进行应用。缺省解析器首先在加载类的模式中搜寻类,然后在公共同义词(public synonyms)中搜索。 
 loadjava -resolve <myclass>
你可能需要指定不同的解析器,也可以在使用loadjava时强制进行解析,从而在布置时确定可能在以后运行时发生的任何问题。
loadjava -resolve -resolver "((* SCOTT) (foo/bar/* OTHERS) (* PUBLIC))"
Call Spec和存储过程调用

为了从SQL中调用Java方法(以及从PL/SQl和JDBC中调用),必须首先通过Call Spec发布公共静态方法,它为SQL定义方法采用的参数以及返回的SQL类型。

在我们的例子中,我们将利用SQL*Plus连接到数据库,并为Hello.world()定义一个顶级Call Spec:
SQL> connect scott/tiger SQL> create or replace function helloworld return VARCHAR2 as language java name 'Hello.world () return java.lang.String'; / Function created.
可以像下面这样调用Java存储过程:
SQL> variable myString varchar2[20]; SQL> call helloworld() into :myString; Call completed. SQL> print myString; MYSTRING --------------------- Hello world
Java存储过程可以通过其Call Spec从以下各项中进行调用:SQL DML语句(INSERT, UPDATE、DELETE、SELECT、CALL、EXPLAIN PLAN、LOCK TABLE和MERGE)、PL/SQL块、子程序、程序包以及数据库触发器。Call Spec的美妙之处在于存储过程实现可以从PL/SQL转换为Java,反之亦可,这一点对于请求者是透明的。

Call Spec从实现语言中(PL/SQL或Java)中抽象出调用界面,因而使之能够在原有应用程序和新的基于Java/J2EE的应用程序之间共享商务逻辑。但是,在从Java客户程序调用在数据库驻留的Java类时,你可能不希望通过PL/SQL包装器(wrapper)。在以后的版本中,Oracle计划提供一种机制,它可以使开发人员略过Call Spec。

高级数据访问控制

Java存储过程可用于控制和限制对Oracle数据的访问,其方法是只允许用户通过存储过程管理数据,而存储过程在其调用者的权限内执行,而不能对表本身进行访问。例如,你可以在特定时间内禁止更新数据,或者使管理者只具有查询工资数据的权利,而不能进行更新,或者记录所有的访问并通知某一安全机构。

原有应用程序与J2EE应用程序之间的数据逻辑共享因为原有应用程序与J2EE应用程序都通过Call Spec调用存储过程,所以J2EE和非J2EE应用程序可以共享相同的数据逻辑。由于有了Call Spec,所以不用考虑所用的是何种实现语言(无论是PL/SQL还是Java),该数据逻辑都可以共享。

为BMP实体Bean自动生成主关键字

在对EJB实体bean应用BMP时,一个bean实例可以由自动生成的与新插入的数据相关联的主关键字惟一确定,它是ejbCreate()的返回值。可以利用一个插入相应数据的存储过程在一个数据库操作中检索ejbCeater()中的该值,并检索或计算主关键字。作为另一种方法,也可以利用JDBC3.0的RETURN_GENERATED_KEYS特性,以一个SQL语句插入该数据并检索相应的关键字(或ROWID)。但是,存储过程方法在各个JDBC驱动器版本和数据库之间更具可移植性。

posted @ 2005-11-23 15:54 wader 阅读(438) | 评论 (0)编辑 收藏

标准hibernate配置文件(我以前做海信项目时配置的)

<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"
http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>

<!-- properties -->

<property name="hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:jtds:sqlserver://192.168.0.29:1433/HisenseCommunity</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password">admin</property>
<property name="hibernate.dialect">org.hibernate.dialect.SybaseDialect</property>
<property name="hibernate.connection.pool.size">20</property>
<property name="hibernate.show_sql">true</property>

<!-- mapping files -->
<mapping resource="hisense/ORMFILE/AdminInfoBean.hbm.xml"/>
<mapping resource="hisense/ORMFILE/AdminLevel.hbm.xml"/>
<mapping resource="hisense/ORMFILE/Operate.hbm.xml"/>
<mapping resource="hisense/ORMFILE/Relation.hbm.xml"/>
<mapping resource="hisense/ORMFILE/Community.hbm.xml"/>
<mapping resource="hisense/ORMFILE/Category.hbm.xml"/>
<mapping resource="hisense/ORMFILE/CategoryType.hbm.xml"/>
<mapping resource="hisense/ORMFILE/AdBusiness.hbm.xml"/>
<mapping resource="hisense/ORMFILE/AdClient.hbm.xml"/>
<mapping resource="hisense/ORMFILE/AdContent.hbm.xml"/>
<mapping resource="hisense/ORMFILE/AdType.hbm.xml"/>
<mapping resource="hisense/ORMFILE/Profile.hbm.xml"/>
<mapping resource="hisense/ORMFILE/ProfileDv.hbm.xml"/>
<mapping resource="hisense/ORMFILE/ProfileAlbum.hbm.xml"/>
<mapping resource="hisense/ORMFILE/Club.hbm.xml"/>
<mapping resource="hisense/ORMFILE/CommendType.hbm.xml"/>
<mapping resource="hisense/ORMFILE/Comment.hbm.xml"/>
<mapping resource="hisense/ORMFILE/Goods.hbm.xml"/>
<mapping resource="hisense/ORMFILE/CommunityMarket.hbm.xml"/>
<mapping resource="hisense/ORMFILE/CommunityMarketType.hbm.xml"/>
<mapping resource="hisense/ORMFILE/News.hbm.xml"/>
<mapping resource="hisense/ORMFILE/Merchant.hbm.xml"/>
<mapping resource="hisense/ORMFILE/Commend.hbm.xml"/>
<mapping resource="hisense/ORMFILE/ClubActivities.hbm.xml"/>
<mapping resource="hisense/ORMFILE/ActivityType.hbm.xml"/>
<mapping resource="hisense/ORMFILE/EstateManagement.hbm.xml"/>
<mapping resource="hisense/ORMFILE/ProfileAndClubRelations.hbm.xml"/>

</session-factory>
</hibernate-configuration>

posted @ 2005-11-23 15:37 wader 阅读(668) | 评论 (0)编辑 收藏

用xdoclet 1.2 实例生成struts实体bean的hbm文件

这是我曾经为系统生成hbm文件时编写的一个ant 的build.xml配置文件,这里面主要有两类参数设置,一类是路径设置,另一类是功能加载设置;下面通过看看我的注释你就应该明白了:
<?xml version="1.0" encoding="UTF-8"?>         //xml标头信息
<project name="Test" default="all" basedir=".">      //basedir是指定根目录,"."提当前目录;
   <property name="classes" location="./classes"/>      //生成类的指定目录
   <property name="src" value="src" />      //源文件,要编译的源的目录;
   <property name="db" value="db" />      //数据库设置
   <property name="lib" value="./aiihome_admin/WEB-INF/lib" />  //指定库路径;
   <property name="lib-xdoc" value="./lib" />            //指定xdoc库路径;
   <property name="build" value="classes" />            //成生输出的目录;

   <path id="myclasspath">         //设置路径组
    <fileset dir="${lib}">
     <include name="*.jar"/>
    </fileset>
    <fileset dir="${lib-xdoc}">
     <include name="*.jar"/>
    </fileset>

   </path>

   <target name="init">                  //设置初始化功能
   <mkdir dir="${classes}"/>
   </target>

   <target name="compile" depends="init">         //设置要完成的工作,depends指他的依赖项,也是必须项
   <javac executable="jikes" classpathref="myclasspath"    srcdir="${src}" destdir="${classes}"/>
   </target>

   <target name="clean">               //设置清除功能
   <delete dir="${classes}"/>            //dir要清除的目录
   </target>

   <target name="xdoc" description="Generates Hibernate class descriptor files.">          //设置xdoc工作功能
     <taskdef name="hibernatedoclet" classpathref="myclasspath"               classname="xdoclet.modules.hibernate.HibernateDocletTask">       //任务名hibernatedoclet,类库classname
     </taskdef>
     <hibernatedoclet destdir="${classes}">                                       //hibernatedoclet任务设置项
      <fileset dir="${src}">                                                                  //源目录
       <include name="**/*.java"/>                                                      //文件名
      </fileset>
     <hibernate version="2.0"/>                                                         //hibernate vs
   </hibernatedoclet>
   </target>

   <target name="all" depends="xdoc" />                                             //执行任务名
   <!-- Other target omited -->
</project>

关于ant编译文件的标签很多,不同的标签可以实现不同的功能,在编译这一块地,ant真是太强了,可惜我只知道皮毛,提供大家一个配置文件参考:在middlegen2里面有一个example里有一个生成ejb项目的build文件,它的生成项目比较全,应该可以满足一般需要了。

posted @ 2005-11-23 15:30 wader 阅读(559) | 评论 (0)编辑 收藏

[Hibernate]使用XDoclet生成hbm.xml

用XDoclet生成hbm.xml就是在.java文件里写入一些元数据,XDoclet会从这些数据以及类本身得到足够的信息来生成目标文件。当然,除了用于hibernate,XDoclet还可以用于web、ejb等等很多用途。

XDoclet要从sourceforge上下载,包含了很多jar包、文档和例子,我觉得文档做得还是不错的,查起来比较方便。要使用XDoclet,一般要通过ant来完成,也就是在ant脚本里加入XDoclet的内容。

由于eclipse已经包含了ant支持,因此我没有专门去下载一个ant回来,而是直接使用eclipse带的,版本是1.5.3。

创建一个名为build.xml的脚本(其实应该换个名,比如gen-hbm.xml,看起来比较明白),内容如下:

<?xml version="1.0" encoding="ISO-8859-1"?>

<project name="XDoclet Examples" default="hibernate" basedir=".">
    <property name="xdoclet.root.dir" value="c:/xdoclet-1.2.1"/>
    <property name="xdoclet.lib.dir" value="${xdoclet.root.dir}/lib"/>
    <path id="myclasspath">
        <fileset dir="${xdoclet.lib.dir}">
            <include name="*.jar"/>
        </fileset>
    </path>
     <taskdef
        name="hibernatedoclet"
        classname="xdoclet.modules.hibernate.HibernateDocletTask"
        classpathref="myclasspath"
        />
    <target name="hibernate" description="Generate mapping documents">

        <echo>+---------------------------------------------------+</echo>
        <echo>|                                                   |</echo>
        <echo>| R U N N I N G   H I B E R N A T E D O C L E T     |</echo>
        <echo>|                                                   |</echo>
        <echo>+---------------------------------------------------+</echo>

        <hibernatedoclet
            destdir="./src"
            excludedtags="@version,@author,@todo,@see"
            addedtags="@xdoclet-generated at ${TODAY},@copyright The XDoclet Team,@author XDoclet,@version ${version}"
            force="false"
            verbose="true">

            <fileset dir="./src">
                <include name="org/haree/struts/form/UserForm.java"/>
            </fileset>

            <hibernate version="2.0"/>

        </hibernatedoclet>
    </target>
</project>

我曾经卡住的一个地方就是在taskdef里的classpathref属性。一开始我在eclipse的ant运行参数里设置了XDoclet相关的包,总是提示:

Can't create a hibernate element under hibernatedoclet. Make sure the jar file containing the corresponding subtask class is on the classpath specified in the <taskdef> that defined {2}.

后来如上设置了classpathref,即包含了XDoclet使用到的包,并将eclipse的ant里关于XDoclet的包都去掉,竟然就成功了。其实现在也不明白为什么会这样。。。

posted @ 2005-11-23 15:09 wader 阅读(752) | 评论 (0)编辑 收藏