ejyoo's 개발 노트

BoardManagement - ibatis 적용 본문

BackEnd/Java

BoardManagement - ibatis 적용

ejyoovV 2021. 3. 16. 21:36

MVC 패턴을 적용하여 JDBC 코딩한 것을 ibatis 를 사용하여 코드를 변경하려고 한다.

대부분 이전에 작성한 코드를 복사하여 사용하였다.

작성한 코드가 존재하는 경우 복사해서 사용하도록 한다.

 

먼저 JAVA Build Path 에 ibatis와 Ojdbc를 추가한다.

프로젝트 우클릭 - Build Path - Configure Build Path
Add External JARs... - ibatis, ojdbc 추가

 

💡 ibatis가 접근할 DB 세팅

ibatis가 접근할 DB를 직접 세팅한다.

프로젝트 밑에 res폴더를 만든 뒤 res 내에 'SqlMapConfig.properties'를 생성한다.

Source Folder - res 폴더 생성
SqlMapConfig.properties - DB 접근 정보 작성

💡 SqlMapConfig.xml를 생성한다.

SqlMapConfig.xml은 sql관련 설정 파일이다.

 

💡 SqlMapConfig.xml에 코드를 작성한다.


💡 DB 연결정보 properties 파일 경로 설정

properties 태그를 사용하여 DB 연결 정보가 있는 properties를 참조한다.


💡 ibatis 설정 정보를 입력한다.

여기에서 useStatementNamespaces 부분이 있다.

이것을 true로 주게 되는 경우, Namespace를 사용하겠다라는 의미와 동일하다.

Namespace는 패키지와 비슷한 기능을 하므로, 경로에 대한 별명을 지어주는 것이다.

useStatementNamespaces가 false이면, 

나중에 ibatis를 사용할 때 쿼리접근 태그를 사용하는 경우 입력하는 값이 ID로 인식된다. 

예)

smc.insert("member.insertMember", mv);

를 할 때, member를 namespace로 설정했지만, useStatementNamespaces를 false로 주는 경우,

"member.insertMember" 가 id로 인식되어 이에 맞는 쿼리 id를 찾게된다.

(결과적으로는 해당하는 쿼리를 찾지 못하는 상황이 발생할 수 있음)

요즘은 namespace를 사용하는 추세라고 한다.

 


💡 typeAlias 부여 (자주사용하는 패키지에 대한 별명 지정)

자주 사용하는 패키지의 경로가 존재하는 경우,

그 경로에 대한 Alias를 부여한다.

typeAlias는 

vo 클래스 등 이름이 패키지 명까지 기술하는 경우, 길어지게 되는데,

간단하게 사용하기 위해서 alias를 지정한다.

 

형식은 

<typeAlias alias="alias명" type="클래스의 풀네임" />

이렇게 작성하며 

속성의 특성은 아래와 같다.

1) type : 패키지로부터 클래스 파일까지의 경로를 설정함.

2) alias : 경로를 설정한 type에 대한 별명을 지어준다.

이렇게 typeAlias를 사용함으로써 길어진 패키지 경로를 간단하게 축약하여 사용할 수 있게된다.

 

보통 데이터를 담고있는 VO(model)을 Alias로 많이 사용한다.


💡 VO 클래스 생성(Model)

DB에서 사용하는 데이터를 관리하는 VO 클래스를 만든다.

getter, setter 를 생성한다.

toString을 작성한다.


💡 DB 접속정보 설정 영역을 작성한다.

DB 접속 정보를 설정한다.

DB 접속 정보와 커넥션 개수를 설정한다.

여기에서는 이전에 작성한 SqlMapConfig.properties내 기술된 Key, Value값을 읽어서 처리하는 부분이다.

 


💡 ibatis를 제공하는 Util 객체를 생성한다.

SqlMapClientUtil.java에 DB 연결 및 기타 설정 정보가 있는 xml파일을 읽어와서

ibatis를 제공해주는 객체인 smc에 넣어준다.

 

 

 


💡 SQL 쿼리만 작성할는 xml 파일을 생성한다.

sql 쿼리는 따로 모아서 xml 문서에 저장하게 된다.

그 문서를 SqlMapConfig.xml에 연결하여 사용하게 된다.(SQL 쿼리가 있는 XML 파일을 참고하는 경로를 설정해주어야 쿼리를 실행할 수 있다.)

만약 쿼리를 찾지 못한다면 resource 경로가 올바른지 확인해야 한다.

res 폴더에 (없는경우 프로젝트 우클릭 소스폴더 생성)

kr.or.ddit.sqlMap 패키지 내 'board.xml'을 생성한다.

기본 틀

💡 SqlMapConfig.xml에 SQL Query가 담겨있는 xml파일을 연결한다.

ibatis에게 쿼리가 존재하는 xml 을 연결해준다.

이 작업이 없으면 쿼리를 실행할 수 없게된다.


💡 사용할 SQL xml 파일에 대해 namespace를 설정한다.

현재 board.xml은 위치가 kr.or.ddit.sqlMap 안에 존재한다.

이것을 ibatis가 SQL이 담긴 xml을 접근할 때, 

kr.or.ddit.sqlMap을 명시해주어야 접근할 수 있다.

하지만 이것을 써주는 것보단 별명을 짧게 지어주어 경로대신 사용할 수 있다.

단, 이부분은 SqlMapConfig.xml에서 

ibatis를 처리하기 위한 환경 설정 시, 

useStatementNamespaces를 "true"로 주어야 한다는 것을 잊지 말아야 한다.

SQL이 담긴 xml의 namespace 지정
이 부분이 true여야 namespace를 사용 가능함

 

namespaces를 사용하겠다 라는 설정 정보

 

만약, useStatementNamespaces를 false로 주는경우,

나중에 이 쿼리를 호출할 때, 경로명을 적거나

namespace는 설정했는데 저 값이 false여서 해당 sql문을 조회하지 못하게 되므로 유의해야한다.

 

실제 사용되는 부분은 아래와 같다.(글 하단에 해당 내용이 등장할 것이니 이렇게 사용되고 있구나 라고 생각하자.)

위의 사진에서 board.insertBoard 라고 쓰여져 있는 부분이 xml 파일을 접근할 때 사용되는 id 부분이다.

이때 namespaces에 대한 설정을 올바르게 한 경우 board. 라는 것에 대한 경로가 정상적으로 인식될것이다.

올바르게 설정하지 않은 경우 저 board.가 경로로 인식되지 않고 id로 인식된다.

자세한건 글 하단에 내용이 등장할 때 비교하도록 한다.

 


💡 SQL문 작성

ibatis에서는 xml파일에 쿼리를 작성한다고 했다.

ibatis에서 사용할 수 있는 기본 태그가 4개 존재한다.

<select> ~ </select>
<insert> ~ </insert>
<update> ~ </update>
<delete> ~ </delete>

이 태그에 사용되는 속성은 3가지가 있다.

1) id 속성 : 해당 태그를 호출할 때, <sqlMap> 태그의 namespace와 연결하여 사용하는 이름이다.

즉 위의 사진에서 

이 부분이 namespace와 태그의 id가 결합된 것이다.

위의 사진을 예로 들면

board가 namespace이고 

insertBoard, getCheckBoard가 태그에 사용된 id 값이다.

 

2) parameterClass속성 : sql문에 사용될 데이터가 들어있는 객체를 지정한다.

 - 보통 VO 클래스, 자바의 자료형 이름(String, int) 등이 사용된다.

 - typeAlias로 지정한 alias명을 사용할 수 있다.

 - 삽입된 파라미터의 값에 대해 ibatis가 자료형을 추측하여 알고있으므로 생략해도 되지만, 명시적으로 써주는 것이 좋다.

 

이것은 Dao에서 SQL 호출할 때, 넘겨주는 데이터에 대한 객체 타입을 지정해주는 것이다.

예로 하나 살펴본다.

ibatis에서 쿼리 수행 결과 정상이면 null을 떨구므로 null로 성공여부를 확인해아햠. 실패면 Exception 발생함

이것의 연결관계는 다음과 같다

SqlMapConfig.xml내에 작성된  resource 경로를 board.xml 에서 namespace 'board'로 설정 후 

SqlMapConfig.xml 에서 setting useStatementNamespaces=true로 주어 board.xml에 설정한 namespace를 사용가능하도록 했다.

그 다음 boardDao에서 board.xml의 namespace와

board.xml내 insert태그에 작성된 id와 결합하여 

boardDao에서 smc.insert("board.insertBoard" 를 사용하였고,

필요한 데이터가 담겨진 BoardVO bv라는 변수를 넘겨주었다.

ibatis는 namespace가 board이고 id가 insertBoard를 찾은 뒤, 데이터가 담겨진 변수의 타입값을 parameterClass에 명시된 "boardVO"로 확인하게 된다.

 

3) resultClass 속성

select문을 실행한 결과를 담은 객체를 지정한다.

- 보통 VO 클래스나 자바의 자료형 이름을 사용한다.

 

나중에 아래 사진과 같이 사용한다.

게시글이 존재하는지 여부를 판단하기 위해 select 문을 사용했을 때,

출력 결과가 1 이상이면 존재한다는 의미로 사용하기 위해서 

실행할 결과로 int를 사용한 케이스이다.

 

DAO에서 1 개의 결과만 가져오므로 queryForObject를 사용한다.

예1)
예1)

두번째 예로 Select All 사용 시 모든 데이터를 들고와야 하기 때문에

resultClass에 boardVO를 사용하였다.

결과가 1개 이상이므로 queryForList를 사용하였다.

이렇게 쿼리 수행 결과를 어떤 형태로 가져올 것인지를 사용하는 곳이 resultClass이다.


💡 BoardInsert 작성

 

##안에 들어가는 이름은 아무거나 작성해도 좋지만 웬만하면 VO에 기입된 카멜 표기법을 따르도록 한다.

 


updateBoard 작성

##안에 들어가는 이름은 아무거나 작성해도 좋지만 웬만하면 VO에 기입된 카멜 표기법을 따르도록 한다.


deleteBoard 작성

##안에 들어가는 이름은 아무거나 작성해도 좋지만 웬만하면 VO에 기입된 카멜 표기법을 따르도록 한다.


selectAllBoard 작성

##안에 들어가는 이름은 아무거나 작성해도 좋지만 웬만하면 VO에 기입된 카멜 표기법을 따르도록 한다.


checkBoard 작성

##안에 들어가는 이름은 아무거나 작성해도 좋지만 웬만하면 VO에 기입된 카멜 표기법을 따르도록 한다.


SearchBoard 작성

##안에 들어가는 이름은 아무거나 작성해도 좋지만 웬만하면 VO에 기입된 카멜 표기법을 따르도록 한다.

 

 


BoardDao 인터페이스 수정

- select가 1개 일 때, queryForObject 사용

- select가 1개이상일 때, queryForList 사용

 

 


BoardDao implements IBoardDao 수정-insertBoard

 

BoardDao implements IBoardDao 수정-getCheckBoard

 

BoardDao implements IBoardDao 수정-getBoardAll

 

BoardDao implements IBoardDao 수정-updateBoard

BoardDao implements IBoardDao 수정-deleteBoard

BoardDao implements IBoardDao 수정-getSearchBoard

 

 


BoardService 인터페이스

insertBoard

getCheckBoard

 

getBoardAll()

 

updateBoard()

deleteBoard()

getSearchBoard

 

 

 

==

수정 파일은 다 올렸는데. 잡 버그가 많아서

그것을 잡긴했다. 위의 올린 이미지와 코드가 다를 수 있다.

 

==

💡 전체적인 구조 흐름 정리

📝 ibatis를 사용하기 위해서는 jar 파일을 추가한다.

📝 ibatis를 사용하기 위해 DB 정보를 설정을 해야한다.

  - SqlMapConfig.properties

📝 ibatis에 대한 설정을 한다.

  - 디비정보가 있는 SqlMapConfig.properties와 연결한다.

  - ibatis 세팅을 한다 (namespace 사용 true!)

  - VO객체는 typeAlias를 지정해주는 것이 좋다!

  - DB접속 정보를 매핑한다.

  - SQL Query 가 모여있는 xml 파일을 연결한다.

📝 SqlMapClientUtil 을 작성한다.

  - SqlMapConfig.xml파일을 ibais와 연결한다.

📝 쿼리를 작성한다.

  - namespace 결정

  - 쿼리작성(insert, update, delete, selectOne, selectAll)

  - insert, update, delete는 parameterClass

  - select 는 resultMap!

  - DB 컬럼과 VO 객체 연결 시 매핑작업이 필요할 수 있음.

📝 Main 작성한다.

📝 Main에서 Service를 호출한다. 

📝 Service에서 Exception처리를 하고 smc 객체를 얻은 뒤 Dao에 smc를 담아 호출한다.

📝 Dao에서 받아온 smc를 가지고 SQL문이 존재하는 board.xml을 호출한다.

📝 쿼리를 실행한 뒤 board.xml 에서 Dao로 결과값을 가져온다.

📝 Dao에서 결과값을 가지고 Service로 돌려준뒤 Service는 메인으로 돌려준다

  - 리턴값으로 boolean을 사용하는경우 결과값에 대한 세팅은 Dao에서한다.

📝 Main에서 유효성 검사를 하여 성공 시 출력할 메시지를 세팅한다.