실행환경

window10

스프링부트 
Intellij 
Mybatis 3.4.6 
Maven3



IDE위에서는 전부 정상적으로 실행되는데

배포파일로 실행하면 문제가 생긴다.

mvn package 로 jar 파일로
java -jar demo.jar 이렇게 실행하면 
TypeAliasePackage를 못찾고 에러가 뜬다



정말 기묘한 에러였다.


이렇게 TypeException을 던지고 실행이 안됨






해결방법




스프링 부트이면 저렇게 SpringVFS을 설정에 세팅해주면 바로 해결된다.



또다른 방법은 pom.xml에 라이브러리 추가






해결방법 출처 


해당 에러 해결법 제공

https://bluesky-devstudy.blogspot.com/2016/06/spring-boot-war-mybatis-typehandler.html


Mybatis 커뮤니티  질문 

https://www.facebook.com/groups/mybatis/permalink/1960436807309419/?comment_id=1960536903966076



첫번째 url에서는

스프링부트에서 

버젼 java8 mybatis3.4 이후 
typeHandler scan은 없다고 되어있는데

해당 문제가 해결되었다고 써있었지만


나는 java8 mybatis3.4.6 springboot1.5.3 &2.x.x 
환경에서도 같은 문제가 발생했다


차이점은 

윗 url에서는 war로 배포했고

나는 jar로 배포했다는 점이다






'Programming > Mybatis' 카테고리의 다른 글

SqlSessionFactory 와 Builder의 구분  (0) 2018.06.12
Mybatis JavaConfig 설명  (0) 2018.06.08
mybatis 핵심 기능 mapper.xml 부분  (0) 2017.03.13
Mybatis 에 대한 정리  (0) 2017.01.21


집가는데 친구가 이런 질문을 던졌다. 


설명해주는김에 


마이바티스를 예제로 들어서 설계 관련 내용을 써보았다.




우선 위에 질문에 대한 정답은 



SqlSessionFactoryBuilder 개발자들을 위한 ,단순히 가독성을 좋은 소스코드를 작성하기위한

객체이다.

객체는 서버를 최초 1 실행시에 SqlSessionFactory 생성하는데 한번 쓰이고

사라지는 객체이다.




이거 이외에  설명을 좀 길게하려했는다.




한번의 db 요청하려면 SqlSession 사용해야한다 써야된다.

Session이란 인스턴스안에 있는 논리적인 실체로 현재 유저의 로그인 상태를 말한다


우리가 서블릿 공부할때 쓰는 Session Cookie 과 같은  그 세션의 개념이다. 



JDBC 프로그래밍에서

Connection con= DriverManager.getConnection(url, id, pw);

이코드로 Db 접속해있는 하나의 논리적인 연결 상태를 의미하는것


Conntection이란 단순히 물리적(네트워크) 연결을 말하는


SqlSession이란 RDB에 인증을 거친 논리적인 연결 상태를 말하는 것이다.



하나의 SqlSession 만들기 위해서는

jdbc프로그래밍에서 필요한것처럼 기본적으로


1. Url

2. Id

3. password


3개의 정보가 필요하고 

이외에도

Mybatis에서는


캐싱정책의 사용유무,

지연 로딩 등등


많은 설정 정보들이 존재한다.

 

이러한 정보들을 SqlSession 생성할때마다 전부 다시 정의하는 것은 매우 힘들다.


이거는 마치 JDBC 로 db 접속할때


매번 id pw url을 그때그때 서블릿 클래스마다 클래스내 전역변수로 지정해주는 것처럼 번거로운 일이다.



그렇기 때문에 이러한 설정값들을

한곳에 모아놓고 모아놓은 곳에서 객체를 가져오는 것이 효율적인데

이것이 SqlSessionFactory 이다



mybatis 의  DefaultSqlSessionFactory  클래스 내부 모습 

정말 별거 없다  


 

여기서 문제가 더 있다.


SqlSessionFactory 만들기위해서는 엄청 많은 정보들을 넣어줘야하는데 (id url AliasesPackage.....)

이거를 그냥 인스턴스를 쉽게 생성자를 사용해서 

new SqlSessionFactory() 이렇게 만드는 거는

매우 불안하다 


왜냐면 "생성자 인자가 많은 경우에는 Constructor 방식은 가독성이 매우 떨어진다"

--Effective Java edition2 규칙2 생성자 인자가 많을때는 

Builder패턴 적용을 고려하라 page16 --

 

그렇기에 이런경우에는 디자인패턴중에서  BuilderPattern 사용하는데

이것이 SqlSessionFactoryBuilder이다.

 

SqlSessionFactoryBuilder 내부 소스코드 




SqlSessionFactoryBuilder 개발자들을 위한 ,단순히 가독성을 좋은 소스코드를 작성하기위한

객체이다.

객체는 서버를 최초 1 실행시에 SqlSessionFactory 생성하는데 한번 쓰이고

사라지는 객체이다.






'Programming > Mybatis' 카테고리의 다른 글

Mybatis Springboot TypeHandler 배포 에러  (0) 2018.06.27
Mybatis JavaConfig 설명  (0) 2018.06.08
mybatis 핵심 기능 mapper.xml 부분  (0) 2017.03.13
Mybatis 에 대한 정리  (0) 2017.01.21



마이바티스를 사용하여 db에 접속된 세션을 얻기 위해서는 


SqlSessionFactory 가 필요하다 


이거를 만드는 방법은 여러방식이 있는데 


SqlSessionFactoryBuilder를 이용해서 mybatis-config.xml을 가져와서 만드는 방법도 있지만 


XML 을 배척하는 JavaConfig를 선호함으로 다른 방식을 사용하겠다.


Mybatis-Spring  라이브러리를 사용하면


SqlSessionFactoryBean 이 있는데 

이 객체를 사용하면 mybatis-config.xml 파일 없이도

클린한 JavaConfig 를 구성할수있다.




import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.BooleanTypeHandler;
import org.apache.ibatis.type.DateTypeHandler;
import org.apache.ibatis.type.TypeHandler;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

@Configuration
@MapperScan(value="org.prj.arachne.infrastructure.mapper")
public class MybatisConfiguration {

@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource)throws Exception{
SqlSessionFactoryBean sessionFactory=new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);

Resource[] res=new PathMatchingResourcePatternResolver()
.getResources("classpath:/mappers/*_mapper.xml");

//sessionFactory.setEnvironment("dev");

sessionFactory.setMapperLocations(res);
sessionFactory.setTypeAliasesPackage("org.prj.arachne.domain");
sessionFactory.setTypeHandlers(new TypeHandler[] {
new DateTypeHandler(),
new BooleanTypeHandler()
});


return sessionFactory.getObject();
}

/**
* 마이바티스 {@link org.apache.ibatis.session.SqlSession} 빈을 등록한다.
*
* SqlSessionTemplate은 SqlSession을 구현하고 코드에서 SqlSession를 대체하는 역할을 한다.
* 쓰레드에 안전하게 작성되었기 때문에 여러 DAO나 매퍼에서 공유 할 수 있다.
*/
@Bean
public SqlSessionTemplate sqlSession(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}







}


  

@MapperScan : @Mapper 인터페이스들의 패키지 위치를 선언하는 설정이다.


sqlSessionFactoryBean 에서 


Datasource : 데이터베이스 접속을위한 계정, db드라이버, 비번 과 같은 정보들 

MapperLocation  : sql 들이 들어있는 xml 파일들의 위치를 지정한다


위 설정을 가지고 

userMapper.java(인터페이스) 와 user_mapper.xml 이렇게가 한쌍이되어서 

mybatis가 구현체를 알아서 생성해준다. 


TypeAliasesPackage : 디비에서 가져온 데이터들을 담을 자바 빈들이 모여있는 패키지 등록    쉽게말하면 MVC 패턴에서 Model에 해당하는 패키지를 등록하는 것이다.


추가 옵션 설정은 이렇게 해주면된다 

다양한 옵션들은 mybatis공식 사이트 들어가서 확인해보시기를 



Properties properties = new Properties();
properties.setProperty("mapUnderscoreToCamelCase", "true");
sessionFactory.setConfigurationProperties(properties);



'Programming > Mybatis' 카테고리의 다른 글

Mybatis Springboot TypeHandler 배포 에러  (0) 2018.06.27
SqlSessionFactory 와 Builder의 구분  (0) 2018.06.12
mybatis 핵심 기능 mapper.xml 부분  (0) 2017.03.13
Mybatis 에 대한 정리  (0) 2017.01.21



mybatis 는 정말로 쉽다.


러닝커브가 매우 짧으며 


그 투자된 학습시간에 비해  높은 생산성을 보인다   


단순 문자열로 SQL 이라는 중요한 소스코드를 관리한다는 것은 큰 문제가 있다.


Mybatis는 SQL문을 자바소스코드에서 분리함과 동시에 


SQL 문을 재사용 가능하게 하며

SQL 문을 파일로 분리하여 유지보수성을 높히며

도메인 과 릴레이션의 매칭을  통해 oop와 sql간 사상차이를 극복할수있게 도와준다.



 




위 파일중 mapper.xml 파일 한개를 가져왔다 

이 소스코드를 훑어보면서 mybatis사용법을 익혀보자


<?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">


mybatis mapper 파일임을 정의 하고 있다.

<!DOCTYPE mapper

.. 이하생략 ..   .dtd>

이라고 문서 타입을 정의하므로서 

해당 문서 타입에 벗어나는 문법을 잡아서 빨간줄을 띄워줌으로서

우리는 mybatis 문법에 대한 에러를 잡을수있다.



<mapper namespace="com.kimsoungryoul.persistence.myblog.studyBoardMapper">


해당 매퍼파일의 고유한 이름을 정의하고있다.

우리는 namespace에 정의된 값으로 통해 자바클래스에서 쿼리문을 가져다 쓸수있다.

마치 int a=5;

prinf("%d",a); 라는 코드에서 a 라는 고유한 변수명으로 5라는 값을 가져다 쓰듯이

 com.kimsoungryoul.persistence.myblog.studyBoardMapper 라는 고유값을 통해 

해당 mapper 아래 여러 쿼리문들을 가져다 쓰는것이다.



<insert id="insert">    

INSERT INTO studyboard

(writer, title,subtitle,

contents)

VALUES

(#{writer}, #{title}, #{subTitle}, #{contents})

</insert>

쿼리문 작성.. 우리는 해당 쿼리문을 

com.kimsoungryoul.persistence.myblog.studyBoardMapper.insert라는 id값을 추가하여 가져다쓸수 있다. 




<select id="get" resultMap="BoardResultMap">

SELECT * FROM studyboard

where

no=#{no}

</select>



<select id="list" resultMap="BoardResultMap">

SELECT * FROM studyboard

where no > 0

order by regdate desc

limit #{pageStart}, #{perPageNum}

</select>



<select id="searchlist" parameterType="hashmap" resultMap="BoardResultMap">

select B.* from studyboard B

inner join tbl_hashtag H

on

H.tag=#{keyword} AND B.no=H.b_no

order by regdate desc 

limit

#{pageStart}, #{perPageNum}

</select>



<update id="update">

UPDATE studyboard

SET

modifieddate = #{modifiedDate},

writer = #{writer},

title = #{title},

contents = #{contents}

WHERE no =

#{no}

</update>



<delete id="delete">

DELETE FROM studyboard

WHERE no=#{no}

</delete>


<delete id="deleteAll">

DELETE FROM studyboard

</delete>


<select id="getB_no" resultType="Integer">

select no from studyboard

where

no=LAST_INSERT_ID()

</select>




<update id="likePlus">

UPDATE

studyboard

SET

likecnt=likecnt + 1

WHERE

b_no=#{b_no}

</update>



<update id="viewplus">

UPDATE

studyboard

SET

viewcnt=viewcnt + 1

WHERE

b_no=#{b_no}

</update>




<resultMap id="BoardResultMap" type="StudyBoard">

<id property="no" column="no" />

<result property="regDate" column="regdate" />

<result property="modifiDate" column="modifidate" />

<result property="title" column="title" />

<result property="subTitle" column="subtitle" />

<result property="writer" column="writer" />

<result property="contents" column="contents" />

<result property="likeCnt" column="likecnt" />

<result property="replyCnt" column="replycnt" />

<result property="viewCnt" column="viewcnt" />

<collection property="hashTagList" select="selectHashTag"

column="{no=no}" javaType="java.util.ArrayList" />

<collection property="attachmentList"

select="com.kimsoungryoul.persistence.study.boardAttachmentMapper.list"

column="{sb_no=no}" javaType="java.util.ArrayList" />

</resultMap>


<insert id="insertHashTag" parameterType="hashmap">

INSERT INTO tbl_hashtag (b_no, tag)

VALUES

<foreach collection="hashTagList" item="tag" open="" close=""

separator=",">

(LAST_INSERT_ID(), #{tag})

</foreach>

</insert>


<select id="selectHashTag" resultType="String">

select tag from

tbl_hashtag

where b_no=#{no}

</select>


<select id="hashTagListInBoardMenu" resultType="HashTagDTO">

select tag, count(tag) as tagcnt from tbl_hashtag group by tag order by count(tag) desc limit 0,4

</select>



<delete id="deleteHashTag">

delete from tbl_hashtag

where b_no=#{no}

</delete>


<delete id="deleteAllHashTag">

delete from tbl_hashtag

</delete>




<sql id="whereSql">

<where>

<if test="title != null and title !='' ">

AND title = #{title}

</if>

<if test="subTitle !=null and subTitle!=''">

AND subtitle=#{subTitle}

</if>

<if test="writer != null and writer !='' ">

AND writer = #{writer}

</if>


<if test="contents!=null and contents != '' ">

AND contents=#{contents}

</if>


<if test="no !=null and no !=0 ">

AND no= #{no}

</if>

</where>

</sql>



</mapper>














'Programming > Mybatis' 카테고리의 다른 글

Mybatis Springboot TypeHandler 배포 에러  (0) 2018.06.27
SqlSessionFactory 와 Builder의 구분  (0) 2018.06.12
Mybatis JavaConfig 설명  (0) 2018.06.08
Mybatis 에 대한 정리  (0) 2017.01.21

아이바티스(ibaits)는 아파치 재단에서 진행되던 오픈소스 프로젝트로 


프로젝트 팀원들이 구글 코드로 이전하면서  ibatis 는 개발이 중단 되었다.

(사실상 개발 중단이 아닌 프로젝트 소속기관을 이전하면서 이름만 변경된 것이다 )


구글 코드로 이전하면서 ibatis는 새롭게 이름을 다시 지었는데 


이것이 Mybatis 다.


-what different?-





마이바티스는 객체지향 언어인 자바의 관계형 데이터 베이스 프로그래밍을 좀더 쉽게 할수 있게 도와주는 개발 프레임워크이다. 자바에선 데이터베이스 프로그래밍을 하기 위해 JDBC(자바에서 제공하는 데이터베이스 프로그래밍 API)를 제공하고, JDBC는 관계형 데이터 베이스를 사용하기 위해 다양한 API를 제공한다.

( ORM (Object Relational Mapping) 에서 대표적으로 mybatis , hybernate 가 있다.  ) 


-------------------------------------------------

ORM은 무엇이며 우리는 왜 ORM을 사용해야만 하는가?


http://kimsoungryoul.tistory.com/7

----------------------------------------


다양한 관계형 데이터베이스를 지원하기 위해 JDBC는 세부적인 작업이 가능하게 작업별로 각각의 메소드를 호출하게된다. 이러한 사항들은 다수의 메소드를 호출하고 관련된 객체를 해제해야하는 단점이 있다.

Mybatis는 JDBC보다 좀더 편하게 사용하기 위해 개발 되었다.



Mybatis 의 대표적 특징은 SQL문을 분리하는 


SQL Maper 프레임 워크라는 점이다.







mybatis 관련 참고 이미지 (이해 안가면 그냥 넘겨도 무방하다)




SQL을 분리한다는 것은 무엇인가?



JDBC 로 데이터베이스로 접속하는 프로그래밍을 한다면 





.............

pstmt = conn.prepareStatement("select * from board");     

.............





이런 식으로 쿼리문이 자바 소스코드안에 문자열로 취급되어 들어간다



여기서 JDBC 프로그래밍의 문제점이 보인다


1. SQL과 자바는 서로 다른 언어이다. 


이 두가지가 한 파일(또는 클래스) 내에 섞여 있다는 것은 

굉장히 껄끄러운 문제점이다. 


객체지향 프로그래밍은 각 메서드 클래스별 하나의 책임(SRP)을 맡길 것을 권장하는데


역활이 두가지인것도 아니고 무려 두가지 언어가 뒤섞였다는 점은 

개발자들의 기분을 매우 찜찜하게 만든다.


 2. 객체지향적? SQL 작성의 어려움 


대게 처음 배우는 사람들은 무의식중에 클래스 - 테이블 을 1대1 매칭 시키면서 


공부를 한다.  그러나  1:n 문제 m:n 같은 문제에 부딪치면서 


기존에 1대1매칭 시키던 자신의 사상에 큰 고민을 하기 시작한다.


여러 테이블을 join 하여  어느 정도 해결할수 있더라도 

n:m 과같은 문제는 깔끔한 sql 로 해결 할수 없다.


mybatis는 sql 문을 객체지향적? 으로 쓸수 있게 여러 기능 들을 제공한다. 









쿼리문을 xml 로 분리한 mybatis 프로그래밍 중 일부이다. 

mybatis는 xml 로 쿼리문을 따로 관리하고  자바의 DAO 클래스(Persistence계층)들은 필요한 쿼리문을 이곳에서 불러서 사용한다.


mybatis의 핵심은 이것이다.


.


이것은 xml 으로 분리한 sql 문을 불러 쓰는 DAO 클래스의 일부이다. 

'Programming > Mybatis' 카테고리의 다른 글

Mybatis Springboot TypeHandler 배포 에러  (0) 2018.06.27
SqlSessionFactory 와 Builder의 구분  (0) 2018.06.12
Mybatis JavaConfig 설명  (0) 2018.06.08
mybatis 핵심 기능 mapper.xml 부분  (0) 2017.03.13

+ Recent posts