Integrating MyBatis 3 and Spring frameworks – Part 2

MyBatis 3 is very powerful SQL mapping framework with automatic database access class generation using a proxy implementation of the services defined by users. We get realize it’s true power if you integrate MyBatis 3 with Spring framework and use these proxy implementation. It will reduce our database work by 80%. In this tutorial, we will see how to integrate MyBatis 3 with Spring 3 framework.

In our previous step, we created the CRUD database service for class User using MyBatis 3. Now, we will integrate the data services implemented using MyBatis with Spring framework.

Tools Used:

  • c3p0-0.9.1.2.jar – For providing pooled database connection.
  • mybatis-spring-1.0.0.jar – For integrating MyBatis with Spring (Provided by MyBatis team)
  • Spring JDBC and Core library

To integrate these two frameworks, we have to follow bellow steps:

Step 1: Defining datasource as a Spring bean

As we will use c3po data source provider, we have to define datasource bean in Spring. Following is the configuration snippet:


<!-- Declare a datasource that has pooling capabilities -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" p:driverClass="${app.jdbc.driverClassName}"
p:jdbcUrl="${app.jdbc.url}" p:user="${app.jdbc.username}" p:password="${app.jdbc.password}"
p:acquireIncrement="10" p:idleConnectionTestPeriod="60" p:maxPoolSize="100"
p:maxStatements="50" p:minPoolSize="10" />

Here we have created a spring bean with id dataSource of class com.mchange.v2.c3p0.ComboPooledDataSource which is provided by c3p0 library for pooled data source.

We have set some properties in the bean. Following is the description of properties defined in bean:

  • driverClass : Driver class that will be used to connect to database.
  • jdbcUrl : jdbc url defining the database connection string.
  • user : username of the database user.
  • password : password of the database user.
  • acquireIncrement : how many connections will be created at a time when there will be a shortage of connections.
  • idleConnectionTestPeriod : after how much delay a connection will be closed if it is no longer in use.
  • maxPoolSize : Max number of connections that can be created.
  • maxStatements : Max number of SQL statements to be executed on a connection.
  • minPoolSize : Minimum number of connections to be created.

We have used Spring EL to define many of the property values, that will be bring from properties file.

Defining Transaction Manager in Spring

We will user Transaction Manager provided by Spring JDBC framework and for defining transaction levels we will use annotations. Following is the configuration for transaction manager:


<!-- Declare a transaction manager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />

<!-- Enable annotation style of managing transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />

Defining MyBatis SqlSessionFactory and MapperScanner


<!-- define the SqlSessionFactory, notice that configLocation is not needed when you use MapperFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value="WEB-INF/mybatis/sqlmap-config.xml" />
</bean>

<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="${MapperInterfacePackage}" />
</bean>

The SqlSessionFactory bean will provide SessionFactory instances of MyBatis. To configure SqlSessionFactory, we need to define two properties. First the data source which will be used by MyBatis to create connection database and MyBatis configuration file name to configure the environment of MyBatis.

MapperScannerConfigurer is used to publish the data service interfaces in defined for MyBatis to configure as Spring Beans. We just have to provide package in which the interfaces and their mapping XML files has been defined. We can specify more than one packages using common separation or semicolon. After that we will be able to get the instances of UserService using @Autowired annotation. We do not have to implement the interface as MyBatis will provide proxy implementation for this.

Spring configuration file as together

Here is our jdbc-context.xml as together:


<?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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans-3.0.xsd


http://www.springframework.org/schema/tx


http://www.springframework.org/schema/tx/spring-tx-3.0.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-3.0.xsd

">

<context:property-placeholder location="/WEB-INF/jdbc.properties,/WEB-INF/mybatis/mybatis.properties" />

    <!-- Enable annotation style of managing transactions -->
    <tx:annotation-driven transaction-manager="transactionManager" />

    <!-- Declare a datasource that has pooling capabilities -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close" p:driverClass="${app.jdbc.driverClassName}"
    p:jdbcUrl="${app.jdbc.url}" p:user="${app.jdbc.username}" p:password="${app.jdbc.password}"
    p:acquireIncrement="10" p:idleConnectionTestPeriod="60" p:maxPoolSize="100"
    p:maxStatements="50" p:minPoolSize="10" />

    <!-- Declare a transaction manager -->
    <bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
    p:dataSource-ref="dataSource" />

    <!-- define the SqlSessionFactory, notice that configLocation is not needed when you use MapperFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="WEB-INF/mybatis/sqlmap-config.xml" />
    </bean>

    <!-- scan for mappers and let them be autowired -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="${MapperInterfacePackage}" />
    </bean>

</beans>

jdbc.properties file


# database properties
app.jdbc.driverClassName=com.mysql.jdbc.Driver
app.jdbc.url=jdbc:mysql://localhost/mybatis-example
app.jdbc.username=root
app.jdbc.password=password

mybatis.properties file


MapperInterfacePackage=com.raistudies.persistence

 

Related Posts:

Leave a comment ?

2 Comments.

  1. Please post the rest of it soon. Good tutorial!

  2. when I am trying to Autowired User service I am getting the following error

    Error creating bean with name ‘loginController’: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.mycom.myproject.controller.LoginController.setUserMapper(com.mycom.myproject.db.mybatis.dao.UserMapper); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.mycom.myproject.db.mybatis.dao.UserMapper] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

    In spring-servlet.xml I am just using

    What I can miss please help

Leave a Comment Cancel reply


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>