In this article i’m trying to create a very simple reporting application. In my several past projects, i used to do reporting with java swing and jasper report, and im connecting both of them using a simple JDBC and java.sql.Connection. But in recent project, i had to used iBatis Framework for replacing JDBC. So i had to spend several hours finding a workaround on how connecting Jasper with iBatis, but thanks to uncle Google i finally found a very simple but elegant workaround.
Enough with the chit-chat, i’ll show you the code. First, as always, a simple database named “test” and a simple table named “contoh”.
CREATE DATABASE 'test'
USE 'test'
CREATE TABLE `contoh` (
`nama` varchar(30) NOT NULL DEFAULT '',
`alamat` varchar(100) DEFAULT NULL,
PRIMARY KEY (`nama`)
)
next step is creating a java bean for database mapping
package com.edw.bean;
public class Contoh {
private String nama;
private String alamat;
public String getAlamat() {
return alamat;
}
public void setAlamat(String alamat) {
this.alamat = alamat;
}
public String getNama() {
return nama;
}
public void setNama(String nama) {
this.nama = nama;
}
}
and an xml mapping for database queries, i named it contoh.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<sqlMap namespace="contoh" >
<resultMap id="result" class="com.edw.bean.Contoh">
<result property="nama" column="NAMA" columnIndex="1"/>
<result property="alamat" column="ALAMAT" columnIndex="2"/>
</resultMap>
<insert id="insertContoh" parameterClass="com.edw.bean.Contoh" >
insert into contoh (nama, alamat)
values (#nama:VARCHAR#, #alamat:VARCHAR#)
</insert>
<select id="selectAllContoh" resultMap="result">
select nama, alamat
from contoh
</select>
</sqlMap>
and ibatis’ main xml configuration, sqlmapconfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings
useStatementNamespaces="true"
lazyLoadingEnabled="true"
enhancementEnabled="true"
maxSessions="20"
/>
<transactionManager type="JDBC" commitRequired="false">
<dataSource type="SIMPLE">
<property name="SetAutoCommitAllowed" value="false"/>
<property name="DefaultAutoCommit" value="false"/>
<property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
<property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost/test"/>
<property name="JDBC.Username" value="root"/>
<property name="JDBC.Password" value="password"/>
</dataSource>
</transactionManager>
<sqlMap resource="com/edw/sqlmap/contoh.xml"/>
</sqlMapConfig>
next step is creating a simple java class to load all iBatis’ configuration file.
package com.edw.config;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import java.io.IOException;
import java.io.Reader;
/**
*
* @author edw
*/
public class SqlMapConfig {
protected static final SqlMapClient sqlMap;
static {
try {
Reader reader = Resources.getResourceAsReader("com/edw/sqlmap/sqlmapconfig.xml");
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
} catch (IOException e) {
throw new RuntimeException("Fatal Error, ga dapet sqlmapconfignya. Cause: " + e, e);
} catch (Exception e){
throw new RuntimeException("Fatal Error. Cause: " + e, e);
}
}
public static SqlMapClient getSqlMap() {
return sqlMap;
}
}
I create a very simple reporting using JasperReport, i named it Iseng.jrxml and compile it into Iseng.jasper
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="Iseng" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="0"/>
<parameter name="nama1" class="java.lang.String"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="nama" class="java.lang.String"/>
<field name="alamat" class="java.lang.String"/>
<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="56" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="555" height="46"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font size="24"/>
</textElement>
<text><![CDATA[Testing Report]]></text>
</staticText>
</band>
</title>
<pageHeader>
<band height="13" splitType="Stretch"/>
</pageHeader>
<columnHeader>
<band height="34" splitType="Stretch">
<staticText>
<reportElement x="0" y="11" width="100" height="20"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Nama]]></text>
</staticText>
<staticText>
<reportElement x="225" y="11" width="100" height="20"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[Alamat]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="27" splitType="Stretch">
<textField>
<reportElement x="32" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{nama}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="225" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{alamat}]]></textFieldExpression>
</textField>
</band>
</detail>
<columnFooter>
<band height="45" splitType="Stretch"/>
</columnFooter>
<pageFooter>
<band height="54" splitType="Stretch"/>
</pageFooter>
<summary>
<band height="42" splitType="Stretch"/>
</summary>
</jasperReport>
And this is my main Swing class. iBatis generate a List of Beans class for its result set, and im using Jasper’s JRBeanCollectionDataSource class to map iBatis’ resultSet.
package com.edw.ui;
import com.edw.bean.Contoh;
import com.edw.config.SqlMapConfig;
import com.ibatis.sqlmap.client.SqlMapClient;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.view.JasperViewer;
import org.apache.log4j.Logger;
/**
*
* @author edw
*/
public class Main extends JFrame implements ActionListener {
private Logger logger = Logger.getLogger(this.getClass());
private JButton cmdPrint = new JButton("cetak");
private SqlMapClient sqlMapClient = SqlMapConfig.getSqlMap();
public Main() {
Container conn = getContentPane();
conn.setLayout(new FlowLayout());
conn.add(cmdPrint);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cmdPrint.addActionListener(this);
pack();
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == cmdPrint) {
try {
//load report location
FileInputStream fis = new FileInputStream("Iseng.jasper");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fis);
// do query and get list of Contoh
List<Contoh> contohs = sqlMapClient.queryForList("contoh.selectAllContoh");
//fill it in JRBeanCollectionDS
JRBeanCollectionDataSource jrbcds = new JRBeanCollectionDataSource(contohs);
//compile report
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(bufferedInputStream);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap(), jrbcds);
//view report to UI
JasperViewer.viewReport(jasperPrint, false);
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}
}
}
public static void main(String[] args) {
Main main = new Main();
main.setVisible(true);
}
}
and my log4j configuration, i named it log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG,stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%c{1}] %-5p %c:%L - %m%n
this is my NetBeans’ project structure,
dont forget to put your .jasper file in the same folder as your build.xml file,
this is what happen when i run my application, on the background you can see iBatis’ resultSet.
and this is what happen when i push my report button
I hope my article can be useful for others, thank you and have fun using iBatis.
(H)