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 MyBattis mappers.

package org.kodejava.example.mybatis;

import org.apache.commons.dbcp.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(1);
            System.out.println("Record = " + record);
        } finally {
            session.close();
        }
    }

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

How do I create MyBatis mapper?

In this examples you will see how to create or define a data mapper using the MyBatis. The mapper will communicate our application with the underlying databases where the data is stored. MyBatis data mapper is defined as an interface object. We can either use annotations or the xml mapper to define our database query.

In the first steps we will create a domain object, a simple pojo to store our data in the object world. The attributes / fields of our pojo resemble the structure of our records table in the database.

package org.kodejava.example.mybatis.domain;

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

public class Record implements Serializable {
    private Integer id;
    private String title;
    private Date releaseDate;
    private Integer artistId;
    private Integer labelId;
    private Date created;
    private Date modified;

    public Record() {
    }

    //
    // Define the getters and setters for our pojo.
    //
    // ...
    // ...
    // ...

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

Next we define the mapper interface code, we’ll create a RecordMapper.java file that contains a method to get data from the table. At this time the interface will be as the following:

package org.kodejava.example.mybatis.persistence;

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.
     */
    Record getRecord(int id);
}

After create the ResultMapper.java interface we create a RecordMapper.xml file that defines the queries used by our mapper. Here is how it looks like:

<?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="int" resultMap="recordResultMap">
        SELECT
            id,
            title,
            release_date,
            artist_id,
            label_id,
            created,
            modified
        FROM records
        WHERE id = #{id}
    </select>
</mapper>

To tell MyBatis about our mapper we need to define the mapper inside MyBatis configuration file. We register the mapper inside the <mappers> element of the 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/mediadb"/>
                <property name="username" value="root"/>
                <property name="password" value="welcome"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/kodejava/example/mybatis/persistence/RecordMapper.xml"/>
    </mappers>
</configuration>

Finally, we create a simple application to use the data mapper to get record data from the database.

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 org.kodejava.example.mybatis.persistence.RecordMapper;

import java.io.Reader;

public class MediaClient {
    public static void main(String[] args) throws Exception {
        String resource = "org/kodejava/example/mybatis/Configuration.xml";
        Reader reader = Resources.getResourceAsReader(resource);

        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(reader);

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