2009年4月20日星期一
项目中遇到的一个动态查询
实现: select * from users where user_id in
( select id from
( select t1.id, 1 flag from table1 union all select t2.id, 2 flag from table2
)where flag = decode (&flag,1,1,2,2)
);
2009年4月19日星期日
windows下安装基于Apache的Subversion服务器
在Windows下安装最为方便的办法就是下载安装程序包,详细过程如下:
1.安装程序与下载说明
Apache Web服务器 :http://httpd.apache.org/download.cgi
(Apache2.0.X版,我用的是2.0.59版;用2.2.X在windows下配置文件修改后无法启动!)
Subversion :(http://subversion.tigris.org/files/documents/15/35379/svn-1.4.2-setup.exe)
TortoiseSVN 客户端工具 (TortoiseSVN-1.4.1.7992-win32-svn-1.4.2.msi)
网络上比较多,这里就不给出。
2. 程序安装
(1)Apache2.0.63安装
防止安装有问题,如果机器上装有IIS,在安装前我先将IIS端口改为8080,然后按提示安装完成
打开 http://loccalhost,如果能出现内容,那你的Apache就安装成功了。
注:如果你将Apache安装成一个服务,它将以本地system帐户来运行。为Apache创建一个单独的用户来运行它将会更安全一些。由于常用的端口号冲突比较多,可以将Apache的端口号该为其他,比如81等。
请确保运行Apache的用户有版本库的完全访问权限(右键版本库目录->属性->安全)。要不然,用户将无法提交他们的更改。就算Apache以本机system来运行,你也要设置它能完全读写版本库目录。
如果没有为Apache配置这个许可,用户将会得到"禁止访问"的错误信息,在Apache的错误日志中表现为错误500。
(2)运行Subversion安装程序,如果安装程序能够识别你已经安装了Apache,那么你的安装基本上就OK了。如果它不能(我的机器未能识别),那么你需要做以下手工配置:
注:如果你先安装Apache,再安装Subversion,正常情况下下面的工作(2.3配置前)Subversion安装程序已经帮你完成了使用资源管理器,进入Sibversion的安装目录(通常为c:\program files\Subversion),找到文件 httpd/mod_dav_svn.so和mod_authz_svn.so,将它们拷贝到Apache的modules目录(通常为c:\ program files\apache group\apache2\modules)。
从Subversion的安装目录拷贝文件libdb43.dll到Apache的modules目录。
使用如记事本之类的文本编辑器编辑Apache的配置文件(通常为c:\program files\apache group\apache2\conf\httd.conf),修改以下内容:
去掉以下行的注释(将开头的#删除):
#LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule dav_module modules/mod_dav.so
在LoadModule节的最后添加以下两行:
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
在配置文件的最后添加下面这些行:
<Location /svn>
DAV svn
SVNParentPath D:\SVN
AuthType Basic
AuthName "Subversion repositories"
AuthUserFile D:\passwd
#AuthzSVNAccessFile D:\svnaccessfile
Require valid-user
</Location>
配置表示:你所有的版本库将位于D:\SVN目录下,要访问你的版本库可以使用这样的
URL:http://YourIP/svn/,访问权限将由passwd文件中的用户名/密码来限制。
详细说明如下:
---------------------------------------------------------------------------
<Location /svn>
意味着可以通过像这样的URL(http://MyServer/svn)来访问Subversion版本库
DAV svn
告诉Apache哪个模块负责服务像那样的URL--在这里就是Subversion模块
SVNListParentPath on
在Subversion 1.3及更高版本中,这个指示器使得Subversion列出由SVNParentPath指定的目录下所有的版本库
SVNParentPath D:\SVN
告诉Subversion在目录D:\SVN下寻找版本库 #(修改成你自己的目录)
AuthType Basic
启用基本的验证,比如用户名/密码
AuthName "Subversion repositories"
当一个验证对话框弹出时,告诉用户这个验证是用来做什么的
AuthUserFile D:\passwd #(密码文件,不是文件夹哦)
指定D:\passwd用为密码文件用来验证用户的用户名及密码
AuthzSVNAccessFile D:\svnaccessfile
指定D:\svnaccessfile来限定各个用户或组在版本库中目录的访问权限
Require valid-user
限定用户只有输入正确的用户名及密码后才能访问这个路径
---------------------------------------------------------------------------
创建passwd文件
打开命令行(DOS窗口CMD),
将当前目录切换到apache2目录(通常为c:\program files\apache group\apache2\bin),
输入命令:
htpasswd.exe -c passwd username
Automatically using MD5 format.
New password: ****** (输入密码)
Re-type new password: ******
Adding password for user username
copy passwd d:\ (Httpd.conf 中设定的是在D:)
重启Apache服务。
重启后打开http://YourIP/svn/ 输入密码后,还是出错(因为还没有建立版本库)
Forbidden
You don't have permission to access /svn on this server.
--------------------------------------------------------------------------------
Apache/2.0.59 (Win32) SVN/1.4.2 DAV/2 Server at 192.168.18.8 Port 80
(3)TortoiseSVN
按提示安装完成,需重启电脑
3.SVN项目设置
(1).打开资源管理器,在D:\SVN目录下新建WWW目录
(2).在WWW文件夹上右击TortoiseSVN--->Create repository here...
(也可以通过命令的方式:到SVN的安装BIN目录。运行:svnadmin create D:\svn\www
d:\svn目录需先建好,要不会出错:
svnadmin: 档案库创建失败
svnadmin: 无法创建最上层目录
(3).然后选择Native filesystem(FSFS)
(4).到项目文件夹上,右击TortoiseSVN-->import...
在URL of repository:中输入http://YourIP/svn/www
(5).项目成员,可在自己机上新建一个空的项目文件夹.右击SVN checkout...
在提示的用户名和密码对话框中输入服务端配置的用户名和密码;然后点击OK;后面对话框中即会显示逐个加入的文件和目录信息,最后一条显示“Completed At Version 1”。
如果成功,可以在本地目录下看到相应的代码文件。选中文件或目录,可以进行“SVN Update”(从服务器更新版本)和“Svn Commit”(提交更改到服务器)操作。
另外,如果使用的是Netbeans等集成开发环境,里面有可能会带有SVN的管理工具,或者支持SVN,可以通过这些开发环境直接将项目导入到svn中。在这里,我将附上我的一些配置文件:
passwd:
eleven:******
meteor:******
syani:******
evergreen:******
其中××××代表密码
[groups]
admin = eleven
developteam = syani, meteor, evergreen
svnaccessfile:
#管理员和开发人员都具有读写权限
[/]
@admin = rw
danger =
@developteam = rw
2009年4月18日星期六
实现ADF应用集成
本文主要描述在ADF开发中如果实现不同应用之间的集成。
场景:
在开发过程中,为了降低开发难度和风险,有时会采用在基础框架应用外新建应用进行开发,待新应用开发完成后,再将其集成到基础框架应用中。这里将以howtoappsintegration1和howtoappsintegration2两个应用为例,说明如何实现系统之间的集成。
实现
1、分别创建新应用howtoappsintegration1和howtoappsintegration2,两个应用都有Model项目和ViewController项目。
2、我们将howtoappsintegration2应用集成到howtoappsintegration1应用中。在howtoappsintegration1应用中打开howtoappsintegration2应用的Model项目,这里名为Model2。此时,在howtoappsintegration1应用中,应该包含Model,Model2和ViewController三个项目,由于在一个应用中只能包含一个ViewController项目(多个ViewController项目Runtime时会报异常)。
3、修改howtoappsintegration1中的ViewController项目的Dependencies,同时依赖于Model和Model2两个项目,在Data Control面板中可以看到包含两个Data Control。
4、在完成了上述步骤后,我们就可以开始将ViewController项目进行合并。打开两个应用所在的文件夹,首先拷贝howtoappsintegration2应用的task flow到howtoappsintegration1的对应目录下(一般task flow存在于public_html中的WEB-INF文件夹中),在这里为app2-task-flow.xml。
5、在Jdeveloper中刷新Application Navigator面板,可以看到该task flow已经存在于对应目录下,打开该task flow。发现该task flow中的页面包含叉号,说明页面出错或不存在,这里是由于不存在,点开该task flow的source,查看该页面在howtoappsintegration2应用的存放目录。
<?xml version="1.0" encoding="UTF-8" ?> <adfc-config xmlns="http://xmlns.oracle.com/adf/controller" version="1.2"> <task-flow-definition id="app2-task-flow"> <default-activity>Jobs</default-activity> <view id="Jobs"> <page>/Jobs.jspx</page> </view> </task-flow-definition> </adfc-config> |
6、通过步骤5我们发现该页面直接存在于其public_html目录下,拷贝该页面到howtoappsintegration1应用中,在这里也拷贝到了public_html目录下。完成后刷新Jdeveloper的刷新Application Navigator面板,此时再次查看app2-task-flow.xml的source,发现错误消失。
7、在howtoappsintegration1应用中打开上步中拷进来的页面,即Jobs.jspx,点击其Source,发现有非常多的警告,查看后发现,确实了页面的绑定信息,即缺少了页面对应的PageDef文件(如果页面使用了模板,还需要根据实际情况修改模板信息或删除模板)。
8、找到howtoappsintegration2应用中Jobs.jspx页面绑定文件,一般在adfmsrc目录下,这里名为JobsPageDef.xml,将其拷贝到howtoappsintegration1应用的对应目录下。完成后刷新Jdeveloper的刷新Application Navigator面板,此时再次查看Jobs.jspx页面的source,发现警告没有消失,此时虽然PageDef已经存在于该应用中,但是由于没有在DataBindings.cpx中指定页面和页面绑定信息的关联信息,因此页面仍然无法找到其绑定信息。
9、在howtoappsintegration1应用中打开DataBindings.cpx文件,我们直接修改其Source。需要修改的地方主要有:
(1)dataControlUsages:定义dataControl信息
(2)pageDefinitionUsages:定义页面绑定信息
(3)pageMap:定义页面和页面绑定的关联信息
在这里将该文件进行如下修改:
<?xml version="1.0" encoding="UTF-8" ?> <Application xmlns="http://xmlns.oracle.com/adfm/application" version="11.1.1.51.88" id="DataBindings" SeparateXMLFiles="false" Package="howto.howtoappsintegration1.view" ClientType="Generic"> <pageMap> <page path="/Employees.jspx" usageId="howto_howtoappsintegration1_view_EmployeesPageDef"/> <page path="/Jobs.jspx" usageId="howto_howtoappsintegration1_view_JobsPageDef"/> </pageMap> <pageDefinitionUsages> <page id="howto_howtoappsintegration1_view_EmployeesPageDef" path="howto.howtoappsintegration1.view.pageDefs.EmployeesPageDef"/> <page id="howto_howtoappsintegration1_view_JobsPageDef" path="howto.howtoappsintegration1.view.pageDefs.JobsPageDef"/> </pageDefinitionUsages> <dataControlUsages> <BC4JDataControl id="AppModuleDataControl" Package="howto.howtoappsintegration1.model.services" FactoryClass="oracle.adf.model.bc4j.DataControlFactoryImpl" SupportsTransactions="true" SupportsFindMode="true" SupportsRangesize="true" SupportsResetState="true" SupportsSortCollection="true" Configuration="AppModuleLocal" syncMode="Immediate" xmlns="http://xmlns.oracle.com/adfm/datacontrol"/> <BC4JDataControl id="AppModuleDataControl1" Package="howto.howtoappsintegration2.model.services" FactoryClass="oracle.adf.model.bc4j.DataControlFactoryImpl" SupportsTransactions="true" SupportsFindMode="true" SupportsRangesize="true" SupportsResetState="true" SupportsSortCollection="true" Configuration="AppModuleLocal" syncMode="Immediate" xmlns="http://xmlns.oracle.com/adfm/datacontrol"/> </dataControlUsages> </Application> |
10、保存,在howtoappsintegration1应用中再次打开Jobs.jspx页面,点击查看source,发现页面绑定信息已经找到(或者通过点击Binding,通过关联链接进而点击查看PageDef信息)。
11、虽然页面文件已经找到,但是在页面的source中仍然存在一些警告信息,这是由于该页面中的属性绑定到了backing scope的managed bean(或称为backingbean)上,此时此managed bean尚未存在于该应用中。根据source中managed bean的名称在howtoappsintegration2应用中的adfc-config.xml中找到该managed bean的路径和名称,将其拷贝到howtoappsintegration1应用的对应目录下(一般存在于src目录下),此时刷新Application Navigator后,查看到该managed bean,务必选中该manged bean,右键点击rebuild,否则在下步中将有可能无法看到该类(如果package的路径不同,有可能需要打开代码手动修改该路径,修改后重新rebuild)。
13、此时再次查看howtoappsintegration1应用中的Jobs.jspx的source,发现绑定到managed bean中属性的信息上的警告消失,此时所有拷贝和修改已经基本完成。
14、保存应用,运行拷贝进来的task flow,进行测试。
最终运行页面:
总结:
应用集成是一个看似容易却相对琐碎和比较容易出问题的环节,所以在进行应用集成的过程中,尽量按照步骤,按部就按地进行,切忌将所有的内容全部拷贝然后再去修改配置,如果是这样的话,出了问题就将非常难以排查,尤其是在需要多人协同开发的项目上(这里建议的最佳实践就是由专人负责应用集成)。一般而言,只要细心,按照步骤进行,是不会有问题的。下面是在集成过程中需要特别注意的几点:
(1)文件一定要拷贝完整
(2)注意library是否正确,数据库连接是否正确
(3)DataBinding.cpx文件修改一定要小心,根据需要注册Data Control到该文件
(4)Managed Bean拷贝完成后一定要注意其Package路径,并进行rebuild
(5)在最终集成到的应用中,一定只能包含一个ViewController项目(Model项目可以有多个)。
(6)如果task flow中有用到了method call,有可能要根据实际情况重新拖拽。
相关代码请查看:
howtoappsintegration.rar
将ADF应用部署到Weblogic
在Jdeveloper 11g中,Oracle已经将Weblogic集成到了IDE中,在使用Jdeveloper 11g进行ADF的开发时,Weblogic也是其默认的部署和运行服务器。同时,在实际应用中,有很多情况下,也需要将ADF部署到Weblogic上,本文主要描述在ADF开发中如何将ADF应用部署到Weblogc。
约定:
1、 Weblogic的域已经存在或使用Jdeveloper默认的Weblogic的域
2、 Weblogic的域在创建时,在“选择域源”步骤中,在“生成一个自动部署的域以支持下列产品”项中勾选了“Application Development Framework”。
3、 将要发布到Weblogic上的应用已经成功创建并完成。
下面我们将部署howtodeploytoweblogic应用到weblogic,这里使用Jdeveloper默认的域。这里仅为部署步骤简介,详细的说明参见文档(Page963 b31974.pdf 第32章 )。
实现
1、 启动Weblogic。如果是通过Jdeveloper打开,可以点击Run-Start Server Instance,若不是通过Jdeveloper打开,可以通过运行脚本。
2、 选择Model项目,双击打开Application Module,点击Configurations,继续选中Local的Configuration,将Connection Type设置成为JDBC DataSource,选择后Datasource Name为java:comp/env/jdbc/howtoDS。
3、 选择ViewController项目,双击点开Project Setting,选择Deployment,删除已经存在的Deployment Profiles,点击New,选择Archive Type为War File,Name为test。
4、 创建WAR后,在Edit War Deployment Profile Properties页面中,选择Web Application’s Context Root为Specify Java EE Context Root,设置为test,点击OK完成。
5、 在应用上点击右键,选择New,在Deployment Profiles的Items中,可以看到只有EAR可用,选择EAR,命名为howtodeploytoweblogic。
6、 在Edit Ear Deployment Profile Properties页面中,选择Application Assembly,选中ViewController.jpr下的test,点击OK完成。
7、 删除原有的Ear,确保此时Deployment Profiles中只有howtodeploytoweblogic,点击OK完成。
8、 在应用上点击右键,点击Deploy,选择howtodeploytoweblogic,进一步选择to EAR file。
9、 发布完成以后记录此时EAR包所在路径,同时登陆Weblogic的管理页面,这里使用Jdeveloper默认域,用户名和密码均为weblogic,url为http://127.0.0.1:7101/console/。
10、登录成功后,首先为应用创建数据源,在域结构中点击 服务-JDBC-数据源,选择新建,进入数据源向导。
10.1、点击新建,名称为howtodeploytoweblogic,JNDI的设置需要和步骤2中的Datasource保持一致,这里为jdbc/howtoDS,数据库类型选择Oracle,驱动使用Oracle’s Driver(Thin) Versions:9.0.1,9.2.0,10,11。
10.2、点击下一步到连接属性设置,完成数据库连接属性,点击下一步显示所有的连接属性,点击测试配置,确定连接测试成功。
10.3、继续点击下一步到选择目标,勾选将要应用该数据源的服务器,然后点击完成,消息提示“已激活更改,不需要重新启动”。
10.4、选中刚创建成功的数据源,点击 配置-连接缓冲池,选择高级,勾选保留时测试连接项,继续选择监视,测试数据源,若测试成功,说明数据源配置成功。至此,数据源配置完成。
11、登录成功后在域结构中点击部署,此时在右边可以看到所有已部署在服务器上的应用和库。点击安装,进入安装向导。
11.1、输入刚才EAR包的路径,选中该EAR。
11.2、点击下一步,Weblogic会自动判断将要部署的内容为应用还是库,这里为应用。
11.3、继续点击下一步,根据需要进行设置,这里使用默认设置,直接点击完成。提示部署成功,即可通过浏览器进行访问。url为http://127.0.0.1:7101/test/faces/Main.jspx需要注意的是,这里url地址中的test,对应的是在设置war profiles中的Web Context Root。
最终运行结果:
相关代码请查看:
howtodeploytoweblogic.rar
2009年4月17日星期五
复合LOV的实现
概述
在实际应用中,经常会用到对于同一个属性使用不同LOV,本技巧主要介绍了对于同一属性使用多个LOV的方法,以及不同LOV之间切换的方法。
场景:
1、 定义新员工时,根据员工学历的不同,使用不同LOV选择起薪范围
2、 根据职位不同,LOV中显示的内容也不同或需使用不同LOV显示内容
3、 其他应用场景
下面我们以EmployeesVO中的DepartmentID属性为例,根据员工Salary的不同为该属性添加使用不同LOV,以显示不同内容。
实现
1、创建新应用后,创建Entity Object:EmployeesEO,该EO基于数据库中的Employees表,可以看到其关联(EmpManagerFkAssoc)被自动创建。
2、创建基于1中创建的EO的View Object:EmployeesVO。
3、创建名为EmpManagerFkLink的View Link,在“Selected Source Attribute”和“Selected Destination Attribute”中都选择EmployeesVO中的EmpManagerFkAssoc,点击“OK”完成。
4、创建DepartmentId的LOV数据源VO(DepartmentLOV),并设置DepartmentId属性为Key Attibute,其SQL如下:
SELECT Departments.DEPARTMENT_ID,
Departments.DEPARTMENT_NAME,
Departments.MANAGER_ID,
Departments.LOCATION_ID
FROM DEPARTMENTS Departments
5、为EmployeesVO中的DepartmentId属性添加两个LOV,其List Data Source均选择为前面创建的DepartmentsLOV(DepartmentsLOV1),List Attribute为DepartmentId,List Return Values使用默认,即DepartmentId-DepartmentId,在UI Hints中设置不同的显示项,分别如下:
LOV_DepartmentId:
LOV_DepartmentId1:
6、为DepartmentId属性添加LOV Swicher,单击选中该属性,在“List of Values: DepartmentId”中设置List Type UI Hint为Input Text with List of Values,在List of Values Switcher点击新建,命名为lovSwitcher,在“Edit Attribute: lovSwitcher”面板中选择Value Type为Expression,添加Value内容,即Groovy脚本,以判断使用哪个LOV,在这里根据Salary进行判定(若Salary>10000,使用LOV_DepartmentId1,若Salary<=10000,使用LOV_DepartmentId)。
Value:
if(Salary != null && (new oracle.jbo.domain.Number(Salary)).intValue() > 10000)
{
return 'LOV_DepartmentId1'
}
return 'LOV_DepartmentId'
7、新建页面,命名为Main,为方便扩展功能,产生出了其Backing Scope的Managed Bean。
7.1、选中并点开“Data Controls”中“AppModuleDataControl”内的EmployeesVO2(与AM中名字相同,不一定为该名),继续点击“Named Criteria”,将All Queriable Attributes拖动到页面中,选择ADF Query Panel with Table,根据需要调整显示属性,完成后确定。
7.2、在“Structure”面板中选择af:table – redId1,双击打开其属性编辑器,选择“Columns”项设置所有属性(除lovSwitcher)的“Component To Use”为输入类型控件。
7.3、保存设置,运行页面。
最终运行结果:
在Search区中在Salary选项中填入9999(<10000),DepartmentId此时使用的LOV是LOV_DepartmentId,显示DepartmentId和DepartmentName两项。
更改Salary为10001,重新查看DepartmentId,发现其显示列数分别为DepartmentId,DepartmentName与ManageId,使用的LOV为LOV_DepartmentId1。
清空Search中内容,使用默认空值进行查询,在Table中继续验证。
相关代码请查看:
howtomultiplelov.rar
ADF 11g Multiple RowSelect on RichTable
- 使用ADF RichTable提供的Multiple RowSelect功能
- 在RichTable中增加列,使用基于VO的Checkbox进行RichTable的行多选
- 在RichTable中增加列,不基于VO进行RichTable的行多选
1.使用ADF RichTable提供的Multiple RowSelect
缺点:只能按住键盘Ctrl键或Shift键通过鼠标进行多选,用户操作不直观
步骤:设置RichTable的属性,将RowSelection设为multiple,并将SelectedRowKeys设为空,即可在后台通过如下代码获得选定行的RowKey,进而可以通过在VO上通过对应RowKey得到对应行。
public Boolean getIsChecked() {
//return (Boolean) getAttributeInternal(ISCHECKED);
return getAttributeInternal(ISCHECKED) == null ? false :
(Boolean)getAttributeInternal(ISCHECKED);
}
补充:为什么将SelectedRowKeys置为空
修改之前SelectedRowKeys值为#{bindings.EmployeesVO1.collectionModel.selectedRow},该EL表达式表明之前该Table的SelectedRowKeys绑定到了对应VO的selectedRow,但client端的状态改变并不能实时的提交到Server端,以至于当此绑定存在时,取到的是Server端存储的selectedRow而非client端当前的selectedrow。
2.在RichTable中增加列,使用基于VO的Checkbox进行RichTable的行多选
优点:使用checkbox的方式提供选择,代码复杂度中等
缺点:必须修改每一个需要使用该多选方式的RichTable对应的VO
步骤:
- 在VO添加非数据库项IsChecked,设置其Type为Boolean,Updateable为Always
- 为该VO生成ViewRowImpl.java,并修改IsChecked的get方法
public Boolean getIsChecked() {
//return (Boolean) getAttributeInternal(ISCHECKED);
return getAttributeInternal(ISCHECKED) == null ? false :
(Boolean)getAttributeInternal(ISCHECKED);
} - 将VO拖入页面创建RichTable,修改IsChecked列,将标签改为<af:selectBooleanCheckbox>,并将其Autosubmit/Immediate属性设为true,并在header中拖入另一个SelectBooleanCheckbox
- header里的Checkbox不能添加ValueChangeListener,如果已经添加,需要将ValueChangeListener重置为Default(空)。为Header里的Checkbox创建ClientListener和ServerListener,分别设置属性如下:
ClientListener
method: mainClientCall
type: click
ServerListener
method: callMBmainmethod
type: onSelectedOrDeselected()
完成后如下 - 在页面转入Source模式,在标签 <af:document... 与 <af:messages... 间加入如下代码
<script type="text/javascript">
<![CDATA[function mainClientCall (event)
{
var currcheckbox = event.getSource();
var selectstatus = currcheckbox.getValue();
//call method in manage bean
AdfCustomEvent.queue(currcheckbox, "callMBmainmethod",{params:selectstatus}, true);
}
]]>
</script>
在页面backingbean中修改onSelectedOrDeselected方法,添加以下代码以实现全选功能。注意修改this.getTable()为你的目标表。public void onSelectedOrDeselected(ClientEvent clientEvent) {
boolean isSelected =
(Boolean)clientEvent.getParameters().get("params");
RichTable rt = this.getTable1();
for (int i = 0; i < rt.getRowCount(); i++) {
JUCtrlHierNodeBinding rowData =
(JUCtrlHierNodeBinding)rt.getRowData(i);
Row row = rowData.getRow();
if (isSelected) {
row.setAttribute("IsChecked", true);
} else {
row.setAttribute("IsChecked", false);
}
}
// Refresh target table state
AdfFacesContext adfContext = AdfFacesContext.getCurrentInstance();
UIComponent refreshComponent = this.getTable1();
if (refreshComponent != null) {
adfContext.addPartialTarget(refreshComponent);
}
}- 可以在AppModel或ManageBean中通过遍历VO判断IsChecked的状态来取出选定行。
3.在RichTable中增加列,不基于VO进行RichTable的行多选
优点:使用checkbox的方式提供选择,不必修改VO
缺点:代码复杂度较高
步骤:
- 在RichTable中插入列,设置宽度(width)为13,RowHeader属性为true,Align属性为Center;在列及列header中分别拖入SelectBooleanCheckBox,设置checkbox的simple属性为true,删除其Text属性中的值。将全选checkbox的ID设置为maincheckbox,单选的checkbox
ID设置为subcheckbox:(参考2.3) - 分别为两个Checkbox创建一组ClientListener/ServerListener,属性设置如下(参考2.4)
MainCheckbox
clientListener
Method: mainClientCall
Type: click
serverListener
Type: callMBmainmethod
Method: mainCheckBoxChecked()
SubCheckbox
clientListener
Method: subClientCall
Type: click
serverListener
Type: callMBsubmethod
Method: subCheckBoxChecked()
在页面转入source模式,复制如下代码至<af: document ...与<af: messages ...标签之间(参考2.5)<script type="text/javascript">
<![CDATA[function mainClientCall (event)
{
var currcheckbox = event.getSource();
var selectstatus = currcheckbox.getValue();
//call method in manage bean
AdfCustomEvent.queue(currcheckbox, "callMBmainmethod",{params:selectstatus}, true);
}
function subClientCall (event)
{
var currcheckbox = event.getSource();
var selectstatus = currcheckbox.getValue();
//call method in manage bean
AdfCustomEvent.queue(currcheckbox, "callMBsubmethod",{params:selectstatus}, true);
}
]]>
</script>- 修改页面对应Manage
bean中的方法,修改mainCheckBoxChecked(),subCheckBoxChecked()方法,添加如下代码public void getSelectedRows(ActionEvent actionEvent) {
System.out.println("Selected Rows"); //debug
System.out.println("******************************************"); //debug
RowKeySet selectedRowsList = this.getMultipleCheckBoxProcess().getSelectedRowsList(this.getResId1());
if (selectedRowsList != null && selectedRowsList.size() != 0) {
for (Object temp : selectedRowsList)
System.out.println("Get Row : " + temp);
}
System.out.println("******************************************"); //debug
}
public void CleanUpStatus(ActionEvent actionEvent) {
this.getMultipleCheckBoxProcess().CleanUpStatus(this.getResId1(), "maincheckbox", "subcheckbox");
}
public void mainCheckBoxChecked(ClientEvent clientEvent) {
Boolean currstatus = (Boolean)clientEvent.getParameters().get("params");
this.getMultipleCheckBoxProcess().mainCheckBoxChecked(this.getResId1(), "subcheckbox", currstatus);
}
public void subCheckBoxChecked(ClientEvent clientEvent) {
Boolean currstatus = (Boolean)clientEvent.getParameters().get("params");
this.getMultipleCheckBoxProcess().subCheckBoxChecked(this.getResId1(), currstatus);
}
public MultipleCheckBox getMultipleCheckBoxProcess(){
FacesContext ctx = FacesContext.getCurrentInstance();
Application app = ctx.getApplication();
MultipleCheckBox curr = (MultipleCheckBox)app.evaluateExpressionGet(ctx, "#{ viewScope.view_MultipleCheckbox}", Object.class);
return curr;
} - 复制MultipleCheckbox.java至目标位置(在Demo中可以找到),在当前所使用的TaskFlow中添加Manage Bean名为view_MultipleCheckbox,Scope为view级别的Bean,指向MultipleCheckbox.java,修改MultipleCheckbox.java中的Package,使其与实际路径相符。
- 注意在适当的时候调用MultipleCheckbox的CleanUpStatus方法,一般在RichTable中数据发生改变时需要调用,如页面存在Query,则需在Query中调用MultipleCheckbox的CleanUpStatus方法。
补充:类MultipleCheckBox中方法说明
- public RowKeySet
getSelectedRowsList(RichTable tartab);
输入参数1:使用多选择Checkbox的RichTable对象
返回参数:选中的行的RowKey - public void setSelectedRowsList(RowKeySet
selectedRowsList, RichTable tartab);
输入参数1:选中行的RowKey
输入参数2:使用多选择Checkbox的RichTable对象 - public void subCheckBoxChecked(RichTable
tartab, Boolean checkStatus);
输入参数1:使用多选择Checkbox的RichTable对象
输入参数2:当前Checkbox的状态
该方法应在多Checkbox RichTable中某行前的Checkbox被选中/反选时调用 - public void mainCheckBoxChecked(RichTable
tartab, String subcheckboxid, Boolean newstatus);
输入参数1:使用多选择Checkbox的RichTable对象
输入参数2:每行前Checkbox的id
输入参数3:当前全选Checkbox的状态
该方法应在全选Checkbox被选中/反选时调用 - public void CleanUpStatus(RichTable
tartab, String maincheckboxid, String subcheckboxid);
输入参数1:使用多选择Checkbox的RichTable对象
输入参数2:全选Checkbox的id
输入参数3:每行前Checkbox的id
该方法用于清除Checkbox的被选状态,通常需要执行查询前均需调用
Demo:
MultipleRowSelect1.rar
MultipleRowSelect2.rar
MultipleRowSelect3.rar
2009年4月16日星期四
Oracle SQL常用函数总结(2)
31、Tanh(arg)
说明:返回双曲线的正切值
例:Tanh(20) 结果为 1
32、Sysdate
说明:取系统当前时间
例:SELECT SYSDATE FROM DUAL;
33、Greatest
说明:取一组数中的最大值,比较字符的编码大小
例:Greatest('A','C','B') 结果为C
34、Least
说明:取一组数中的最小值,比较字符的编码大小
例:Least('A','C','B') 结果为A
35、To_Number
说明:将字符串转换为数字
例:To_Number(‘12345’) 结果为 12345
补充:这里的字符串必须由数字组成,否则不能转化
36、Last_Day(Sysdate)
说明:返回该月的最后一天的当前时刻
例:Last_Day(Sysdate) 结果为 2008-10-31 15:28:20
37、To_Char(date,’format’)
说明:将时间转换为指定格式
例:To_Char(Sysdate, ‘yyyy/mm/dd hh24:mi:ss’) 结果为 2008/10/07 15:34:13
38、To_Date(string,’format’)
说明:将string根据给定的时间匹配方式转换成为时间类型
例:To_Date('20081007153413','yyyymmddhh24miss') 结果为 2008-10-7 15:34:13
39、Next_Day(date,’dayofweek’)
说明:计算下个星期相同日的日期
例:Next_Day(’07-10月-2008’,’星期二’) 结果为 2008-10-14
40、Add_Months(date,month)
说明:给指定日期加上指定月份
例:To_Char(Add_Months(To_Date('2008,10,07 15:52:00',
'yyyy,mm,dd hh24:mi:ss'),
1),
'yyyy,mm,dd hh24:mi:ss') 结果为 2008,11,07 15:52:00
41、Months_Between(date2,date1)
说明:返回date2-date1的月份
例:Months_Between(Add_Months(Sysdate,1),Add_Months(Sysdate,-1)) 结果为 2
42、New_Time(date,this,that)
说明:返回this时区=that时区的日期和时间
例:SELECT To_Char(Sysdate, 'yyyy.mm.dd hh24:mi:ss') bj_time,
To_Char(New_Time(Sysdate, 'PDT', 'GMT'), 'yyyy.mm.dd hh24:mi:ss') los_angles
FROM DUAL; 结果为 2008.10.07 16:01:46 2008.10.07 23:01:46
43、RowIdToChar(rowid)
说明:将rowid转换成字符
例:RowIdToChar('AAAAfKAACAAAAEqAAA') 结果为 AAAAfKAACAAAAEqAAA
44、CharToRowId(char)
说明:将字符转换成rowid
例:CharToRowId(‘AAAAfKAACAAAAEqAAA’) 结果为 AAAAfKAACAAAAEqAAA
45、Convert(c,dset,sset)
说明:将原字符串c由原字符集sset转到目标字符集dset
例:Convert('Eleven.Xu 徐','we8hp','f7dec') 结果为 Eleven.Xu e>
46、HexToRaw(arg)
说明:将arg从16进制转换成为raw类型数据
例:HexToRaw(‘123’) 结果为 0123
47、RawToHex(arg)
说明:将arg从raw类型数据转成为16进制数据
例:RawToHex(‘0123’) 结果为 30313233
48、To_Multi_Byte(arg)
说明:将arg从单字节字符转换成为多字节字符
例:To_Multi_Byte(‘hello’) 结果为hello
49、User
说明:返回当前用户用户名
例:SELECT User FROM DUAL 结果为 APPS
50、UID
说明:用户的唯一标识
例:SELECT du.username, du.user_id
FROM dba_users du
WHERE du.username = (SELECT User FROM DUAL);
51、Soundex
说明:返回一个与给定字符串相同读音的字符串
例:略
52、Userenv(arg)
说明:若arg为 ‘isdba’,表示判断当前用户是否为DBA
若arg为 ‘sessionid’,表示判断当前sessionid
若arg为 ‘entryid’,表示会话人口id
若arg为 ‘instance’,表示当前instance标志
若arg为 ‘language’,表示当前环境语言
若arg为 ‘lang’,表示当前环境语言缩写
若arg为 ‘terminal’,表示当前终端或机器的标志
例:Userenv('isdba') 结果为 FALSE
Userenv('sessionid') 结果为 1416799
Userenv('entryid') 结果为 0
Userenv('instance') 结果为 1
Userenv('language') 结果为 SIMPLIFIED CHINESE_CHINA.UTF8
Userenv('lang') 结果为 ZHS
Userenv('terminal') 结果为 HAND-ELEVEN
53、VSize(arg)
说明:返回arg的字节数
例:VSize(‘1234’) 结果为 4
54、Decode(value,if1,then1,if2,then2,if3,then3,...,else)
说明:如果value等于if1时,DECODE函数的结果返回then1,...,如果不等于任何一个if值,则返回else。
例:SELECT Decode(Sign(10-11),-1,10,11) FROM DUAL;(取最较小值)结果为 10
补充:详细解释请参考http://blog.csdn.net/elevenXL/archive/2008/10/08/3031647.aspx
说明:根据arg2规定的精度截取arg1
例:SELECT Trunc(111.112233,2) FROM DUAL; 结果为 111.11
SELECT Trunc(111.112233,-2) FROM DUAL; 结果为 100
56、Round(arg1,arg2)
说明:根据arg2规定的精度对arg1按四舍五入进行截取
例:SELECT Round(111.41,1) FROM DUAL; 结果为 111.4
SELECT Round(111.45,1) FROM DUAL; 结果为 111.5
57、BFileName(dir,fullfilename)
说明:指定外部dir目录下的fullfilename文件,在Insert语句中使用较多
例:略
58、initcap(arg)
说明:将arg中的首字母大写
例:略