Thursday, 22 March 2018

MyBatis

Modern java applications generally use some sort of ORM to talk to the database. In an ORM each table in the database is mapped to a java class (Pojo's). Most querries are done through the ORM's api or an ORM specific dialect which is similar to SQL.

MyBatis provides an alternative approach to working with the database. Instead of mapping each table to a java class, MyBatis maps the results of querries to java classes (Pojos's). This allows queries to be written in native sql, allowing for complex querries and leveraging the database. Only results required by the application need to be mapped to java classes. Most mapping can be handled by automatically so mapping code is significanlty reduced.

Below is an example of how this is done in MyBatis. The comple code can be checkeout from here:

https://github.com/rizvn/my-batis-tutorial

This example using the Dao pattern. A Dao is a class used to interact with the database.

1. Create the DAO interface

package com.rizvn.app.dao;
import com.rizvn.app.domain.Customer;
import java.util.List;

/**
 * Created by Riz
 */
public interface CustomerDao
{

  Customer findByRef(String ref);

  List<Customer> selectTop3();
}

This has 2 moethod to get a customer by ref, and list top3 customers

2. Create the domain object

This will be a plain java object (POJO) with gettters and setters. This is a the result of a query. MyBatis will map a result row to an instance of the class where the resultset column names match property names of the class. There are also other mapping approaches supported by myBatis, such as returning a hashmap or writting mapper sections, but that is out of scope for this example. For more click here.

Contents of Customer.java

public class Customer
{
  String ref;
  String name;
  String addressLine1;
  String town;
  String county;
  String postcode;
  Boolean active;
// getters and setters removed for brevity
}


3. Write SQL

Write querries for each method in the dao. The file name should match the name of the dao. Since the dao is named CustomerDao.java, the xml file will be named CustomerDao.xml

The xml file must be placed under the same package structure as the Dao. Since this project uses maven, non java classpath files are placed under src/main/resources. So the paths would be as follow:

  dao class location:  src/main/java/com/rizvn/app/dao/CustomerDao.java
  query file location: src/main/resources/com/rizvn/app/dao/CustomerDao.xml


Below are  the contents of CustomerDao.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="com.rizvn.app.dao.CustomerDao">

  <select id="findByRef" resultType="com.rizvn.app.domain.Customer">
    SELECT
      ref,
      name,
      addressLine1,
      town,
      county,
      postcode,
      active
    FROM Customer
    WHERE ref = #{ref}
    AND active = TRUE
  </select>

  <select id="selectTop3" resultType="com.rizvn.app.domain.Customer">
    SELECT
      ref,
      name,
      addressLine1,
      town,
      county,
      postcode,
      active
    FROM Customer
    WHERE active = TRUE
    LIMIT 3
  </select>

</mapper>

Each method in the interface is mapped to a query by id. The result type is also defined.
The findRef method in the Customer Dao has the following signature.

Customer findByRef(String ref);


The argument is accessible in the query section  as  #{ref}

Test

The CustomerDaoTest, under com.rizvn.app.dao.CustomerDaoTest shows usage examples of using mybatis with this set up.
@Test
public void getCustomerTest(){
  try(SqlSession session = conf.getSqlSessionFactory().openSession())
  {
    CustomerDao customerDao = session.getMapper(CustomerDao.class);      // get Dao class
    Customer customer = customerDao.findByRef("001");                    // call mapped query passing arguments
    System.out.println(customer);
    Assert.assertNotNull(customer);
  }
}

conf is the config classm which setups My Batis see here: https://github.com/rizvn/my-batis-tutorial/blob/master/src/main/java/com/rizvn/app/Config.java




No comments:

Post a Comment