2016년 11월 22일 화요일

mybatis mapper 동적 설정


spring 등 여타 framework 에서 sql query xml 을 mybatis 에 설정 하는 방법은
@MapperScan annotation 을 활용하거나 mybatis 의 scan 등을 활용해 mapper 를 손쉽게 설정 할 수 있다.

하지만 독립적으로 mybatis 를 사용하면서 로직에 따라 동적으로 mapper 를 등록해야 하는 일이 생겼는데 
공식 reference site 에 딱히 방법이 나와 있지 않아 난감해진적이 있었다.
그때 해결했던 이력을 남겨본다.

핵심만 말하자면
mybatis 라이브러리안에 XMLMapperBuilder 라는 class 를 활용해 해결할 수 있다.

아래는 test 했던 난잡한 sample code 이다. 그래도 작은 도움은 될거라 생각된다.

/**
 * Created by fall1999y on 2016. 6. 23..
 */

public class SessionFactoryProvider {
    private static final String mapperFiles[] = {"mybatis/sql/testsql.xml", "mybatis/sql/samplesql.xml"};

    public SqlSessionFactory produceFactory() {
        String resource = "mybatis/mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {

            throw new RuntimeException("Fatal Error.  Cause: " + e, e);
        }
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        for (String mapperFile : mapperFiles) {
            InputStream in = getClass().getClassLoader().getResourceAsStream(mapperFile);
            Configuration configuration = sqlSessionFactory.getConfiguration();
            if (in != null) {
                XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(in, configuration, mapperFile, configuration.getSqlFragments());
                xmlMapperBuilder.parse();
            } else {
                System.err.println("Error file not loaded " + mapperFile);
            }
        }
        return sqlSessionFactory;
    }

    public static void main(String[] args) {
        SessionFactoryProvider provider = new SessionFactoryProvider();
        SqlSessionFactory factory = provider.produceFactory();
        SqlSession s = factory.openSession();

        TestMapper mapper = s.getMapper(TestMapper.class);
        System.out.println(mapper.selectTestTable());
        SampleMapper sampleMapper = s.getMapper(SampleMapper.class);
        System.out.println(sampleMapper.selectSampleTable());
    }
}


참고로 아래는 독립적인 mybatis 에서 xml scan 하는 설정이다. (mybatis.xml)
<mappers>
    <package..
부분만 보면 이해가 가능하다.

<?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>
    <properties resource="properties/db.properties" />
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
        <environment id="development2">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <package name="net.vjvj.mapper"/>
    </mappers>
</configuration>

Intelij 설정 및 plugin

1. preferences... (settings...) Appearance & Behavior > Appearance - Window Options        ✓   Show memory indicator Editor &...