WADER

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

2007年9月24日

在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 阅读(5648) | 评论 (0)编辑 收藏

2007年9月9日

Lucene in Action(中文版)

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

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

2006年6月12日

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 阅读(278) | 评论 (0)编辑 收藏

2005年11月23日

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 阅读(489) | 评论 (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 阅读(1124) | 评论 (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 阅读(298) | 评论 (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 阅读(314) | 评论 (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 阅读(399) | 评论 (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 阅读(2409) | 评论 (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 阅读(739) | 评论 (0)编辑 收藏