반응형

스프링 구조에서만 Mybatis를 사용해보고 Maven 프로젝트에서 Mybatis연결은 처음해보게 되었는데, 항상 Autowired와 같은 어노테이션과 설정으로 자동으로 DI(의존성주입)처리가 된 DAO를 사용하다가 이번에 싱글톤 형태로 구성하여 최초에만 연결처리를 하고 연결된 객체를 계속해서 사용할 수 있도록 구성해보았습니다.

 

Mybatis 설정하기

pom.xml

<!-- MyBatis -->
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.4.1</version>
</dependency>

<!-- Mysql -->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.31</version>
</dependency>

Mysql에 연결하는 예제로 진행됩니다.

 

 

mybatis 연결정보를 담아놓을 xml을 만들겠습니다.

mybatis 패키지를 추가하시고 mybatis-config.xml을 생성합니다.

 

mybatis-config.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>
	<settings>
		<setting name="cacheEnabled" value="false"/>
		<setting name="useGeneratedKeys" value="ture"/>
		<setting name="lazyLoadingEnabled" value="true"/> 
		<setting name="defaultExecutorType" value="BATCH"/>
		<setting name="defaultStatementTimeout" value="3000"/>
	</settings>

    <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}"/>  
                <property name="poolMaximumActiveConnections" value="100"/>
                <property name="poolMaximumIdleConnections" value="100"/>
                <property name="poolTimeToWait" value="20000"/>
          </dataSource>
        </environment>
    </environments>
   
    <mappers>
        <mapper resource ="com/psw/exScheduler/mybatis/mapper/board.xml"/>  
    </mappers>
</configuration>

 

 

다음으로 매퍼를 추가합니다. 방금 추가한 mybatis 패키지 안에 mapper라는 패키지를 추가합니다.

board.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="board">
	<select id="selectTest" parameterType="java.util.HashMap" resultType="HashMap">
		select * from board limit 3;
	</select>
</mapper>

간단하게 3개만 board테이블에서 조회해오는 쿼리입니다.

 

 

이제 설정파일들을 읽어들이고 처리할 자바파일을 만들어보겠습니다.

utils라는 패키지를 추가하고 SqlSessionFactorys.java를 생성합니다.

SqlSessionFactorys.java

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Properties;

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.apache.log4j.Logger;

public class SqlSessionFactorys {
	
	private static final Logger logger = Logger.getLogger(SqlSessionFactorys.class);
	
	private SqlSessionFactorys() {}
	
	static SqlSessionFactorys instance;
	
	private static SqlSession sqlSession;
	
	public static SqlSessionFactorys getInstance() {
		if(instance == null) {
			logger.info("::: SqlSessionFactory Connection "+new Date(System.currentTimeMillis())+" :::");
			
			String resource = "com/psw/exScheduler/mybatis/mybatis-config.xml";
			
			Properties props = new Properties();
			props.put("driver"      , "com.mysql.jdbc.Driver");
			props.put("url"         , "jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&amp;characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&amp;defaultFetchSize=1000");
			props.put("username"    , "userName"); //각각 db연결 정보에 맞게 입력		
			props.put("password"    , "password"); //각각 db연결 정보에 맞게 입력

			InputStream inputStream = null;
	        try {
	        	inputStream = Resources.getResourceAsStream(resource);
	        	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, props);
	        	
	        	sqlSession = sqlSessionFactory.openSession(false);
	        	props.clear();
	        }catch(Exception e) {
	        	logger.error(e);
	        }finally {
	        	if(inputStream != null) {
	        		try {
	        			inputStream.close();
	        		}catch(IOException e) {
	        			logger.error(e);
	        		}
	        	}
	        }
		}
		instance = new SqlSessionFactorys();
		
		return instance;
	}
	
	public SqlSession getSqlSession() {
		return sqlSession;
	}
}

싱글톤 형태로 구성하기 위해 생성자는 private처리하여 접근할수 없도록 방지하였고, getInstance 메소드를 통해 최초에 한번만 SqlSessionFactory를 구성하고 담아둘수 있게 구성하였습니다.

 

SqlSession은 연결 후 해당 Class에서 getSqlSession메소드를 통해 가져와서 사용하면 되는 방식입니다.

 

SchedulerTest.java

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.psw.exScheduler.utils.SqlSessionFactorys;

@DisallowConcurrentExecution
public class SchedulerTest implements Job{
	
	private final Logger logger = Logger.getLogger(SchedulerTest.class);
	
	private static final SqlSession session = SqlSessionFactorys.getInstance().getSqlSession();

	public void execute(JobExecutionContext context) throws JobExecutionException {
		logger.info("::: 스케줄러가 동작합니다.  current Time [" + new Date(System.currentTimeMillis()) + "] :::");
		
		//test select db
		List<Map<Object, Object>> list = session.selectList("board.selectTest");
		for(int i=0; i<list.size(); i++) {
			System.out.println(list.get(i).toString());
		}
	}
}

 

동작 확인

작성이 완료되었으니 실제 동작하는지 확인을 해보겠습니다.

App.java

package kr.or.kisa.ktoaInterlock;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

public class App {
	
	private static final Logger logger = Logger.getLogger(App.class);
	
	private static PropertyReader prop = PropertyReader.getInstance();
	
	public static void main(String[] args){
		//SchedulerFactory Create
		SchedulerFactory schedulerFactory = new StdSchedulerFactory();
		try {
			Scheduler scheduler = schedulerFactory.getScheduler();
			
			JobDetail job = newJob(SchedulerTest.class)
					.withIdentity("jobName", Scheduler.DEFAULT_GROUP)
					.build();
			
			Trigger trigger = newTrigger()
					.withIdentity("triggerName", Scheduler.DEFAULT_GROUP)
					.withSchedule(cronSchedule("0 0 11 * * ?"))
					.build();
			
			scheduler.scheduleJob(job, trigger);
			scheduler.start();
		}catch(Exception e) {
			logger.error("Exception", e);
		}
	}
}

실제 db정보와 연결된 mybatis로 가져온 쿼리 정보입니다.

일치하는것을 확인 할 수 있습니다.

반응형