How do I build SqlSessionFactory without XML?

MyBatis comes with a complete configuration classes that allows us to create a configuration object programmatically without using the XML file. In this code snippet you’ll see how to create a SqlSessionFactory object without XML configuration file.

We start by obtaining a javax.sql.DataSource object. Then we create a TransactionFactory object. With these two objects we can then create an Environment object and specify its name, such as development, for development environment. The final step is to create the Configuration object using the previously created environment.

In the Configuration object we can define information such as the type aliases and register all the MyBatis mappers.

package org.kodejava.example.mybatis;

import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.ibatis.type.TypeAliasRegistry;
import org.kodejava.example.mybatis.annotation.RecordMapper;
import org.kodejava.example.mybatis.domain.Record;

import javax.sql.DataSource;

public class BuildSqlSessionFactory {
    public static void main(String[] args) {
        // Get DataSource object.
        DataSource dataSource = BuildSqlSessionFactory.getDataSource();

        // Creates a transaction factory.
        TransactionFactory trxFactory = new JdbcTransactionFactory();

        // Creates an environment object with the specified name, transaction
        // factory and a data source.
        Environment env = new Environment("dev", trxFactory, dataSource);

        // Creates a Configuration object base on the Environment object.
        // We can also add type aliases and mappers.
        Configuration config = new Configuration(env);
        TypeAliasRegistry aliases = config.getTypeAliasRegistry();
        aliases.registerAlias("record", Record.class);

        config.addMapper(RecordMapper.class);

        // Build the SqlSessionFactory based on the created Configuration object.
        // Open a session and query a record using the RecordMapper.
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(config);
        SqlSession session = factory.openSession();

        try {
            RecordMapper mapper = session.getMapper(RecordMapper.class);
            Record record = mapper.getRecord(1L);
            System.out.println("Record = " + record);
        } finally {
            session.close();
        }
    }

    /**
     * Returns a DataSource object.
     *
     * @return a DataSource.
     */
    public static DataSource getDataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setUrl("jdbc:mysql://localhost/musicdb");
        dataSource.setUsername("root");
        dataSource.setPassword("");
        return dataSource;
    }
}

Below are the other supporting classes for the code above, Record and RecordMapper.

package org.kodejava.example.mybatis.annotation;

import org.apache.ibatis.annotations.Select;
import org.kodejava.example.mybatis.domain.Record;

public interface RecordMapper {
    /**
     * Get a single Record from the database based on the record
     * identified.
     *
     * @param id record identifier.
     * @return a record object.
     */
    @Select("SELECT * FROM records WHERE id = #{id}")
    Record getRecord(Long id);
}
package org.kodejava.example.mybatis.domain;

import java.io.Serializable;
import java.util.Date;

public class Record implements Serializable {
    private Long id;
    private String title;
    private Date releaseDate;
    private Long artistId;
    private Long labelId;

    // Getters & Setters

    @Override
    public String toString() {
        return "Record{" +
            "id=" + id +
            ", title='" + title + '\'' +
            ", releaseDate=" + releaseDate +
            ", artistId=" + artistId +
            ", labelId=" + labelId +
            '}';
    }
}

Maven Dependencies

<dependencies>
    <!--https://search.maven.org/remotecontent?filepath=org/mybatis/mybatis/3.5.0/mybatis-3.5.0.jar-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.0</version>
    </dependency>
    <!--https://search.maven.org/remotecontent?filepath=mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47.jar-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <!--https://search.maven.org/remotecontent?filepath=org/apache/commons/commons-dbcp2/2.5.0/commons-dbcp2-2.5.0.jar-->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-dbcp2</artifactId>
        <version>2.5.0</version>
    </dependency>
</dependencies>

Maven Central
Maven Central

How do I create MyBatis SqlSession object?

To create an SqlSession you can use the SqlSessionFactory class openSession() method. This method offers some overloaded method that can configure the property of the session. For example we can cofigure the auto-commit-mode and the transaction-isolation-level for the session.

package org.kodejava.example.mybatis;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.kodejava.example.mybatis.domain.Record;

import java.io.IOException;
import java.io.Reader;

public class SqlSessionDemo {
    public static void main(String[] args) throws IOException {
        SqlSessionDemo demo = new SqlSessionDemo();

        // Build an SqlSessionFactory.
        SqlSessionFactory factory = demo.getSessionFactory();

        // Create an SqlSession by using the factory.openSession() method.
        // It is a good practice to use a try-with-resources block when
        // working with an SqlSession. The session will be automatically
        // closes when it finishes the job.
        try (SqlSession session = factory.openSession()) {
            Record record = session.selectOne("getRecord", 1L);
            System.out.println("Record = " + record);
        }
    }

    /**
     * Build an SqlSessionFactory.
     *
     * @return an SqlSessionFactory.
     * @throws IOException when fail to read the configuration file.
     */
    private SqlSessionFactory getSessionFactory() throws IOException {
        Reader reader = Resources.getResourceAsReader("configuration.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        return builder.build(reader);
    }
}

Below are the configuration, mapper and the POJO.

  • configuration.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="record" type="org.kodejava.example.mybatis.domain.Record"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost/musicdb"/>
                <property name="username" value="root"/>
                <property name="password" value=""/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/kodejava/example/mybatis/mapper/RecordMapper.xml"/>
    </mappers>
</configuration>
  • RecordMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.kodejava.example.mybatis.persistence.RecordMapper">

    <resultMap id="recordResultMap" type="record">
        <result column="release_date" property="releaseDate"/>
        <result column="artist_id" property="artistId"/>
        <result column="label_id" property="labelId"/>
    </resultMap>

    <select id="getRecord" parameterType="java.lang.Long" resultMap="recordResultMap">
        SELECT
            id,
            title,
            release_date,
            artist_id,
            label_id
        FROM records
        WHERE id = #{id}
    </select>
</mapper>
  • Record.java
package org.kodejava.example.mybatis.domain;

import java.io.Serializable;
import java.util.Date;

public class Record implements Serializable {
    private Long id;
    private String title;
    private Date releaseDate;
    private Long artistId;
    private Long labelId;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Date getReleaseDate() {
        return releaseDate;
    }

    public void setReleaseDate(Date releaseDate) {
        this.releaseDate = releaseDate;
    }

    public Long getArtistId() {
        return artistId;
    }

    public void setArtistId(Long artistId) {
        this.artistId = artistId;
    }

    public Long getLabelId() {
        return labelId;
    }

    public void setLabelId(Long labelId) {
        this.labelId = labelId;
    }

    @Override
    public String toString() {
        return "Record{" +
            "id=" + id +
            ", title='" + title + '\'' +
            ", releaseDate=" + releaseDate +
            ", artistId=" + artistId +
            ", labelId=" + labelId +
            '}';
    }
}

The directory structure of the code above is:

├── pom.xml
└── src
    └── main
        ├── java
        │   └── org
        │       └── kodejava
        │           └── example
        │               └── mybatis
        │                   ├── SqlSessionDemo.java
        │                   └── domain
        │                       └── Record.java
        └── resources
            ├── configuration.xml
            └── org
                └── kodejava
                   └── example
                        └── mybatis
                            └── mapper
                                └── RecordMapper.xml

Maven Dependencies

<!-- https://search.maven.org/remotecontent?filepath=org/mybatis/mybatis/3.5.0/mybatis-3.5.0.jar -->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.0</version>
</dependency>
<!-- https://search.maven.org/remotecontent?filepath=mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47.jar -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

Maven Central
Maven Central

How do I create an SqlSessionFactory object in MyBatis?

The example below shows you how to create MyBatis SqlSessionFactory object using an xml configuration. The steps required is create the configuration file. This file basically contains the connection information to the database and MyBatis configuration such as typeAliases and the mappers.

The next steps is read the configuration file using a org.apache.ibatis.io.Resources class. This information the passes as the argument of the build() method of the SqlSessionFactoryBuilder class. The build() method return an SqlSessionFactory object.

package org.kodejava.example.mybatis;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.Reader;

public class SqlSessionFactoryDemo {
    public static void main(String[] args) throws IOException {
        // A resource file for MyBatis configuration.
        Reader reader = Resources.getResourceAsReader("configuration.xml");

        // Creates an SqlSessionFactoryBuilder. This builder need only 
        // create one time during the application life time.
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

        // Creates an instance of SqlSessionFactory. This object can be 
        // used to initiate an SqlSession for querying information from 
        // the mapped query.
        SqlSessionFactory factory = builder.build(reader);
        System.out.println("factory = " + factory);
    }
}

Below is an example of MyBatis configuration file:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="record" type="org.kodejava.example.mybatis.domain.Record"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost/musicdb"/>
                <property name="username" value="root"/>
                <property name="password" value=""/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/kodejava/example/mybatis/mapper/RecordMapper.xml"/>
    </mappers>
</configuration>