Pages

Wednesday, December 1, 2010

Spring - TIBCO - JMS Integration - Asynchronous Approach

In Synchronous approach we used <jms:outboundGateway> in Asynchornous approach we will use <jms:outbound-channel-adapter> and <jms:message-driven-channel-adapter>:

Here is your messaging xml configuration should look like:

    <channel id="outboundMessageChannel">    </channel>
    <channel id="inboundMessageChannel">    </channel>
    <channel id="preMarshalledMessageChannel"/>
    <channel id="unMarshalledMessageChannel"/>


    <jms:outbound-channel-adapter id="jmsMessageOut"
                                  channel="outboundMessageChannel"
                                  jms-template="jmsTemplate"/>


    <si-xml:marshalling-transformer id="marshallerWithPoller"
                                    input-channel="preMarshalledMessageChannel"
                                    output-channel="outboundMessageChannel"
                                    marshaller="jaxbMarshaller"
                                    result-transformer="resultToStringTransformer"/>


    <si-xml:unmarshalling-transformer id="defaultUnmarshaller"
                                      input-channel="inboundMessageChannel"
                                      output-channel="unMarshalledMessageChannel"
                                      unmarshaller="jaxbMarshaller"/>


    <jms:message-driven-channel-adapter id="jmsMessageIn"
                                        channel="inboundMessageChannel"
                                        destination="messageToStoreReplyQueue"
                                        connection-factory="connectionFactory"
            />


    <service-activator id="testMessageEndPoint" input-channel="unMarshalledMessageChannel"
                       method="handleMessageResponse" auto-startup="true">

    <beans:bean class="com.test.ResponseService"/>
    </service-activator>


To listen your responses you should create the service-activator class which is "ResponseService" and when ever there is a message in "unMarshalledMessageChannel" your service activators method "handleMessageResponse" will be invoked with appropriate unmarshalled message.

For total configuration refer to my other post - http://myjavatechnologies.blogspot.com/2010/11/spring-integration.html

Happy Integration!

Monday, November 29, 2010

Linux Commands Reference

How to view simple text files in Linux ?

Command: Cat file_name (This is a nice way to view short files that fit on your screen.)

Command: less file_name (If the files are so long that they don't fit on your screen, less automatically paginates the file, you can use Page Up and Page Down keys to moves through the file and type "q" to quit the file.

How to clear the screen in Linux ?

Command: clear

Wednesday, November 17, 2010

Spring - TIBCO - JMS Integration - Synchronous Approach

Here I am going to provide how to use Spring Integration with JMS and TIBCO synchrnously.

For simplicity I divided into 2 different XML files called as :

- tibcoContext.xml and
- messagingContext.xml,

These both files should be imported in your spring applicationContext.xml (or) what ever name given in your project.

The namespaces for tibcoContext.xml goes here:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:integration="http://www.springframework.org/schema/integration"
       xmlns:jms="http://www.springframework.org/schema/integration/jms"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:stream="http://www.springframework.org/schema/integration/stream"
       xmlns:si-xml="http://www.springframework.org/schema/integration/xml"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/integration
                           http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
                  http://www.springframework.org/schema/integration/jms
                  http://www.springframework.org/schema/integration/jms/spring-integration-jms-1.0.xsd
                  http://www.springframework.org/schema/context
                  http://www.springframework.org/schema/context/spring-context.xsd
                  http://www.springframework.org/schema/integration/stream
                  http://www.springframework.org/schema/integration/stream/spring-integration-stream-1.0.xsd
                  http://www.springframework.org/schema/integration/xml
                  http://www.springframework.org/schema/integration/xml/spring-integration-xml-1.0.xsd">

The namespaces for messagingContext.xml goes here:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:jms="http://www.springframework.org/schema/integration/jms"
             xmlns:stream="http://www.springframework.org/schema/integration/stream"
             xmlns:si-xml="http://www.springframework.org/schema/integration/xml"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/integration
                           http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
                           http://www.springframework.org/schema/integration/jms
                           http://www.springframework.org/schema/integration/jms/spring-integration-jms-1.0.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/integration/stream
                           http://www.springframework.org/schema/integration/stream/spring-integration-stream-1.0.xsd
                                 http://www.springframework.org/schema/integration/xml
                                 http://www.springframework.org/schema/integration/xml/spring-integration-xml-1.0.xsd ">

Coming to configuration in tibcoContext.xml file:

Step 1: You need the below connection factory in order to connect to your EMS server:

<bean id="tibConnectionFactory" class="com.tibco.tibjms.TibjmsQueueConnectionFactory">
        <property name="serverUrl" value="tcp://localhost:7222"/>
        <property name="userName" value=""/>
        <property name="userPassword" value=""/>
</bean>


<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <property name="targetConnectionFactory" ref="tibConnectionFactory"/>
        <property name="sessionCacheSize" value="10"/>
        <property name="cacheProducers" value="true"/>
        <property name="cacheConsumers" value="true"/>
 </bean>


Step 2: Configure the Queue where you need to send the messages:

<bean id="senderQueue" class="com.tibco.tibjms.TibjmsQueue">
        <constructor-arg value="jms/tibcoSenderQueue"/>
</bean>


Step 3: Configure the Jaxb Marshaller to Marshal and unmarshall the messages you would like to send and receive:

<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="classesToBeBound">
            <list>
                <value>com.test.Test1</value>
                <value>com.test.Test2</value>
            </list>
        </property>
</bean>


Step 4: Configure the transformer to convert your payload result to String:

<bean id="resultToStringTransformer"
          class="org.springframework.integration.xml.transformer.ResultToStringTransformer"/>


Step 5: The last and final step in your tibcoContext.xml is to configure the Gateway to send and recieve the Messages:

    <integration:gateway id="dynamicQueryMessageGateway"
                         default-request-channel="senderChannel"
                         service-interface="com.test.ISenderGateway"/>

     <integration:gateway id="dynamicQueryReplyGateway"
                         default-reply-channel="marshaledRecieverChannel"
                         service-interface="com.test.IRecieverGateway"/>


Now We need to create the above gateway interfaces in our code which looks like below:

@Service("senderGatewayService")
public interface ISenderGateway {

    @Gateway(requestChannel = "senderChannel")
    public void sendMessage(@Header("requestType") String requestType, TestOb ob);
}


@Service("receiverGatewayService")
public interface IRecieverGateway {

    @Gateway(replyChannel = "marshaledRecieverChannel", replyTimeout = 5000)
    public ResultOb recieveMessage();

}

Now here the configuration of messagingContext.xml file:

Step 1: Create Approprate required channels:

<channel id="senderChannel"/>
<channel id="marshaledSenderChannel"/>

<channel id="recieverChannel"/>
<channel id="marshaledRecieverChannel">
        <queue/>
</channel>


Step 2: Create Marshaler on SenderChannel:

<si-xml:marshalling-transformer id="defaultMarshaller"
                                    marshaller="jaxbMarshaller"
                                    input-channel="senderChannel"
                                    output-channel="marshaledSenderChannel"
                                    result-transformer="resultToStringTransformer"/>


Step 3: Create JMS outbound gateway on marshaledSenderChannel which holds the results after marshaling:

 <jms:outbound-gateway id="outBoundGateway"
                          request-channel="marshaledSenderChannel"
                          request-destination="senderQueue"
                          connection-factory="connectionFactory"
                          reply-channel="recieverChannel"/>


Step 4: Create unmarshaler on the receiverChannel:

<si-xml:unmarshalling-transformer id="defaultUnmarshaller"
                                      input-channel="recieverChannel"
                                      output-channel="marshaledRecieverChannel"
                                      unmarshaller="jaxbMarshaller"/>


Here we finished all the required configuration for sending and recieving jms messages using spring integration in Synchronous way.

Client code to test the above:

@Autowired
    private ISenderGateway senderGateway;


@Autowired
    private IReceiverGateway receiverGateway;


public void testSynchronousMessaging() {
        try {
                      
            senderGateway.sendMessage("requestType", testOb);

            System.out.println(receiverGateway.recieveMessage());
        } catch(Exception e) {
            e.printStackTrace();
        }

}

Any comments, improvments or suggetions are welcome.

Spring - Annotation Based Spring MVC

Assuming that the student knows basic web application structure and all the configuration files required for Basic web application.
Assuming that the student knows Servlets.

To create Annotation based Spring MVC web application please follow the below steps:

Step 1 : Update your web.xml file with following configuration:

    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

DispatcherServlet - Spring's Web MVC framework is designed around a DispatcherServlet that dispatches requests to handlers, with configurable handler mappings, view resolution, locale and theme resolution as well as support for upload files.
A central servlet that dispatches requests to controllers and offers other functionality facilitating the development of web applications.
Is an expression of the “Front Controller” design pattern.

It is completely integrated with the Spring IoC container and as such allows you to use every other feature that Spring has.


The framework will, on initialization of a DispatcherServlet, look for a file named [servlet-name]-servlet.xml in the WEB-INF directory of your web application and create the beans defined there.

Step 2 : Create spring-mvc-servlet.xml under WEB-INF directory. (Observe that the file name should start with servlet-name of the DispatcherServlet-servlet.xml.)

Step 3 : The Basic spring-mvc-servlet.xml looks like below:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation=
               "http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd">

</beans>

Step 4 : spring-mvc-servlet.xml file will contain all of your Spring Web MVC-specific components (beans). The exact location of this configuration file can be changed via a DispatcherServlet initialization parameter. You can specify that in web.xml like below:

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:/spring/spring-context.xml</param-value>
    </context-param>

Step 5 : Just as with any other view technology you're integrating with Spring, for JSPs you'll need a view resolver that will resolve your views. The most commonly used view resolvers when developing with JSPs are the InternalResourceViewResolver and the ResourceBundleViewResolver.

Add the below configuration in your spring-mvc-servlet.xml file: (I am using InternalResourceViewResolver here in this example)

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

Step 6 :  Here as we are going to use annotations instead of configuring our Controllers in xml files, we also need to add the following configuration in spring-mvc-servlet.xml file, so that container scans all the controller components at the initialization of DispatcherServlet and they will be available.

    <context:component-scan base-package="com.sritech.samples">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

Step 7 : Your web application lib directory also need the following spring jars:

spring.jar
spring-webmvc.jar
commons-logging.jar


These jars will be deployed to the server and they are also used during the build process.

The above configuration allows your DispatcherServlet to scan for all the controllers in the specified package (Ex: com.sritech.samples).

All above 6 Steps are one time configuration you have to do to create your annotation based Spring MVC application.

Example 1:- Create Welcome Page using SimpleWelcomeController and Simple JSP.

Step 1 : Create the controller class:

package com.sritech.samples.mvc.example1;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class SimpleWelcomeController {

    @RequestMapping("/example1/welcome.htm")
    public void elementaryGreeter() {
    }
}

The @Controller annotation indicates that a particular class serves the role of a controller. There is no need to extend any controller base class or reference the Servlet API. You are of course still able to reference Servlet-specific features if you need to. The basic purpose of the @Controller annotation is to act as a stereotype for the annotated class, indicating its role. The dispatcher will scan such annotated classes for mapped methods, detecting @RequestMapping annotations.

The @RequestMapping annotation is used to map URLs like '/example1/welcome.htm' onto an entire class or a particular handler method.

Step 2 : Create the JSP.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Welcome to Spring MVC</title>
</head>

<body>
        Hello everyone! Welcome to Spring MVC: Example 1
</body>
</html>

Step 3 : Now create the war file and deploy into your Tomcat Server. (Any Web Server or application Server).

Step 4 : After the application is deployed go the below link:

http://server-name:portNumber/spring-mvc-samples/example1/welcome.htm

Step 5 : You will be seeing the following output on your screen:

Welcome to Spring MVCHello everyone! Welcome to Spring MVC: Example 1


Surprised!

Continue...

Spring Dependency Injection

Without the concept of dependency injection, a consumer who needs a particular service in order to accomplish a certain task would be responsible for handling the life-cycle (instantiating, opening and closing streams, disposing, etc.) of that service. Using the concept of dependency injection, however, the life-cycle of a service is handled by a dependency provider (typically a container) rather than the consumer. The consumer would thus only need a reference to an implementation of the service that it needed in order to accomplish the necessary task.

A kind of Inversion of Control (IoC)

● “Hollywood Principle” – Don't call me, I'll call you

● “Container” resolves (injects) dependencies of components by setting implementation object (push)

● As opposed to component instantiating or Service Locator pattern where component locates implementation (pull)

● Martin Fowler calls Dependency Injection

EJB Vs Spring

EJB are Java EE platform components where we can get the benefits of life cycle management, bean management, transaction management and security Services. EJB's are called heavy weight components due to their complexity.

Many lightweight components are designed to overcome the shortcomings of EJB. They lightweight in that they can support simple Java objects as components. A challenge of lightweight containers is how to decouple dependencies between components. IOC has proved to be an effective solution to this problem. Where IOC is a general design principle DI is a concrete design pattern the embodies this principle.

Example 1

Problem: Design an application for generating different types of reports (text, pdf and html reports) for different time periods (daily, monthly and quarterly).


Solution:


public interface ReportGenerator {
    public void generateReport(String reportContent);
}

public class TextReportGenerator implements ReportGenerator{
    public void generateReport(String reportContent) {
        System.out.println("Text Report:" + reportContent);
    }
}

public class HtmlReportGenerator implements ReportGenerator{
    public void generateReport(String reportContent) {
        System.out.println("HTML Report:" + reportContent);
    }
}

public class PdfReportGenerator implements ReportGenerator{
    public void generateReport(String reportContent) {
        System.out.println("PDF Report:" + reportContent);
    }
}

public class ReportService {
    private ReportGenerator reportGenerator = new TextReportGenerator(); // Service is directly contacting concrete class of ReportGenerator here.

    public void dailyReport() {
        reportGenerator.generateReport("Daily Report Content");
    }

    public void monthlyReport() {
        reportGenerator.generateReport("Monthly Report Content");
    }

    public void quarterlyReport() {
        reportGenerator.generateReport("Quarterly Report Content");
    }
}


ReportService is creating the instance of ReportGenerator internally, so it has to be aware of which concrete class of ReportGenerator to use. This will cause a direct dependency fromReportService to either of the ReportGenerator implementations.

To avoid dependency between these I am going to introduce container:

import java.util.HashMap;
import java.util.Map;

public class Container {
    public static Container instance;
    private Map<String, Object> components;

    public Container() {
        components = new HashMap<String, Object>();

        instance = this;

        ReportGenerator reportGenerator = new TextReportGenerator();
        components.put("reportGenerator", reportGenerator);

        ReportService reportService = new ReportService();
        components.put("reportService", reportService);
    }

    public Object getComponent(String id) {
        return components.get(id);
    }
}

Now I am going to change the ReportService class to:

public class ReportService {
    private ReportGenerator reportGenerator = (ReportGenerator)Container.instance.getComponent("reportGenerator");
    ...
}

This modification means that ReportService doesn’t have to worry about which ReportGenerator implementation to use, so you don’t have tomodify ReportService any more when you want to switch report generator implementation.

Now we will test our code by writing main class:

public class TestReport {
    public static void main(String[] args) {
        Container container = new Container();
        ReportService reportService =
                (ReportService) container.getComponent("reportService");
        reportService.dailyReport();
    }
}

Result is: Text Report:Daily Report Content

conclusion: employing a container can help reduce coupling between different components within a system, and hence increase the independence and re usability of each component. In this way, you are actually separating configuration (e.g., which type of report generator to use) from programming logic (e.g., how to generate a report in PDF format) in order to promote overall system re usability.

Using a Service Locator to Reduce Lookup Complexity:

To reduce the lookup complexity of your components, you can apply one of Sun’s core Java EE design patterns, Service Locator. The idea behind this pattern is as simple as using a service locator to encapsulate the complex lookup logic, while exposing simplemethods for lookup. Then, any component can delegate lookup requests to this service locator.

Now we will create simple ServiceLocator class and move the lookup logic of ReportService into this class.

public class ServiceLocator {
    private static Container container = Container.instance;

    public static ReportGenerator getReportGenerator() {
        return (ReportGenerator) container.getComponent("reportGenerator");
    }
}

Now change the ReportService class to:

public class ReportService {
    private ReportGenerator reportGenerator = ServiceLocator.getReportGenerator();
    ...
}

Applying Inversion of Control and Dependency Injection (Now we will finally apply the DI pattern to remove the dependency between ReportService and ServiceLocator.

The idea of this principle is to invert the direction of resource retrieval. In a traditional lookup, components seek resources by making requests to a container, and the container duly returns the resources in question.With IoC, the container itself actively delivers resources to its managed components. A component has only to choose a way of accepting the resources.

Now we will change our ReportService class like below:

public class ReportService {
    private ReportGenerator reportGenerator; //No need to lookup, container is responsible to supply this.

    public void setReportGenerator(ReportGenerator reportGenerator) {
        this.reportGenerator = reportGenerator;
    }
   
    ...

}

Now our Container class looks like below:

import java.util.HashMap;
import java.util.Map;

public class Container {

    private Map<String, Object> components;

    public Container() {
        components = new HashMap<String, Object>();

        ReportGenerator reportGenerator = new TextReportGenerator();
        components.put("reportGenerator", reportGenerator);

        ReportService reportService = new ReportService();
        reportService.setReportGenerator(reportGenerator);
        components.put("reportService", reportService);
    }

    public Object getComponent(String id) {
        return components.get(id);
    }
}


-> Now we can completely remove the ServiceLocator here because we are no more using that.
-> Service classes are completely independent of dependencies, container is responsible for supplying the dependencies.
-> Spring Container uses same technique to provide dependencies.



Different Types of Dependency Injection

Injecting a dependency via a setter method is not the only way of implementing DI. You will need different types of DI in different scenarios.

There are three main types of DI:

• Interface injection (Type 1 IoC)
• Setter injection (Type 2 IoC)
• Constructor injection (Type 3 IoC)

Setter and Constructor Injections are most widely used once. Interface injection is seldom used.


Hope it is helpful and Happy Learning!

Why Spring?

  1. Wiring of components through Dependency Injection – Promotes de-coupling among the parts that make the application.
  2. Design to interfaces – Insulates a user of a functionality from implementation details.
  3. Test-Driven Development (TDD) – POJO classes can be tested without being tied up with the framework.
  4. Declarative programming through AOP – Easily configured aspects, esp. transaction support.
  5. Simplify use of popular technologies
    – Abstractions insulate application from specifics, eliminate redundant code
    – Handle common error conditions
    – Underlying technology specifics still accessible
  6. Conversion of checked exceptions to unchecked.
  7. Not an all-or-nothing solution – Extremely modular and flexible.
  8. Well designed
    – Easy to extend
    – Many reusable classes
  9. Integration with other technologies
    – EJB for J2EE
    – Hibernate, iBates, JDBC (for data access)
    – Velocity (for presentation)
    – Struts and WebWork (For web).

Spring Features

What is Spring
Spring is a light weight and comprehensive framework for building Java SE and Java EE applications.

Key Features

  1. Java beans based configuration management.
  2. Applying Inversion of Control principle (Especially Dependency Injection technique) to reduce dependencies of components on specific implementations of other components.
  3. A core bean factory.
  4. Generic abstraction layer for database transaction management.
  5. Built in generic strategies for JTA and a single JDBC Data source.
  6. Integration with persistent frameworks like Hibernate, JDO and IBATIS.
  7. MVC web application framework, built on core Spring functionality, supporting many technologies for generating views, including JSP, FreeMarker, Velocity, Tiles, iText, and POI.
  8. Extensive aspect-oriented programming (AOP) framework to provide services such as transaction management.

Ibatis - Calling Oracle functions

Configuring XML file: -
<parameterMap id="functionXYZMap" class="java.util.Map">
        <parameter property="outParam" mode="OUT" javaType="java.lang.String" jdbcType="VARCHAR"/>  ---> LINE # 1
        <parameter property="inParam" mode="IN" javaType="java.lang.String" jdbcType="VARCHAR"/>
    </parameterMap>
   
    <procedure id="functionXYZ" parameterMap="functionXYZMap">       
            {? = call get_function_data(?) }
    </procedure>

Java Code:-

 public String getSpecieDescr(String specieCode) {
        Map<String, Object> inputMap = new HashMap<String, Object>();
        inputMap.put("specieCode", specieCode);

        sqlMapClientTemplate.queryForObject(retrieveSpecieDescrQuery, inputMap);
       
        return (String) inputMap.get("specieDescr");  // I was returning the result comes from the above line, it was returning null.

    }

Difficulties I faced when writing the above function:

1. I was not adding the output parameter in LINE # 1 which was giving the exception --> --- Cause: java.sql.SQLException: Missing IN or OUT parameter at index:: 2]], dirtiesContext [false].

2. I added wrong jdbcType as VARCHAR2-->  --- Cause: java.sql.SQLException: Invalid column type]], dirtiesContext [false].

3. I removed ? (output ? =) exception i got is --> PLS-00221: 'GET_SPECIE' is not a procedure or is undefined

4. I havent put (= after my ?) --> --- Cause: java.sql.SQLException: Malformed SQL92 string at position: 3. Expecting "=" got "c"

5. I added wrong javaType as "java.lang.StringBuffer" --> --- Check the output parameters (retrieval of output parameters failed). 
--- Cause: java.lang.NullPointerException]], dirtiesContext [false].  (When I was browsing for the function invocation in one site somebody mentioned that when you use INOUT parameter then you should not use String as javaType because Strings are immutable the values cannot be override, It mislead me such that i thought it will applicable for OUT parameters also, but it is only for INOUT params).

Ibatis - Basics

Data Mapper:-

Data Mapper provides a very simple framework for using XML descriptors to map JavaBeans, Map implementations, primitive wrapper types (String, Integer…) and even XML documents to an SQL statement. The following is a high level description of the lifecycle:

1. Provide an object as a parameter (a JavaBean, Map or primitive wrapper). The parameter object will be used to set input values in an update statement, or where clause values in a query...
2. Execute the mapped statement. This step is where the magic happens. The Data Mapper framework will create a Prepared Statement instance, set any parameters using the provided parameter object, execute the statement and build a result object from the Result Set.
3. In the case of an update, the number of rows affected is returned. In the case of a query, a single object, or a collection of objects is returned. Like parameters, result objects can be a
JavaBean, a Map, a primitive type wrapper or XML.
 
The SQL Map XML Configuration File (http://ibatis.apache.org/dtd/sql-map-config-2.dtd)

Data Mapper is configured using a central XML configuration file, which provides configuration details for Data Sources, Data Mapper and other options like thread management...

The following is an example of the SQL Map configuration file:
 SqlMapConfig.xml

<!—Always ensure to use the correct XML header as below! -->

<?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>

<!-- The properties (name=value) in the file specified here can be used placeholders in this config file
(e.g. “${driver}”. The file is relative to the classpath and is completely optional. -->

<properties resource=" examples/sqlmap/maps/SqlMapConfigExample.properties " />

<!-- These settings control SqlMapClient configuration details, primarily to do with transaction management. They are all optional (more detail later in this document). -->

<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
 lazyLoadingEnabled="true"
maxRequests="128"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false"
defaultStatementTimeout="5"
statementCachingEnabled="true"
classInfoCacheEnabled="true"
/>

<!-- This element declares a factory class that iBATIS will use for creating result objects.
This element is optional (more detail later in this document). -->

<resultObjectFactory type="com.mydomain.MyResultObjectFactory" >
<property name="someProperty" value="someValue"/>
</resultObjectFactory>

<!-- Type aliases allow you to use a shorter name for long fully qualified class names. -->

<typeAlias alias="order" type="testdomain.Order"/>

<!-- Configure a datasource to use with this SQL Map using SimpleDataSource.
Notice the use of the properties from the above resource -->

<transactionManager type="JDBC" >
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
<property name="JDBC.DefaultAutoCommit" value="true" />
<property name="Pool.MaximumActiveConnections" value="10"/>
<property name="Pool.MaximumIdleConnections" value="5"/>
<property name="Pool.MaximumCheckoutTime" value="120000"/>
<property name="Pool.TimeToWait" value="500"/>
<property name="Pool.PingQuery" value="select 1 from ACCOUNT"/>
<property name="Pool.PingEnabled" value="false"/>
<property name="Pool.PingConnectionsOlderThan" value="1"/>
<property name="Pool.PingConnectionsNotUsedFor" value="1"/>
</dataSource>
</transactionManager>

<!-- Identify all SQL Map XML files to be loaded by this SQL map. Notice the paths are relative to the classpath. For now, we only have one… -->

<sqlMap resource="examples/sqlmap/maps/Person.xml" />

</sqlMapConfig>

·         The SQL Map can have a single <properties> element that allows a standard Java properties file
(name=value) to be associated with the SQL Map XML configuration document.
·         For example, if the properties file contains the following:
driver=oracle.jdbc.driver.OracleDriver
·         Then the SQL Map configuration file or each SQL Map referenced by the configuration document can use the placeholder ${driver} as a value that will be replaced by oracle.jdbc.driver.OracleDriver. For example:
<property name="JDBC.Driver" value="${driver}"/>
·         The <settings> element allows you to configure various options and optimizations for the SqlMapClient instance that will be built using this XML file. The settings element and all of its attributes are completely optional.
o   maxRequests - maximum number of threads that can execute an SQL statement at a time. (Default = 512)
o   maxSessions - the number of sessions (or clients) that can be active at a given time. (Default = 128)
o   maxTransactions - the maximum number of threads that can enter SqlMapClient.startTransaction() at a time. (Default = 32)
o   cacheModelsEnabled - This setting globally enables or disables all cache models for a SqlMapClient. (Default = true)
o   lazyLoadingEnabled - This setting globally enables or disables all lazy loading for a SqlMapClient. (Default = true)
·         The <resultObjectFactory> Element - The resultObjectFactory element allows you to specify a factory class for creating objects resulting from the execution of SQL statements. This element is optional – if you don't specify the element, iBATIS will use internal mechanisms to create result objects (class.newInstance())...If you choose to implement a factory, your factory class must implement the interface com.ibatis.sqlmap.engine.mapping.result.ResultObjectFactory, and your class must have a public default constructor.
·         The <typeAlias> Element - The typeAlias element simply allows you to specify a shorter name to refer to what is usually a long, fully qualified classname. For example:
<typeAlias alias="shortname" type="com.long.class.path.Class"/>
·         The <transactionManager> Element - The <transactionManager> element allows you to configure the transaction management services for an SQL Map. The type attribute indicates which transaction manager to use. The value can either be a class name or a type alias. The three transaction managers included with the framework are: JDBC, JTA and EXTERNAL.
o   JDBC - This allows JDBC to control the transaction via the usual Connection commit() and rollback() methods.
o   JTA - This transaction manager uses a JTA global transaction such that the SQL Map activities can be included as part of a wider scope transaction that possibly involves other databases or transactional resources. This configuration requires a  UserTransaction property set to locate the user transaction from a JNDI resource. (Ex: java:comp/UserTransaction)
o   EXTERNAL – This allows you to manage transactions on your own. You can still configure a data source, but transactions will not be committed or rolled back as part of the framework lifecycle. This means that some part of your application external to Data Mapper must manage the transactions. This setting is also useful for non-transactional databases (e.g. Read-only).
·         The <transactionManager> element also allows an optional attribute commitRequired that can be true or false. Normally iBATIS will not commit transactions unless an insert, update, or delete operation has been performed. This is true even if you explicitly call the commitTransaction() method. This behavior creates problems in some cases. If you want iBATIS to always commit transactions, even if no insert, update, or delete operation as been performed, then set the value of the commitRequired attribute to true. Examples of where this attribute is useful include:
o   If you call a stored procedures that updates data as well as returning rows. In that case you would call the procedure with the queryForList() operation – so iBATIS would not normally commit the transaction. But then the updates would be rolled back.
o   In a WebSphere environment when you are using connection pooling and you use the JNDI <dataSource> and the JDBC or JTA transaction manager. WebSphere requires all transactions on pooled connections to be committed or the connection will not be returned to the pool.
o    Note that the commitRequired attribute has no effect when using the EXTERNAL transaction manager.
·         The <dataSource> Element - Included as part of the transaction manager configuration is a dataSource element and a set of properties to configure a DataSource for use with your SQL Map.

·         There are currently three datasource factories provided with the framework, but you can also write your own.
o   SimpleDataSourceFactory - The SimpleDataSource factory provides a basic implementation of a pooling DataSource that is ideal for providing connections in cases where there is no container provided DataSource. It is based on the iBATIS SimpleDataSource connection pool implementation.
Ex: <transactionManager type="JDBC" > <dataSource type="SIMPLE">
o   DbcpDataSourceFactory - This implementation uses Jakarta DBCP (Database Connection Pool) to provide connection pooling services via the DataSource API. This DataSource is ideal where the application/web container cannot provide a DataSource implementation, or you’re running a standalone application.
Ex: <transactionManager type="JDBC" > <dataSource type="DBCP">
o   JndiDataSourceFactory - This implementation will retrieve a DataSource implementation from a JNDI context from within an application container. This is typically used when an application server is in use and a container managed connection pool and associated DataSource implementations are provided.
Ex: <transactionManager type="JDBC" > <dataSource type="JNDI">
·         The <sqlMap> Element - The sqlMap element is used to explicitly include an SQL Map or another SQL Map Configuration file. Each SQL Map XML file that is going to be used by this SqlMapClient instance, must be declared. The SQL Map XML files will be loaded as a stream resource from the classpath or from a URL. You must specify any and all Data Mapper
o   <!-- CLASSPATH RESOURCES -->
§  <sqlMap resource="com/ibatis/examples/sql/Customer.xml" />
o   <!-- URL RESOURCES -->
§  <sqlMap url="file:///c:/config/Customer.xml " />
·         The SQL Map XML File ( http://ibatis.apache.org/dtd/sql-map-config-2.dtd)

<?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=”Product”>

<cacheModel id=”productCache” type=”LRU”>
<flushInterval hours=”24”/>
<property name=”size” value=”1000” />
</cacheModel>

<typeAlias alias=”product” type=”com.ibatis.example.Product” />

<parameterMap id=”productParam” class=”product”>
<parameter property=”id”/>
</parameterMap>

<resultMap id=”productResult” class=”product”>
<result property=”id” column=”PRD_ID”/>
<result property=”description” column=”PRD_DESCRIPTION”/>
</resultMap>

<select id=”getProduct” parameterMap=”productParam”
resultMap=”productResult” cacheModel=”product-cache”>
select * from PRODUCT where PRD_ID = ?
</select>

</sqlMap>

(or)

<sqlMap namespace=”Product”>
<select id=”getProduct” parameterClass=” com.ibatis.example.Product”
resultClass=”com.ibatis.example.Product”>
select
PRD_ID as id,
PRD_DESCRIPTION as description
from PRODUCT
where PRD_ID = #id#
</select>
</sqlMap>

·         Mapped Statements - The Data Mapper concept is centered on mapped statements. Mapped statements can be any SQL statement and can have parameter maps (input) and result maps (output). If the case is simple, the mapped statement can be configured directly to a class for parameters and results. The mapped statement can also be configured to use a cache model to cache popular results in memory.

<statement id=”statementName”
[parameterClass=”some.class.Name”]
[resultClass=”some.class.Name”]
[parameterMap=”nameOfParameterMap”]
[resultMap=”nameOfResultMap”]
[cacheModel=”nameOfCache”]
[timeout=“5”]>

select * from PRODUCT where PRD_ID = [? | #propertyName#]
order by [$simpleDynamic$]
</statement>

Where statement can be any of insert, update, delete, select, procedure, or statement. In the above statement, the [bracketed] parts are optional and in some cases only certain combinations are allowed. So it is perfectly legal to have a Mapped Statement with as simple as this:
               
<insert id=”insertTestProduct” >
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (1, “Shih Tzu”)
</insert>

·         Statement Types - The <statement> element is a general “catch all” statement that can be used for any type of SQL statement.
o   <statement>
o   <insert>
o   <update>
o   <delete>
o   <select>
o   <procedure>
·         The SQL - The SQL is obviously the most important part of the map. It can be any SQL that is valid for your database and JDBC driver. The most common obviously is the greater-than and less-than symbols (<>). These are commonly required in SQL and are reserved symbols in XML. There is a simple solution to deal with these and any other special XML characters you might need to put in your SQL. By using a standard XML CDATA section, none of the special characters will be parsed.
·                        <select id="getPersonsByAge"
parameterClass=”int”
resultClass="examples.domain.Person">
SELECT *
FROM PERSON
WHERE AGE <![CDATA[ > ]]> #value#
</select>
·         Reusing SQL Fragments - When writing SqlMaps, you often encounter duplicate fragments of SQL, for example a FROM-clause or constraint-statement. iBATIS offers a simple yet powerful tag to reuse them. To eliminate this duplication, we use the tags <sql> and <include>. The <sql> tag contains the fragment to reuse, the <include> tag includes such a fragment in a statement. For example:

<sql id="selectItemfragment">
FROM items
WHERE parentid = 6
</sql>

<select id="selectItemCount" resultClass="int">
SELECT COUNT(*) AS total
<include refid="selectItemfragment"/>
</select>

<select id="selectItems" resultClass="Item">
SELECT id, name
<include refid="selectItemfragment"/>
</select>

·         Stored Procedures - Stored procedures are supported via the <procedure> statement element. The following example shows how a stored procedure would be used with output parameters.
<parameterMap id="swapParameters" class="map" >
<parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
<parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>

<procedure id="swapEmailAddresses" parameterMap="swapParameters" >
                {call swap_email_address (?, ?)}
</procedure>

·         parameterClass - The value of the parameterClass attribute is the fully qualified name of a Java class (i.e. including package). The parameterClass attribute is optional, but highly recommended. It is used to limit parameters passed to the statement, as well as to optimize the performance of the framework. If you’re using a parameterMap, there is no need to use the parameterClass attribute. For example, if you only wanted to allow objects of type (i.e. instanceof) “examples.domain.Product” to be passed in as a parameter, you could do something like this:

<insert id=”statementName” parameterClass=” examples.domain.Product”>
                insert into PRODUCT values (#id#, #description#, #price#)
</insert>

IMPORTANT: Although optional for backward compatibility, it is highly recommended to always provide a parameter class (unless of course there are no required parameters). You will achieve better performance by providing the class, because the framework is capable of optimizing itself if it knows the type in advance.

·         parameterMap - The parameterMap attribute is rarely used in favor of the parameterClass attribute. The value of the parameterMap attribute is the name of a defined parameterMap element and inline parameters. However, this is a good approach if XML purity and consistency is your concern, or you need a more descriptive parameterMap

<parameterMap id=”insert-product-param” class=”com.domain.Product”>
                <parameter property=”id”/>
                <parameter property=”description”/>
</parameterMap>

<insert id=”insertProduct” parameterMap=”insert-product-param”>
                insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?)
</insert>

In the example above, the parameter map describes two parameters that will match, in order, the value tokens (“?”) in the SQL statement. So the first “?” will be replaced by the value of the “id” property and the second with the “description” property. Parameter maps and their options are described in more detail later in this document.

·         Inline Parameters - Inline parameters can be used inside of a mapped statement.
For example:

<insert id=”insertProduct” >
                insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)
                values (#id#, #description#)
</insert>

In the above example the inline parameters are #id# and #description#. Each represents a JavaBeans property that will be used to populate the statement parameter in-place.

·         resultClass - The value of the resultClass attribute is the fully qualified name of a Java class (i.e. including package). The resultClass attribute allows us to specify a class that will be auto-mapped to our JDBC Result Set based on the ResultSetMetaData. Wherever a property on the JavaBean and a column of the Result Set match, the property will be populated with the column value.

·         resultMap - The resultMap property is one of the more commonly used. The value of the resultMap attribute is the name of a defined resultMap element. Using the resultMap attribute allows you to control how data is extracted from a result set and which properties to map to which columns. Unlike the auto-mapping approach using the resultClass attribute, the resultMap allows you to describe the column type, a null value replacement and complex property mappings (including other JavaBeans, Collections and primitive type wrappers).

·         cacheModel - The cacheModel attribute value is the name of a defined cacheModel element. A cacheModel is used to describe a cache for use with a query mapped statement. Each query mapped statement can use a different cacheModel, or the same one. The following example will demonstrate how it looks related to a statement.

<cacheModel id="product-cache" type="LRU">
                <flushInterval hours="24"/>
                <flushOnExecute statement="insertProduct"/>
                <flushOnExecute statement="updateProduct"/>
                <flushOnExecute statement="deleteProduct"/>
                <property name=”size” value=”1000” />
</cacheModel>

<select id=”getProductList” parameterClass=”int” cacheModel=”product-cache”>
                select * from PRODUCT where PRD_CAT_ID = #value#
</select>

·         xmlResultName - When mapping results directly to an XML document, the value of the xmlResultName will be the name of the root element of the XML document. For example:
               
<select id="getPerson" parameterClass=”int” resultClass="xml" xmlResultName=”person”>
                                SELECT
                                PER_ID as id,
                                PER_FIRST_NAME as firstName,
                                PER_LAST_NAME as lastName,
                                PER_BIRTH_DATE as birthDate,
                                PER_WEIGHT_KG as weightInKilograms,
                                PER_HEIGHT_M as heightInMeters
                                FROM PERSON
                                WHERE PER_ID = #value#
</select>

The above select statement would produce a result XML object of the following structure:

<person>
                <id>1</id>
                <firstName>Clinton</firstName>
                <lastName>Begin</lastName>
                <birthDate>1900-01-01</birthDate>
                <weightInKilograms>89</weightInKilograms>
                <heightInMeters>1.77</heightInMeters>
</person>

·         remapResults - The remapResults attribute is available on <statement>, <select>, and <procedure> mapped statements. It's an optional attribute and the default is false. The remapResults attribute should be set to true when a query has a variable set of return columns. For example consider the following queries:

                SELECT $fieldList$ FROM table

In the former example the list of columns are dynamic, even though the table is always the same.

                SELECT * FROM $sometable$

In the former example the table could be different. Because of the usage of * in the select clause, the resulting column names could be different as well. Dynamic elements could also cause the column list to change from one query execution to the next one. Since the overhead to introspect/determine the resultset metadata is not trivial, iBATIS will remember what was returned the last time the query was run. This creates problems in situations similar to the examples above, hence the possibility to do metadata introspection with every query execution. So if the return columns can change set remapResults to true, else set remapResults to false to avoid the overhead of metadata introspection.

·         resultsetType  - To specify the resultSetType of the SQL statement. It can either be:

FORWARD_ONLY: cursor may move only forward
SCROLL_INSENSITIVE: cursor is scrollable but generally not sensitive to changes made by others
SCROLL_SENSITIVE: cursor is scrollable and generally sensitive to changes made by others

Note that resultSetType is generally not required and that different JDBC drivers may behave differently using the same resultSetType setting (e.g. Oracle does not support SCROLL_SENSITIVE).

fetchSize - Sets the fetchSize on the SQL statement that will be executed. It gives the JDBC driver a hint to do pre fetching in order to minimize round-trips to the database server.

timeout - Sets the JDBC query timeout for this statement. Any value specified here will override the value specified in the “defaultStatementTimeout” setting in the SQLMapConfig.xml file. If you specify a default timeout and decide that you don't want a timeout for a particular statement, set the timeout value to 0. The specified value is the number of seconds the driver will wait for a statement to finish. Note that not all drivers support this setting.

·         Learning’s
o   When running functions should not specify integer (0) values to Nullable fields.
o   When running functions should not set nullValue=true option.
o   When running functions if need to pass null value we should definitely have the property nullValue = true.
o   When we use resultSet as java.util.HashMap, it caches the results, which creates a mess of results for multiple calls with different parameters where different result is expected. To avoid this set remapResultSet = true to not cache the results.
Ibatis XML files will not parse the sql comments (--) , they gives unrelated errors if your query in ibatis xml file contains these comments.


Happy Learning!