text/Java

java - mybatis 사용 (no spring)

hoonzii 2024. 5. 30. 11:06
반응형

검색하다 보면 mybatis 사용하는 예제들은 다 spring에 붙여서 쓰던데,

이번에 나는 executable jar로 말아서 사용했어야 해서 (배치작업용)

그것에 대해 작성해보려고 한다.

  1. lib 폴더에 jar 파일 가져다 놓고 import 하기
  2. db 정보, mybatis 설정, mapper 설정하기
  3. 이제 사용하기

순으로 정리 된다.

 

필요한 라이브러리를 jar를 받아준다.

다른 건 필요 없고, 각 DB에 맞는 라이브러리 와 mybatis 라이브러리 두 개를 넣어준다.

eclipse 기준으로 프로젝트 우클릭 → Build Path → Libraries → Add jars 해서 두 개의 라이브러리를 추가해 준다.

 

properties를 설정해 준다.

spring에 붙여서 쓸 때처럼 properties를 설정해줘야 하는데

db 설정 (db.properties)

#mysql - table
table.driver = com.mysql.cj.jdbc.Driver
table.url = jdbc:mysql://{ip}:{port}/{DB이름}?useUniCode=yes&characterEncoding=utf8
table.user = {db id}
table.password = {db password}

#mysql - table2
table2.driver = com.mysql.cj.jdbc.Driver
table2.url = jdbc:mysql://127.0.0.1:3306/localtestdb?useUniCode=yes&characterEncoding=utf8
table2.user = root
table2.password = 1234

크게 driver, url, user, password 이렇게 세팅해 주면 된다.

한 개의 DB만 쓸 때는 하나만, 여러개를 쓸때는 이렇게 각 DB 별로 정보를 세팅해 주면 된다.

 

mybatis 설정 (MyBatisConfig.xml)

environment에 위에서 설정했던 db 정보들 (driver, url, user, password)을 넣어준다.

여러 db 정보들은 enviroments 안에 각 enviroment 정보로 세팅…

각 environment는 id를 가지고 있고, 나중에 java에서는 이 id를 기준으로 사용한다.

mapper 경로는 같은 jar안에 꾸겨넣어서 쓸 거면 resources로, jar바깥에서 참조할 거면 url로 절대경로 써주면 된다. 나 같은 경우는 jar 바깥에 구성하고 나중에 db가 변경되거나, 쿼리를 변경해야 할 때를 대비해 바깥에 빼놓았어서 url로 절대경로를 써줬다. (절대경로 사용 시에는 (file:///) 을 접두사로 붙여준다.)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<environments default="table_mysql">
		<environment id="table_mysql">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
				<property name="driver" value="${table.driver}"/>
				<property name="url" value="${table.url}"/>
				<property name="username" value="${table.user}"/>
				<property name="password" value="${table.password}"/>
			</dataSource>
		</environment>
		
		<environment id="table2_mysql">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
				<property name="driver" value="${table2.driver}"/>
				<property name="url" value="${table2.url}"/>
				<property name="username" value="${table2.user}"/>
				<property name="password" value="${table2.password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<mappers>
		<mapper resource="conf/Mapper_table.xml"/>
		<mapper url="file:///{mapper 절대경로}/Mapper_table2.xml"/>
	</mappers>
</configuration>

 

mapper.xml 설정 (실제 사용될 쿼리들)

mapper.xml에는 실제 사용될 쿼리들을 적어준다.

중요한 건 mapper의 namespace, 쿼리별 id, 쿼리의 인자(parameterType), 쿼리의 결과(resultType)이다.

<?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="conf.Mapper_table">
	<select id="totalCount" resultType="map">
		select count(1) as cnt
		from dummytable
		;
	</select>
</mapper>

java에서 사용할 때,

resultType 변수명 = sqlSession.select(”namespace. 쿼리 id”, parameterType의 변수)로 사용하니까…

그럼 이 파일들은 어디에 놓냐? 자기 마음이겠지만… 내 경우엔

패키지를 하나 구성해서 해당 영역에 넣어줬다. 물론 eclipse 내에서 실행할 때는 이렇게 두고 하지만

jar로 만들어 실행할때는 외부에 해당 conf 폴더를 따로 두고 그 폴더를 읽게 구성했다.

 

사용하기

사용하기 앞서, 위에 설정했던 파일을 읽어드릴 config.java 파일들을 구성해야 한다.

세팅한 순서대로 DB 설정을 읽고 → mybtis 설정을 읽고 → mapper를 불러온다

//DBConfig.java

package mybatisTest.db;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;

public class DBConfig {
	public static Properties prop = new Properties();
	static {
		try {
		InputStream is = DBConfig.class.getResourceAsStream("../conf/db.properties");
		if(is == null) {
			is = new FileInputStream("./conf/db.properties");
		}
		
		prop.load(is);
		
		is.close();
		}catch(Exception e) {
			e.printStackTrace();
			System.out.println("db.properties file not found!");
		}
	}
}

eclipse 내 실행 시에는 resource를 통해서 읽게끔(같은 패키지내 config 파일), jar 실행시에는 외부의 conf 파일을 읽게끔 구성했다.

중요한 건 prop형식으로 config 설정 값을 static으로 가지고 있다는 점이다.

 

mybatis 설정 파일을 읽기

//MybatisConfig.java

package mybatisTest.db;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MybatisConfig {
	
	private static SqlSessionFactory table_sqlSessionFactory;
	private static SqlSessionFactory table2_sqlSessionFactory;
	
	static {
		try {
			InputStream is = MybatisConfig.class.getResourceAsStream("../conf/MyBatisConfig.xml");
			if(is == null)
				is = new FileInputStream("./conf/MyBatisConfig.xml");
			table_sqlSessionFactory = new SqlSessionFactoryBuilder().build(is, "table_mysql", DBConfig.prop);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	static {
		try {
			InputStream is = MybatisConfig.class.getResourceAsStream("../conf/MyBatisConfig.xml");
			if(is == null)
				is = new FileInputStream("./conf/MyBatisConfig.xml");
			table2_sqlSessionFactory = new SqlSessionFactoryBuilder().build(is, "table2_mysql", DBConfig.prop);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static SqlSessionFactory getTableSqlSesionFactory() {
		return table_sqlSessionFactory;
	}
	
	public static SqlSessionFactory getTable2SqlSessionFactory() {
		return table2_sqlSessionFactory;
	}
}

코드가 긴데 그냥

sqlSessionFactory 선언하기

mybatisConfig.xml 파일 읽어서 sqlSessionFactory에 넣기

get 메소드 구현하기

3단계다.

두 번씩 반복된 건 각 DB별로 구현된 거라 그렇고, 뭐 코드 중복 싫으면 짧게 줄이는 거고…

주의해야 할 점은 sqlSessionFactoryBuilder 부분에 어떤 DB를 가져올 건지, environment에 설정된 id 값을 넣어주는 데 있다.

 

 

마지막으로,

실제 쿼리를 가져다 쓰고 해당 쿼리 결괏값을 불러오는 클래스를 구현한다.

//Table.java 

package mybatisTest.db;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

public class Table {
	
	public void totalCountTable1() {
		List<Map<String, Object>> criteras = new ArrayList<Map<String,Object>>();
		SqlSessionFactory sqlSessionFactory = MybatisConfig.getTableSqlSesionFactory();
		try(SqlSession sqlSession = sqlSessionFactory.openSession(false)) {
			criteras = sqlSession.selectList("conf.Mapper_table.totalCount");
			System.out.println(criteras);
		}
	}
	
	public void totalCountTable2() {
		List<Map<String, Object>> criteras = new ArrayList<Map<String,Object>>();
		SqlSessionFactory sqlSessionFactory = MybatisConfig.getTable2SqlSessionFactory();
		try(SqlSession sqlSession = sqlSessionFactory.openSession(false)) {
			criteras = sqlSession.selectList("conf.Mapper_table2.totalCount");
			System.out.println(criteras);
		}
	}
}

각 DB별로 sqlSessionFactory를 달리 설정했으니 선언해 줄 때 조심하고,

mapper에 박혀있는 namespace와 쿼리 id로 쿼리 실행 및 결괏값을 받아준다.

패키지 구조는 이렇다.

 

실제로 다른 클래스에서 쿼리 값을 사용할 땐 이렇게 사용한다.

package mybatisTest.batchMain;

import mybatisTest.db.Table;

public class MainModule {
	
	public static void main(String[] args) {
		Table table = new Table();
		table.totalCountTable1();
		table.totalCountTable2();
	}
	
}

 

 

전체 패키지 구조는 이렇다.

 

ref) 🔗Clinton Beginmybatis – MyBatis 3 | Configuration

반응형