MyBatis Application Project 작업순서

Posted 2019. 7. 9. 11:24

java application project에서 테스트를 위한 작업순서(in Maven 프로젝트)

 

1. pom.xml 추가

  1.1 mybatis 기본 dependency 추가 

  <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
	<dependency>
	    <groupId>org.mybatis</groupId>
	    <artifactId>mybatis</artifactId>
	    <version>3.4.1</version>
	</dependency>

 

  1.2 config.xml 설정파일 관련 dependency 추가

<!-- https://mvnrepository.com/artifact/commons-configuration/commons-configuration -->
	<dependency>
	    <groupId>commons-configuration</groupId>
	    <artifactId>commons-configuration</artifactId>
	    <version>1.10</version>
	</dependency>
	
	<!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
	<dependency>
	    <groupId>commons-collections</groupId>
	    <artifactId>commons-collections</artifactId>
	    <version>3.2.1</version>
	</dependency>

  1.3 Config.java, ConnectionFactory.java 생성   

-- Config.java --

public class Config {
	private static Configuration configuration;
	 
    static {
        try {
        	URL url = Config.class.getClassLoader().getResource("config/database.xml");
            if (configuration == null) {
				configuration = new XMLConfiguration(url);
            } else {
            	System.out.println("return configuration from Memory...");
            }
        } catch (ConfigurationException e) {
            e.printStackTrace();
        }
    }   
    public static Configuration getConfiguration() {
        return configuration;
    }
}

--  ConnectionFactory.java -----

public class MyBatisConnectionFactory {
	private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            final String resource = "config/mybatis-config.xml";
            Reader reader = Resources.getResourceAsReader(resource);
            if (sqlSessionFactory == null) {
            	Configuration conf = MyConfig.getConfiguration();    			
    			Properties props = new Properties();    			
    			props.setProperty("driver",	 	conf.getString("jdbc.driver","oracle.jdbc.driver.OracleDriver"));
    			props.setProperty("url", 		conf.getString("jdbc.url","jdbc:oracle:thin:@127.0.0.1:1521:orcl"));
    			props.setProperty("username", 	conf.getString("jdbc.username","test2018"));
    			props.setProperty("password", 	conf.getString("jdbc.password","test2018"));
    			
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader, props);
            }
        } catch (FileNotFoundException fileNotFoundException) {
            fileNotFoundException.printStackTrace();
        } catch (IOException iOException) {
            iOException.printStackTrace();
        }
    }
    public static SqlSessionFactory getSqlSessionFactory() {
        return sqlSessionFactory;
    }
}

 

2. TestMain.java 테스트 (Transaction 처리 포함 테스트)

  ...중략...
  
	public static void main(String[] args) {

		SqlSession sqlSession = null;
		try {
			sqlSession = MyBatisConnectionFactory.getSqlSessionFactory().openSession(false);

			//Mapper 사용하는 방법
			TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
			List<Map<String, Object>> progrmList = testMapper.getProgrmList();
			
			//Sqlsession을 사용하는 방법
			List<Map<String, Object>> progrmList = (List<Map<String,Object>>)sqlSession.selectList("getProgrmList");
			
			
			for (Iterator iterator = progrmList.iterator(); iterator.hasNext();) {
				Map<String, Object> map = (Map<String, Object>) iterator.next();
				System.out.println(map);				
			}
			
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("id", "test8");
			param.put("name", "test8 name");
			param.put("age", 88);
			
			testMapper.insertTest(param);
			
			Map<String, Object> param2 = new HashMap<String, Object>();
			param2.put("id", "test5");
			param2.put("name", "test5 update name");
			param2.put("age", 28);
			testMapper.updateTest(param2);
			
			// 커밋
			sqlSession.commit();
		} catch (Exception e) {
			// 롤백
			sqlSession.rollback();
			e.printStackTrace();
		} finally {
			sqlSession.close();
		}
	}

 

 

 

 



Write your message and submit

기존 iBatis를 사용하는 전자정부프레임워크를 myBatis로 컨버팅중에 나온 오류.


returnType="egovMap" 로 선언된 부분에서 Data가 있음에도 불구하고 리턴되지 않아 한참을 고생.


<typeAlias  alias="egovMap" type="egovframework.rte.psl.dataaccess.util.EgovMap"/>


<select id="BBSManageDAO.selectList" returnType="egovMap">

...

</select>


iBatis에서는 정상으로 작동하지만 myBatis에서는 정상작동하지 않습니다.

원인은 myBatis에 추가되는 option설정때문인데요....(iBatis에서는 이 설정이 없는듯 합니다.)


sqlMapConfig.xml 에 다음과 같이 추가합니다.

<configuration>

    <typealias .../>


    <settings>

        <setting name="mapUnderscoreToCamelCase" value="true"/> <== default는 false 임

<setting name="jdbcTypeForNull" value="NULL"/> <== NULL 처리를 위해 NVL, IFNULL 등을 하지 않아도 됨

    </settings>


</configuration>


myBatis에는 의외로 많은 설정들이 존재합니다.  

바꿔말하면 아래의 다양한 옵션들을 환경하에서 개발하다가 Default로 설정된 환경에서 변경할 경우 이전에 잘 돌아가던 코드가 제대로 작동을 하지 않는 경우가 발생할텐데, 이러한 설정의 차이를 인지하지 못할 경우 낭패(엄청난 삽질)를 당할수 있다는 것입니다. 

꼼꼼히 보고 체크해야 할듯 합니다.


아래는 링크는 mybatis공식페이지에 정의된 매퍼설정내용들입니다.


http://www.mybatis.org/mybatis-3/ko/configuration.html

.




Write your message and submit

Spring + myBatis를 이용하여 Oracle DB작업을 하는중 insert문에서 아래와 같은 오류가 발생합니다.

 

error code [17004]; Invalid column type;

 

org.springframework.jdbc.UncategorizedSQLException: Error setting null for parameter #11 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: Invalid column type
; uncategorized SQLException for SQL []; SQL state [null]; error code [17004]; Invalid column type; nested exception is java.sql.SQLException: Invalid column type
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:71)
        at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:365)
        at $Proxy18.insert(Unknown Source)
        at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:237)
        at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:79)
        at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:40)
        at $Proxy27.insertDailyReport(Unknown Source)

 

입력되는 변수들의 값을 디버깅으로 찍어보니 몇몇 컬럼의 값이 null로 넘어갑니다.

이상하다? null을 넣을수 없는건 아닐텐데... 물론 컬럼은 Nullable형태입니다.

 

쿼리와 변수를 조합해서 직접 쿼리를 날리면 정상적으로 insert됩니다.

 

검색을 해보니 myBatis의 특성(?) 때문인것 같습니다.

 

이전 MySQL 을 사용할때는 전혀 고려하지 않았는데, 이상합니다.

 

iBatis, myBatis 모두 Oracle을 사용할때는 다음과 같이 nullable column을 사용하기 위한 처리를 해줘야 합니다.

 

jdbcType=VARCHAR

 

예제를 보면 다음과 같습니다

 

insert into (emp_no, emp_name) values ( #{empNo, jdbcType=INTEGER}, #{empName, jdbcType=VARCHAR})

 

iBatis에서는 다음과 같이 사용합니다.

 

(#id:VARCHAR#, #name:VARCHAR#, #title:VARCHAR#)

 

insert into (emp_no, emp_name) values ( #empNo:INTEGER#, #empName:VARCHAR#)

 

자세한 내용은 아래 사이트에서 참고하면 됩니다.

 

http://mybatis.github.io/mybatis-3/ko/index.html

 

 

 

 

 

 

 

 

 

 

 

 

 

 



Write your message and submit