BLOG ARTICLE 스트럿츠 연동 아이바티스 | 1 ARTICLE FOUND

  1. 2011.08.23 [iBATIS, myBATIS] 1. 스트럿츠 연동 게시판 무작정 따라하기 ( 설정에 관한 모든 것 )



IBATIS 와 Struts를 연동해서 게시판의

DAO(Data Access Object) 퍼시스턴스 계층을 구현해보겠습니다.




일단 IBATIS 를 이용하려면 3개의 JAR 파일을 해당 어플리케이션의 lib 폴더에 넣어줍니다.






           IBATIS 설정파일이 로드되는 순서


IBATIS 가 DB 관련 처리를 구현하기전에 

어떤식으로 설정정보를 로드하는지 크게 4단계의 순서로 
알아 보겠습니다. 

※ IBATIS 는 톰캣이 실행되면서 init 타임에 로드되는것이 아니라
   일반 자바클래스에서 DAO Manager 를 통해서 클래스 호출순간에 로드됩니다.


1. DAOManager 가   DaoManagerBuilder.builderDaoManager(Dao.xml)  통해서

    sqlMapConfig.xml 과   실제 모든 DAO 작업을 처리할 인터페이스와 그것을 구현한 실제클래스를 설정해 놓은 

    Dao.xml 파일을 로드합니다.


(실제 코드는        "IBATISDAO iBATIS = (IBATISDAO)DAOService.getDao(IBATISDAO.class);"   쯤 됩니다. 아래에서 자세히)




2.  로드된 Dao.xml 파일에 설정되어 있는
     sqlMapConfig.xml 파일과 실제 작업을 수행하는 클래스파일(IBATISDAOimpl.java)을 읽어 들입니다.

   

3.  sqlMapConfig.xml  

 디비접속 정보와,

 쿼리들을 처리할 쿼리문들이 코딩되어 있는  sqlMap.xml  파일을 읽어들여서

 sqlMap.xml 안의 ELEMENT 들을 쓸 수 있게  자동으로 처리하여,

 자바코드에서 ELEMENT  ID 를 key 값으로 부르면 사용 가능하도록 처리해줍니다. 





4.  인터페이스를 구현한 실제 수행 클래스  (여기서는 IBATISDAOimpl.java)

이 클래스는 DAO 기능을 수행할 자바코드를 모아놓은 클래스이다.

 
 

여기까지가  아이바티스가 DAO 수행을 위해서 설정 파일들이 로드되는 과정이다.
 
아래에서는 여기 순서에 맞게 1, 2, 3, 4 번  형식을 그대로 따라서 하나하나 따라해보자. 




아래의 과정들은 아래 코드로부터 시작됩니다.
이코드는 스트럿츠 액션클래스에서 해당작업을 수행하는 클래스에서 DAO 작업이 필요할 때 사용될 코드입니다. 

`
IBATISDAO iBATIS = (IBATISDAO)DAOService.getDao(IBATISDAO.class);

_




1. DAO Manager 를 만듭시다.    

DAOService.java
package Struts_BBS;

import java.io.Reader;

import com.ibatis.common.resources.Resources;
import com.ibatis.dao.client.Dao;
import com.ibatis.dao.client.DaoManager;
import com.ibatis.dao.client.DaoManagerBuilder;

public class DAOService {

	private static DaoManager daoManager;
	
	private static DaoManager getDaoManager(){
		
		Reader reader = null;
			
		try{
			
			if(daoManager == null){
				
				reader = Resources.getResourceAsReader("Dao.xml");
				
				daoManager = DaoManagerBuilder.buildDaoManager(reader);
								
			}// end if;
			
		}catch(Exception e){
			
			e.printStackTrace();
			
		}// try end;
		
		return daoManager;
	}
	
	
	
	public static Dao getDao(Class inter){
		
		return (Dao)getDaoManager().getDao(inter);
	}
	
}

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

2. 

22 라인   reader = Resources.getResourceAsReader("Dao.xml");


이 코드처럼 Dao.xml 파일을 읽어들입니다. 

Dao.xml

이 그림 14라인 에 설정된    interface 와 구현한 클래스는 꼭 작성해야합니다. 인터페이스 필수!







여기서 중요한건 인터페이스를 구현하는 클래스는

무조건 "SqlMapDaoTemplate" 클래스를 상속받아야한다.

IBATISDAOimpl.java (구현클래스)





 


3.

reader 로 읽어들인다음 DaoManagerBuilder.buildDaoManager(reader);


하면   10라인에 설정되어 있는 sqlMapConfig.xml 파일을 읽어들여서 

DB접속정보와  실제 모든 쿼리가 들어있는 sqlMap.xml 도 읽어 들입니다. 

읽는 것으로 끝이 아니라, xml 형식으로 작성되어 있는 

ELEMENT 들을 사용가능하도록 자동으로 다 처리해줍니다.
 
 
이런 과정을 다거친 DAO Manager 를 리턴합니다. ( 자바코드 34라인 return daoManager;)


sqlMapConfig.xml

16라인이 모든 쿼리가 들어있는 sqlMap 파일이다. 



sqlMap 파일인 Margo.xml 파일은 너무긴 관계로 맨 아래에 놓겠습니다.





4. 

리턴받은 DAO Manager 인 daoManage
r 에 인자로 넘겨받은 인터페이스를 넣어줍니다.

코드에는 인터페이스지만, 실제로는 구현클래스가 UpCasting 으로 들어가게됩니다.

자바코드 41 라인     (Dao)getDaoManager().getDao(inter)  이 코드가 그것입니다. 



이제는 이렇게 만들어진 DAO Manager 에는 실제적으로는 구현클래스가 작업을 처리하게 되고,

스트럿츠 뷰페이지를 만들기위해서 DAO 가 필요한 작업에는 맨위에서 호출하는 코드를 보셨듯이

`IBATISDAO iBATIS = (IBATISDAO)DAOService.getDao(IBATISDAO.class);_
  필요할 때 는 이 코드를 사용하여 쓰면됩니다. 


 


여기까지가 DAO 처리 수행하는 모든 과정에 해당하는 설정들이 완성되었습니다.

iBATIS 클래스안의 메소드를 이용해서 처리하는 설명은 다음편으로 ~~




아래는 실제 모든 쿼리들이 들어있는 sqlMap.xml 파일입니다.


Margo.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/dao-2.dtd">

<sqlMap>
<!-- Struts_BBS.ItemBean 클래스를 alias 속성을 줘서 artcle 이라는 이름으로 쓰겠다고 정의 -->
<typeAlias alias="article" type="Struts_BBS.ItemBean"/>
<resultMap id="getContent" class="article">
<result property="article_num" column="article_num"/>
<result property="id" column="id"/>
<result property="title" column="title"/>
<result property="body" column="body"/>
<result property="password" column="password"/>
<result property="count" column="hit"/>
<result property="depth" column="depth"/>
<result property="fileName" column="fileName"/>
<result property="write_date" column="write_date"/>
</resultMap>
<parameterMap id="setContent" class="article">
<parameter property="id" jdbcType="VARCHAR"/>
<parameter property="title" jdbcType="VARCHAR"/>
<parameter property="body" jdbcType="VARCHAR"/>
<parameter property="password" jdbcType="VARCHAR"/>
<parameter property="count" jdbcType="NUMBER"/>
<parameter property="depth" jdbcType="NUMBER"/>
<parameter property="fileName" jdbcType="VARCHAR"/>
</parameterMap>
<parameterMap id="setReply" class="article">
<parameter property="article_num" jdbcType="NUMBER"/>
<parameter property="id" jdbcType="VARCHAR"/>
<parameter property="title" jdbcType="VARCHAR"/>
<parameter property="body" jdbcType="VARCHAR"/>
<parameter property="password" jdbcType="VARCHAR"/>
<parameter property="count" jdbcType="NUMBER"/>
<parameter property="depth" jdbcType="NUMBER"/>
<parameter property="fileName" jdbcType="VARCHAR"/>
</parameterMap>
<parameterMap id="editContent" class="article">
<parameter property="title" jdbcType="VARCHAR"/>
<parameter property="body" jdbcType="VARCHAR"/>
<parameter property="password" jdbcType="VARCHAR"/>
<parameter property="article_num" jdbcType="NUMBER"/>
</parameterMap>

<!-- 긴 sql 문이나 자주쓰는 sql문장을 sql 엘리먼트를 이용해서 정의 -->
<sql id="select-all-sql">
SELECT * FROM margo
</sql>

<sql id="where-idx">
WHERE article_num = #article_num#
</sql>


<sql id="select-all-index">
SELECT * FROM 
(SELECT ROWNUM rnum,A.*  
FROM 
(SELECT * FROM margo ORDER BY article_num DESC) A ) 
</sql>
<!-- 여기까지 sql 정의 부분 -->
<!-- SELECT 요청이 들어오면 아이디값을 이용해서 찾은다음 include된 문자를 치환한다음 
    sql 문장을 실행한다. -->
<select id="Allarticles" parameterClass="int" resultMap="getContent">
<!-- <include refid="select-all-sql"/>
ORDER BY article_num DESC
-->
<include refid="select-all-index"/>
WHERE rnum BETWEEN #index#+1 AND #index# + 10
 
</select>

<!-- 총 글 갯수를 가지고 온다 -->
<select id="getCount" resultClass="int">
SELECT COUNT(*) FROM margo
</select>


<!-- 요청된 글 1개를  가지고 온다 -->
<select id="getContent" parameterClass="int" resultMap="getContent">
<include refid="select-all-sql"/>
WHERE article_num = #value#
</select>


<!-- 글 쓰기 -->
<insert id="setContent" parameterMap="setContent" >
INSERT INTO margo 
VALUES(margo_sequence.NEXTVAL,?,?,?,?,?,?,sysdate, ?)
</insert>



<!-- 아이디를 체크하자 -->
<select id="checkID" parameterClass="java.lang.String" resultClass="java.lang.String">
SELECT pass FROM login WHERE id = #id#
</select>




<!-- 리플을 달기전에 다른글 글번호 정리 -->
<update id="reply_articleNumControl" parameterClass="int">
UPDATE margo SET article_num = article_num - 1 WHERE article_num BETWEEN 
(#value# - MOD(#value#, 1000) +1) AND #value#
</update>

<!-- 리플 달기 -->
<insert id="setReply" parameterMap="setReply" >
INSERT INTO margo 
VALUES(?,?,?,?,?,?,?,sysdate, ?)
</insert>




<!-- 글 삭제전 글번호와 글비밀번호 대조 -->
<select id="checkPASS" parameterClass="int" resultClass="java.lang.String">
SELECT password FROM margo WHERE article_num = #value#
</select>

<!-- 글 삭제 -->
<delete id="deleteContent" parameterClass="int">
DELETE FROM margo WHERE article_num = #value#
</delete>



<!-- 글 수정 -->
<update id="editContent" parameterMap="editContent">
UPDATE margo SET title=?, body=?, password=?, write_date=sysdate WHERE article_num=?
</update>



<!-- 글 읽으면 HitUp -->
<procedure id="hitUp" parameterClass="int" >
{call hitUp(#num#)}
</procedure>

</sqlMap>



YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST