sqladria 2009 src
DESCRIPTION
SQLAdria 2009 presentation's slides about our experience with Maven and SQLJ. It delves in some details about SQLJ and performance comparion between SQLJ and JDBC with prepared statements. It also shows surprising results for what concerns performances of (DB2) SQL PL proceduresTRANSCRIPT
SQLJ for DevelopersAndrea ParrilliOracle SQL Expert, Developer
Mvn: thanks to Damjan Kumar
22
Topics
• What is SQLJ;• Short SQLJ syntax introduction;• Equivalence between SQLJ and JDBC;• SQLJ on DB2 using Data Studio Developer, setup, binding, automatic building with maven;
• Performance comparison between SQLJ, unoptimized JDBC, JDBC with PreparedStatements;
• Performance comparison: SQL PL vs. Java
33
What is SQLJ
• SQLJ is an extension of Java language meant to used with a preprocessor to naturally embed SQL statements in Java code.
• It is specified by ISO/IEC in module SQL/OLB to support portability.
• The SQLJ preprocessor produces JDBC code with precompiled prepared statements.
44
What is a Preprocessor?
SQLJ#sql [ctx] {INSERT INTO MAPING.maplogVALUES (NEXTVAL FORMAPING.maplog_log_id_seq,CURRENT TIMESTAMP,0,:msg)};
Java
A preprocessor is just a kind of compiler (or rather a macro processor) devoted to translating the hosted languange, in an hybrid syntax code unit, into the host language.
55
The Generated Code
sqlj.runtime.ConnectionContext __sJT_connCtx = ctx; if (__sJT_connCtx == null) sqlj.runtime.error.RuntimeRefErrors.raise_NULL_CONN_CTX(); sqlj.runtime.ExecutionContext __sJT_execCtx = __sJT_connCtx.getExecutionContext(); if (__sJT_execCtx == null) sqlj.runtime.error.RuntimeRefErrors.raise_NULL_EXEC_CTX(); synchronized (__sJT_execCtx) { sqlj.runtime.profile.RTStatement __sJT_stmt = __sJT_execCtx.registerStatement(__sJT_connCtx,
MAPLOG_SJProfileKeys.getKey(0), 2); try { __sJT_stmt.setString(1, msg); __sJT_execCtx.executeUpdate(); } finally { __sJT_execCtx.releaseStatement(); } }
66
SQLJ Syntax• ITERATORS: an iterator represents a result set or a cursor, it supports
positional update/delete, inter-transaction persistence, scrollability and sensitivity attributes.
• DQL, DML & DDL: supports the full syntax of the underlying database manager.
• In the IBM implementation of SQLJ standard the statements are exclusively processed at compile time (the bind process), this means that the host language variables can appear only where a bind parameter in a prepared statement (JDBC or standard SQL’s procedural language extensions EXECUTE … USING) can, thus allowing only static SQL in SQLJ statements. On the contrary Oracle’s implementation allows for dynamic SQL in a very intuitive way but at the same time offers less features for what concerns iterators (this is mainly due to the differences between the two transaction models and the cursors implentations).
77
SQLJ Syntax Single row statements
#sql [context] :(hostVar) = {SELECT single_valueFROM somewhere…};#sql [context] {SELECT f1, f2, …INTO :(hostVar1), :(hostVar2), …FROM … };#sql [context] {DML/DDL with binds as allowed in EXECUTE … USING};
88
SQLJ Syntax Iterators
#sql [context] iterator <it_name> implements sqlj.runtime.ForUpdate,
sqlj.runtime.Scrollablewith(holdability=…
sensitivity=… updateColumns=“…”)
{<JavaDataType> <field_name>,…}
The standard defines datatypes mappings between Java and SQL:ex. INTEGER is mapped to BigDecimal, not to BigInteger!
99
Why Maven?
• Manages library dependencies;• Manages library download and installation;• Manages the build process:
• SQLJ translation of .sqlj files into .java;• Binding .ser files to the database;• Generation of artifacts (.jar, .war, …);
• Execution from command line (calling the main method with the right classpath);
• Maven is Open Source!
Once configured allows for a greater productivity shortening deploy and setup times and it fully integrates with the versioning system in use.
1010
How do we manage library dependencies
<dependency><groupId>com.ibm.db2</groupId><artifactId>db2jcc</artifactId><version>1.0</version>
</dependency><dependency><groupId>jdom</groupId><artifactId>jdom</artifactId><version>1.1</version>
</dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>2.5.6</version>
</dependency>
mvn install:install-file-Dfile=lib/db2jcc.jar-DgroupId=com.ibm.db2-DartifactId=db2jcc-Dversion=1.0-Dpackaging=jar-Dgeneratepom=true
Pom.xml Manual install
Not everything is in the standard repositories!
1111
Maven: SQLJ translation of .sqlj into .java
We use a custom maven plugin (sqlj-maven-plugin) for translation and binding of SQLJ files.
<build> <plugins> <plugin> <groupId>si.srcsi</groupId> <artifactId>sqlj-maven-plugin</artifactId> <version>1.2</version> <executions> <execution> <goals> <goal>sqljex</goal> <goal>sqljcustomize</goal> </goals> <configuration> <sqljDirs> <sqljDir>src/main/java</sqljDir> </sqljDirs> <generatedSourcesDirectory>src/main/java</generatedSourcesDirectory> <generatedResourcesDirectory>src/main/java</generatedResourcesDirectory> <classpath>lib/framework.jar</classpath> <dbUrl>${dbUrl}</dbUrl> <dbUser>${dbUser}</dbUser> <dbPassword>${dbPassword}</dbPassword> <dbCollection>${dbCollection}</dbCollection> </configuration> </execution> </executions> </plugin> </plugins></build>
1212
Maven: SQLJ translation the implementation
public class SqljExMojo extends AbstractSqljMojo{ private File[] sqljFiles; private File[] sqljDirs; public void execute() { ... Set sqljFiles = getSqljFiles(); for ( Iterator i=sqljFiles.iterator(); i.hasNext(); ){ File file = (File) i.next(); generate( file ); } Resource resource = new Resource(); resource.setDirectory( getGeneratedResourcesDirectory().getAbsolutePath() );
mavenProject.addResource( resource ); mavenProject.addCompileSourceRoot( getGeneratedSourcesDirectory().getAbsolutePath() );
}
1313
Maven:artifact generation
<modelVersion>4.0.0</modelVersion><groupId>si.srcsi</groupId><artifactId>diners-mapping-batch</
artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version><name>diners-mapping-batch</name>
1414
Maven: execution
#!/bin/bashmvn exec:java-Dexec.mainClass= “si.src.diners.mapping.batch.IcusBatch" -Dexec.args="2 $1 $2 $3 $2"
Mvn takes care of classpath and environment variables
maven_screencast.avi
1515
Data Studio Developer
• IDE_SQLJsupport.avi• IDE_sqljassist.avi• IDE_SQLJ_errors.avi• IDE_debug.avi
Screencasts
Deleted from Presentation: too heavy
1616
Performance Test SQLJ – JDBC - PreparedStatement
•SQLJ: 16 ms / 102 ms ± 10 ms;•JDBC: 31 ms / 78 ms ± 10 ms;•JDBC with PreparedStatement:
•16 ms / 58 ms ± 15 ms;
Note: smaller is faster. First figures are on a small single valued query the latter are for a 1000 elements iterator
This is coherent with the implementation!
1717
The measureint iterations = 100;long sqljTime = 0;long jdbcTime = 0;long jdbcPreparedTime = 0;long start = 0;String str; //SQLJ#sql [ctx] { select str into :str from sirius.x_testsqlj where id = 3}; start = (new Date()).getTime();for(int i = 0; i < iterations; i++) {#sql [ctx] { select str into :str from sirius.x_testsqlj where id = :(i%6)};}sqljTime = (new Date()).getTime() - start;
start = (new Date()).getTime();Statement stmt = con.createStatement();for(int i = 0; i < iterations; i++) { ResultSet rs = stmt.executeQuery("select str from sirius.x_testsqlj where id = " + (i%6));
rs.next();tr = rs.getString(1);}
jdbcTime = (new Date()).getTime() - start; start = (new Date()).getTime();PreparedStatement ps = con.prepareStatement("select str from sirius.x_testsqlj where id = ?");
for(int i = 0; i < iterations; i++) { ps.setInt(1, i%6); ResultSet rs = ps.executeQuery(); rs.next(); str = rs.getString(1);}ps.close();jdbcPreparedTime = (new Date()).getTime() - start;
1818
Performance comparison: SQL PL vs. Java
for each row in the source: set savepoint; for each destination entity: check destination's business constraints; insert into destination table; if anything is wrong write to message
buffer; if there are warnings in the buffer then flush it to messages table and rollback to savepoint; else commit;
1919
Performance comparison: SQL PL vs. Java Surprise!
Over 10 executions of both implementations, run over a set of test data:
•Java + SQLJ: 8s ± 1s;•SQL PL: 15s ± 1.5s;•SQL PL without error logging: 10s ± 1s;
2020
Q&A