Andrej Koelewijn

12/29/2003

JHeadstart 10G (9.0.4.5)

Filed under: — andrejk @ 8:31 pm

Some days ago Oracle released JHeadstart 10G. You can download an evaluation copy from otn.

JHeadstart is a generator for J2EE applications. You basically specify the application in an xml file and jHeadstart will generate a struts/jsp/uix/bcj4 application. Alternatively you can use Oracle Designer, and generate an application based on the contents of your repository.

Eventhough it’s version number might suggest otherwise, this release works best with jdeveloper 9.0.3., not with JDeveloper 10g preview, as it doesn’t use ADF. The next version of jHeadstart will support ADF.

JHeadstart is the first Java generator to have been succesfully used in the yearly RAD-Race. This is a yearly competition organized by Software release Magazine. Competitors have to create a complete administrative database application in only 2 days. This year the JHeadstart team finished 4th. 10 teams entered the competition, of which some already gave up on the first evening, because they couldn’t meet the requirements. The requirements consisted of some data entry screens, data loading functionality, reporting and web services. And all this in only 2 days.

The winning team, EDcubed, generated C++ code, but their tool can also generate Cobol or Java. Number two generated a proprietary 4GL. Number three generated .net code, and the Oracle team generated J2EE code.

What surprises me is that no Oracle Designer teams entered, but maybe this is caused by the fact that Oracle Designer is less suited for generating Html data entry applications and web services functionality.

J2SDK 1.5 alpha

Filed under: — andrejk @ 1:50 pm

You don’t need to be a javalobby member to download J2SDK 1.5.0 alpha.

Eric Gamma on the future of Eclipse

Filed under: — andrejk @ 1:48 pm

Open Enterprise Trends has an article where Eric Gama outlines the future of eclipse. There’s a lot of focus on improving Eclipse as a framework, but there seems to be less focus on improving productivity for the java developer using Eclipse as a java IDE.

12/24/2003

Use rownum instead of scrollable resultsets

Filed under: — andrejk @ 11:06 am

There are some interesting threads
on AskTom discussing the best method to query a page of records (on Oracle), say records 20 to 30 of a query. Tom Kyte’s advice is to use rownum in the where clause to retrieve only the required rows.

In java there’s another way to query a page of records. You can use a scrollable resultset. You position the cursor on the first record required using absolute(), and then you loop through the number of records you need. Here’s an example.

stmt = 
    conn.prepareStatement(
       "select * from big_table order by object_name",
        ResultSet.TYPE_SCROLL_INSENSITIVE,
        ResultSet.CONCUR_UPDATABLE);
stmt.setFetchSize(pagesize);
rset = stmt.executeQuery();
rset.absolute(start);

The approach adviced by tom kyte is as follows:


stmt =
  conn.prepareStatement(
                        "select * "
                        + "from ( select q.* "
                        + "       ,      rownum rnum "
                        + "       from ( select * "
                        + "              from   big_table "
                        + "              order  by object_name "
                        + "            ) q "
                        + "       where rownum <= ? "
                        + "     ) "
                        + "where rnum >= ? ");
stmt.setInt(1, end);
stmt.setInt(2, start);
rset = stmt.executeQuery();

The first method is portable, the second is only useable on Oracle.
So, if both perform the same i would prefer to use the scrollable
resultset. This, however is not the case as can be demonstrated using
tkprof. I ran both statements 10 times, querying the first 10 records
with the scrollable resultset, the next with the rownum approach, then
again 10 with the scrollable resultset, etc. In total i queried 200
records, so both statements where created 10 times. Here’s the output
from tkprof:


select * 
from
 big_table order by object_name


call     count       cpu    elapsed       disk      query    current        rows
------- -----  -------- ---------- ---------- ---------- ----------  ----------
Parse       10      0.01       0.00          0          0          0           0
Execute     20      0.00       0.00          0          0          0           0
Fetch      110     17.07     287.51     100445      30140       1040        1100
------ -----  -------- ---------- ---------- ---------- ----------  ----------
total      140     17.08     287.52     100445      30140       1040        1100

Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 5 

Rows     Row Source Operation
-----  ---------------------------------------------------
     20  SORT ORDER BY
 221004   TABLE ACCESS FULL BIG_TABLE

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

select *
from
 ( select q.
        ,      rownum rnum        from ( select *              
  from   big_table               order  by object_name             ) q       
  where rownum <= :1      ) where rnum >= :2


call     count       cpu    elapsed       disk      query    current        rows
------ -----  -------- ---------- ---------- ---------- ----------  ----------
Parse       10      0.00       0.00          0          0          0           0
Execute     10      0.00       0.00          0          0          0           0
Fetch       20      6.11      18.76      30074      30140          0         100
------ -----  -------- ---------- ---------- ---------- ----------  ----------
total       40      6.11      18.76      30074      30140          0         100

Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 5 

Rows     Row Source Operation
------  ---------------------------------------------------
     10  VIEW 
     20   COUNT STOPKEY
     20    VIEW 
     20     SORT ORDER BY STOPKEY
 221004      TABLE ACCESS FULL BIG_TABLE

As you can see from the output of tkprof, the rownum approach is better
for performance. Half the number of executes, and a lot less fetches.
So if you are using an Oracle database, and you’re not going to use
anything else in the future, use the rownum method.

12/20/2003

Eclipse 3.0 M6

Filed under: — andrejk @ 8:28 pm

Eclipse 3.0 milestone build M6 was released yesterday. New and noteworthy: Platform, JDT

12/18/2003

Persistence layer poll on OTN

Filed under: — andrejk @ 8:45 am

Steve muench links to a poll on the jdeveloper page on OTN. They want to know what persistence layer people are using. It’s a surprisingly small list. I’m currently using hibernate, but i can’t vote for it, as it’s not on the list.

12/3/2003

JSP 2.0 sql tag to call stored procedures

Filed under: — andrejk @ 8:28 pm

As i mentioned some time ago, i’ve created a small jsp application using jstl. I found that the sql tags part of jstl really enable you to quickly create small web applications. Ofcource this architecture isn’t really fit for large websites, but for small internal apps, and for prototyping it’s ok.


One thing i missed was a tag to call a stored procedure, preferable in a separate thread as i needed to start some long running stored procedures. I couldn’t find any taglibs which offered this.


But with jsp 2.0 it’s really easy to implement new tags. You create a .tag file under WEB-INF/tags/. A tag file is basically a jsp fragment. I created the following file: WEB-INF/tags/sql/call.tag. So now i can use it as follows:


<sql2:call dataSource="jdbc/db"> <jsp:attribute name="sql"> begin my_package_pkg.my_long_running_sp(?); end; </jsp:attribute> <jsp:attribute name="param1"> <c:out value="${param.my_param}"/> </jsp:attribute>
</sql2:call>


Here’s the tag file:


<%@ tag dynamic-attributes="param" %>
<%@ attribute name="sql" %>
<%@ attribute name="dataSource" %>

final java.util.Map params =

(java.util.Map) pageContext.getAttribute("param");
final javax.servlet.jsp.JspWriter _out = out;
final javax.servlet.ServletContext _app = application;

java.lang.Thread thread = new Thread() {

public void run() { try { javax.naming.Context ctx = new javax.naming.InitialContext(); if (ctx == null) throw new Exception("No Context"); javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup( "java:comp/env/" + dataSource); if (ds != null) { java.sql.Connection conn = ds.getConnection(); try { if (conn != null) { java.sql.CallableStatement stmt = conn.prepareCall(sql.replace((char)13,' ').replace((char)10,' '); java.util.Map p = params; java.util.Set keys = p.keySet(); java.util.Iterator keyIter = keys.iterator(); int pc = 1; while (keyIter.hasNext()) { String key = (String) keyIter.next(); if (key.startsWith("param")) { stmt.setString(pc, (String) p.get(key)); pc++; } } stmt.execute(); conn.close(); conn = null; } } finally { if (conn != null) { conn.close(); } } } } catch (Exception e) { try { _app.log("call.tag: Error: " + e.getMessage()); } catch (Exception e2) { } } }
}; //thread

thread.start();


I think tag files may be the best feature of jsp 2.0

Powered by WordPress