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 procedures
12. DQL, DML & DDL: supports the full syntax of the underlying database manager.
13.
14. SQLJ Syntax Iterators #sql [context] iterator <it_name> implements sqlj.runtime.ForUpdate, sqlj.runtime.Scrollable with(holdability=… sensitivity=… updateColumns=“…”) { <JavaDataType> <field_name>, … } The standard defines datatypes mappings between Java and SQL: ex. INTEGER is mapped to BigDecimal, not to BigInteger!
15. 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.
16. How do we manage library dependencies Pom.xml Manual install <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 Not everything is in the standard repositories!
17. 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>
18. 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() ); }
20. Maven: execution #!/bin/bash mvn 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
21. Data Studio Developer Screencasts IDE_SQLJsupport.avi IDE_sqljassist.avi IDE_SQLJ_errors.avi IDE_debug.avi Deleted from Presentation: too heavy
22. 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!
23. The measure int 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;
24. 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;
25. 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;