Clean Code that Works.

하도 오래 전에.. 3~4년 전에 하이버네이트를 봤어서.. 기억이 안난다. -_-;;

스터디 사이트 이제부터는 하이버네이트 사용해서 공부 해볼까 해서, lib 추가 하고 간단한 테스트 클래스를 만들어 보았다.

기선님이 만들어 놓은 GenericDaoHibernateGenericDao가 있어서 이것을 사용하니깐 뚝 딱~(myBatis에서는 GenericMapper를 사용)
봄싹 소스 트랙커가 내려가 있는 관계로 내 스터디 프로젝트에 있는 소스를 링크


중간에 문제점이 있었던건
도메인 클래스의 @Entity를 javax. 패키지로 지정 해야 하는데 hibernate 패키지로 지정해서,
Entity 찾을 수 없다는 오류가 나는 것과 lib 잘 못 받아서난 오류 밖에 없었다.
다행 다행



음. 이전 글을 보면
뭐 dtd하고 설정만 조금 바뀌고 사용하는 방법이 거의 똑같지 않느냐..
그럼 버전이 3.0으로 올라간 의미가 없자나!!!!

하지만.
다른 방법이 있다!!

바로 mapper를 사용 하는 방법!!!

이전 ibatis 는
List<Bbs> bbsList = session.selectList( "mybatis3.model.bbs.select");
위와 같은 형식으로 사용했다.

그럼 맵퍼를 사용하면 어찌 되드냐!!
일단 맵퍼 인터 페이스를 생성.


public interface BbsMapper {
 List<Bbs> getBbsList();
 Bbs getBbs(String id);
}

그 후에 사용하는 코드는
bbsMapper.getBbs( "1Ia6C9h6008");
이렇게 하면 땡 !!

@_@;;
좋다. xml설정에서 select id를 불러 드리는 것이 사라졌다.

xml 설정 파일은 아래와 같이 namespace에 맵퍼 인터페이스를 지정해 주면 된다.
음 편한데~~~

<mapper namespace="mybatis3.mappers.BbsMapper">
 <select id="getBbsList" resultType="net.study.spring.model.Bbs">
  SELECT * FROM Bbs
 </select>
 <select id="getBbs" resultType="net.study.spring.model.Bbs" parameterType="string">
  SELECT * FROM Bbs WHERE ID = #{ID}
 </select>
</mapper>

다음 글은 스프링 3와 통합 및 annotation을 사용한 쿼리 사용에 대해서~~


헉!!!
ibatis가 프로젝트 명을 아에 바꿔 버렸다.
mybatis로!!!

하여 홈페이지도 http://ibatis.apache.org/ 이곳에서 http://www.mybatis.org/ 이곳으로 변경 되었다.
버전도 3.0.1 GA까정 나오고.

메일링 리스트에 가입 할려고 했더니 가입 페이지가 안떠서 일 단 쥐쥐.
코드도 다 코드 구글로 옴겨 갔다.
http://code.google.com/p/mybatis/

네임 스페이스 설정도 바뀌고

New sqlMapConfig.xml DTD:

<!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-config.dtd">

New sqlMap (.map.xml) DTD:

<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD iBatis Mapper 3.0 //EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

여타 자질 구레 한 것들도 바뀌고.. 여튼 좀 바뀌었다 .. -ㅅ-;;
검색해보니 스프링 3에서는 아직 정식 지원이 안되는거 같은데..


뭐 그래도 테스트는 해봐야 하니.

간단히 코드 살펴 보면.

이게 설정 파일

<?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>
 <environments default="development">
  <environment id="development">
   <transactionManager type="JDBC"/>
   <dataSource type="POOLED">
    <property name="driver" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/study?autoReconnect=true"/>
    <property name="username" value="study"/>
    <property name="password" value="study"/>   
   </dataSource>
  </environment>
 </environments>
 <mappers>
  <mapper resource="mybatis3/mappers/TestMapper.xml"/>
 </mappers>
</configuration>

매퍼 설정이 아래와 같이 바뀌었다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD iBatis Mapper 3.0 //EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="mybatis3.model.bbs">
 <select id="select" resultType="net.study.spring.model.Bbs">
  SELECT * FROM Bbs
 </select>
</mapper>

이거슨 테스트 코드.

 @Test
 public void getBbs() throws IOException {
  Reader reader = Resources.getResourceAsReader("mybatis-configTest.xml");
  SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build( reader);
  SqlSession session = sqlMapper.openSession();
  List<Bbs> bbsList = session.selectList( "mybatis3.model.bbs.select");
  for ( Bbs bbs : bbsList) {
   System.out.println(bbs);
  }
  session.close();
 }

응? 빨리 스프링 3하고 통합 해 주셈.


MSSQL이나 MYSQL은 자체 페이징 쿼리가 있어서
페이징이 쉽다.

오라클의 경우에는 보통 rownum을 사용하여 페이징을 처리 한다.
iBatis는 queryForList를 사용하여 리스트형태로 값을 가져 오는데.
여기서 시작값과 끝 값을 지정하여 페이징을 할 수도 있다.
하지만 이런 경우에는 일단 글을 다 긁어 온 다음에
메모리에서 해당 페이지 범위의 글을 가져온다.

이 방법의 경우 글이 작으면 상관이 없지만
글이 늘어 나면서 서버에 부하가 많이 걸린다.
하여튼 queryForList를 사용하여 페이징을 하지 않도록 주의 하고..(난 이걸로 해놨는데.. ㅠ_ㅠ.. 언제 바꿔)

오라클 쿼리를 사용해서 페이징을 처리 하도록 하자.
SELECT num, title, userid, writeday FROM (
   SELECT rownum AS rnum, num, title, userid, writeday
   FROM request
   WHERE userid = #userid#
  ) WHERE rnum BETWEEN #startNum# AND #endNum#
   ORDER BY num DESC

파라미터로 startNum 과 endNum을 넘겨 주면 해당 범위 안의 글을 가지고 온다.
<select id="getList" resultMap="articleListMap" parameterClass="java.util.HashMap" />
- iBatis 설정 파일.

이렇게 하여 지정 범위 안의 글을 가지고 온다.

이렇게 하여 가져온 파일을 게시판 리스트 밑에 페이징 하는 부분이 또 문제.
여기는 잘 생각하여 로직만 정리 하면된다.


if ( pageNum <= 5)
  {
   for ( int i = 0, end = pageModel.getTotalPage(); i < end; i++)
   {
    if ( i >= 10) break;
    pageList.add( i, i + 1 );
   }
  } else {
   for ( int i = pageNum - 5, j = 0; i < pageNum + 6; i++, j++)
   {
    if ( i == pageModel.getTotalPage()) break;
    pageList.add( j, i + 1);
   }
  }

난 위의 방법을 사용하여 처리하였다. 최대 10개씩 보여줄 수 있도록 티스토리 스타일 처럼
이것을 jsp에서 알맞게 보여 주도록 또 가공을 해야 한다.


<c:forEach var="list" items="${ pageModel.pageList }" varStatus="count">
     <c:if test="${ list == pageModel.pageNum }" >
      [<b><span id="movePage" onclick="movePage( this)">${ list }</span></b>]
     </c:if>
     <c:if test="${ list != pageModel.pageNum }" >
      <span id="movePage" onclick="movePage( this)">${ list }</span>
     </c:if>
    </c:forEach>

보통 내가 쓰는 방법.
페이지 로직을 정리 해놓지 않아서.
그때그때 머리를 쥐어 짜서 만드니..
어떤때는 코드가 늘었다가 줄었다가..
-_-;;
로직을 잘 정리하도록 하자.

아이구 머리야.

클래스 상속을 매핑하는 가장 쉬운 방법은 하나의클래스 계층도에 대해 하나의 테이블을 할당 하는 경우.
사용자 삽입 이미지

클래스 다이어 그램


사용자 삽입 이미지

테이터베이스 테이블


모든 클래스들의 프로퍼티를 하나의 테이블에 매핑시키는 것으로,
CAREER 테이블은 Career 클래스, CompanyCareer 클래스 그리고 SchoolCareer 클래스가 갖는 모든 프로퍼티와 매핑될 칼럼을 가지고 있다.





클래스 상속 계층을 하나의 테이블에 넣는 방식은 다음과 같은 장점을 가진다.
장점
- 매핑이 간단하다.
- 성능이 좋다.
단점
- 하위 클래스의 프로퍼트와 매핑될 칼럼은 기본적으로 null이어야 한다.
- 새로운 하위 클래스가 추가될 경우 테이블을 변경해야 한다.