最近不务正业,跑去帮忙做Birt报表开发了,好久没有做开发了,碰了不少钉子。嘛,有时换换感觉也不错,不过可惜,做完这次我想也不会有什么机会再碰了,我把一些开发时的心得什么的写一下,也算是纪念吧。
1. 要使用dataset的字段,或者 report parameter,都要在页面建立binding(比如把字段拖放到layout上一次),而不需要参数留在layout上(比如建立binding后在layout上删除参数也无妨)
2. 一个dataset,只能和页面上的一个table 一一对应,如果需要report能够多段显示(比如先显示一些数据,然后点击其中一个链接或者按钮,再显示另外的内容)可以考虑用多个dataset。
3. 一般可以放在layout上面做的事:
String,data time,number 的格式
grouping
sorting
鉴于我们通常是写sql从
数据库拿数据,然后放入dataset,在布局在页面上,上面这几项
工作,也可以在sql里面完成,不过为了简化sql,可以把这几种操作通过报表的设置来做,至于那种效率高,我就不知道了哈。
PS:有时也会混用的,比如sql中用sum等函数统计某类数据的总值,然后在页面上分组,再统计总数。那种方便就用那种吧(这句话好废...)
4. grouping 里面不支持group by多个参数,不过把参数用加号连接起来作为group on的条件就行了
5. 如果客户可能会在报表做好之后,在使用时临时加入一些查询条件,可以在report parameter里面定义一个参数(比如叫where)并设置成可见,默认值为1=1,然后加入到你的sql的where子句的最后,那么想临时增加查询条件的时候,就可以通过修改where的值来实现而无须修改报表。
PS:以上做法用于报表是在maximo界面上生成报表,在业务系统里面触发就不行了。不过还是有些用处的,起码提供了一点点扩展性和自由度。
6. birt的开发环境有一点不太友好,有时preview等运行时出错,没有很明确报告错误(特别是组装sql的时候更是),这时可以加上以下语句,直接输出想输出的数据来debug
importPackage( Packages.java.io);
out = new PrintWriter( new FileWriter( "d:/events.txt", true ) );
out.println( sqlText);
out.close();
适用于dataset,layout中的控件的各种方法,还有能够使用Expression Builder的地方
7. birt的各部分的运行顺序
我在dataset,layout控件,report的各个方法中加入debug code,试了才知道,运行顺序和想象中的不同。
// report 自身的方法
initialize()
// 运行设置在layout上控件的处理方法
onPrepare()
onPrepare()
// data set 的方法,取数据,把数据塞入dataset的变量中
beforeOpen()
describe()
open()
fetch()
// 设定layout中的属性,比如 visibility,format,group 等
success - visibility()
updated: false
success - onCreate()
failed - visibility()
updated: false
failed - onCreate()
// data set 的方法,收尾工作
beforeClose()
close()
另,如果想定义一些用于全局的变量,可以定义在report 的 initialize() 方法里面,后面要使用的话就可以直接使用了。
8. 碰上一些诸如在生成的report中点击链接更新数据库数据等,可以在dataset里面用以下代码,自己创建一个独立的statment来完成insert,update,delete等操作。
updateTxn = MXReportTxnProvider.create(this.getDataSource().getName());
updateStmt = updateTxn.createStatement();
updateStmt.setQuery("update table"
+ " set value = 'aaa'"
+ " where id = 1";
updateTxn.save();
updateTxn = null;
----------------
一些常用有用的sql 语句(用于oracle):
to_date(trunc(add_months(sysdate,-1),'MM'),'yyyy-mm-dd')
// 上个月的第一天
to_date(trunc(sysdate, 'MONTH')-1,'YYYYMMDD')
// 上个月的最后一天
-----------------
oracle function/storage procedure debug 用:
set serveroutput on; (命令窗口用,打开下面这个命令的输出)
dbms_output.put_line(变量名或常量); (写入function和存储过程中,在命令窗口运行时会输出结
果)
------
要传入的参数个数不确定的function的写法, (先使用传入的参数构造sql语句,后面再用游标打开
)
例子:
DECLARE
sqlstr VARCHAR2(500):= 'select * from table_1 where table_date >=
to_date('''||param_1||''',''yyyy-mm-dd'') and table_1.id in ('||param_2||')';
type my_cursor is ref cursor; --声明REF CURSOR
n_date_cursor my_cursor; --定义REF CURSOR游标的变量
BEGIN
dbms_output.put_line(sqlstr); --输出sqlstr的值到控制台
open n_date_cursor for sqlstr; --打开游标
(下面对数据的处理略)