Search code examples
javaspringormibatismybatis

Pure Java MyBatis Mappers?


I have a project that uses Mybatis (v3.0.5) for OR/mapping. The typical (functioning) set up is as follows:

  1. A POJO to map - Fruit
  2. A "MyBatis" mapper XML file - FruitMapper.xml - where all the SQL queries go
  3. An interface mapper that defines all the same mapper methods - FruitMapper.java
  4. A DAO that has an interface mapper reference - FruitDao
  5. A MyBatis config file - mybatis-config.xml
  6. Linking everything together with Spring config XML - myapp-spring-config.xml

A sample implementation:

public class Fruit {
    private String type = "Orange"; // Orange by default!

    // Getters & setters, etc. This is just a VO/POJO
    // that corresponds to a [fruits] table in my DB.
}

public interface FruitMapper {
    public List<Fruit> getAllFruits();
}


public class FruitDao {
    private FruitMapper mapper;

    // Getters & setters

    public List<Fruit> getAllFruits() {
        return mapper.getAllFruits();
    }
}

FruitMapper.xml

<mapper namespace="net.me.myapp.FruitMapper">
    <select id="getAllFruits" resultSetType="FORWARD_ONLY">
        SELECT * FROM fruits
    </select>
</mapper>

mybatis-config.xml

<configuration>
    <!-- Nothing special here. -->
</configuration>

myapp-spring-config.xml: (THIS IS WHAT I WANT TO GET RID OF)

<bean id="fruitDao" class="net.me.myapp.FruitDao">
    <property name="mapper" ref="fruitMapper" />
</bean>
<bean id="fruitMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">  
    <property name="mapperInterface" value="net.me.myapp.FruitMapper" />
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="myDatasource" /> 
    <property name="configLocation" value="classpath:mybatis-config.xml" />
    <property name="mapperLocations" value="classpath:*Mapper.xml" />
</bean>
<bean id="myDatasource" class="org.springframework.jndi.JndiObjectFactoryBean" lazy-init="true">
    <property name="jndiName">
        <value>java:/comp/env/jdbc/our-mysql-database</value>
    </property>
</bean>

This works great. However, I'm not a huge fan of spring and was wondering how I would implement my own, pure Java, version of what all the beans in the Spring config file do.

So I ask: what "glue code"/classes do I need to write to properly implement FruitMapper.java such that it will be bound to FruitMapper.xml at runtime? Such that whenever I write:

FruitMapperDao dao = new FruitMapperDao();
FruitMapperImpl mapper = new FruitMapperImpl(); // <== this is what I need to implement here
dao.setMapper(mapper);

List<Fruit> allFruits = dao.getAllFruits();

...then I should get a list of all fruit records in my data source? Thanks in advance!

UPDATE

I should also mention that, given the setup above, I need both mybatis.jar and mybatis-spring.jar on the runtime classpath. I want to get rid of Spring altogether, and not require any Spring jars or classes for my pure Java solution to work!


Solution

  • You need to obtain an SqlSession instance (e.g. named session) and invoke method session.getMapper(FruitMapper.class). You will obtain an object that already implements mapper interface, then just call it's methods to obtain data from DB.

    P.S. You can obtain SqlSession without Spring like this:

    InputStream inputStream = Resources.getResourceAsStream("/mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession session = factory.openSession();