스프링

MyBatis DB 연동 실습 2 - (1) 환경 설정, 부서 전체 목록, 직원 전체 목록

Kiwisae 2022. 10. 6. 12:27

연동 실습(1) 에서 조금 더 발전됐다.

 

 

 

 

실습 예제 프로젝트 파일을 import 완료 하였다.

 

 

 

 

 

환경설정

 

 

1. pom.xml

의존 라이브러리는 한번 추가해두면 이전 프로젝트에서 계속 복사-붙여넣기 하여 사용 할 수 있다.

특별히 추가한 라이브러리는 없다.

 

2. web.xml

1) 어노테이션 설정을 하는 servlet-mapping

2) 수동으로 실행하는 스프링 환경설정 파일 읽어오기 -  servlet-context.xml, root-context.xml

3) post 방식으로 전달되는 한글 데이터를 처리하는 UTF-8 인코딩 설정

 

1), 2)는 프로젝트 파일 생성시 기본으로 들어가 있는 내용이지만 3)은 꼭 직접 추가해주어야 한다.

 

 

 

 

 

3. servlet-context.xml

 

 

base-package="myBatis2"

 

base-package로 설정된 디렉토리 하위의 문서를 스캔하여 설정된 어노테이션에 따른 기능을 수행한다.

그러므로 파일들이 저장될 최상위 디렉토리 경로를 base-package로 설정한다.

프로젝트 생성 시 기본으로 설정되는 값은 com.으로 시작되는 3단계 경로인데, 임의로 지정가능하다.

단, 반드시 java 하위로 지정해야 한다.

 

 

ViewResolver를 등록한다.

view파일을 저장할 최상위 디렉토리 경로를 prefix에 지정하고, suffix에 확장자인 .jsp를 지정한다. 

 

 

 

현재 뷰 파일이 들어있는 디렉토리의 최상위인 views 하위에 emp라는 또다른 디렉토리가 설정되어 있다.

이러한 파일들은 이후 컨트롤러에서 뷰 파일과 연결하기 위한 리턴 값에 해당 디렉토리 이름을 꼭 지정해주어야 한다.

 

 

 

 

 

 

4. root-context.xml

 

DB 연결에 대한 내용이 들어가는 이 파일은

DB 접속이 필요없거나 MyBatis 의존 라이브러리로 연동했던 지금까지는 크게 다루지 않았지만,

이제부터는 DB를 스프링에서 제어해야 하기 때문에 환경설정을 자세히 다뤄보았다.

 

3개의 bean 을 만든다.

 

1)

DB 연동에 필요한 정보가 들어간다.

 

 

 

2)

 

 

일전 실습 때에는 db연동에 대한 내용이 모두 resources의 configuration.xml에 있었지만 

이제는 root-context.xml에 그 내용이 있으므로 configuration.xml에는 DTO Alias에 대한 내용만 남은 상태이다.

 

 

mapperLocations는 mapper 파일의 위치를 설정하는 프로퍼티다.

이 프로젝트에서는 resources 하위의 sql로 경로가 설정되어 있고,

내부에 저장된 파일 중 확장자가 .sql 로 되어 있다면 mapper 파일로 인식하게 된다.

 

 

 

3)

 

 

MyBatis에서 지원하는 기능으로, SqlSession을 상속받는 구현 클래스다.

DAO 클래스에서 @Autowired 어노테이션으로 SQL문 객체 주입이 가능하다.

 

이 객체 생성에 꼭 필요한 기능이다.

 

index="0" : 첫번째 매개변수

ref="sqlSessionFactory" : 2)의 bean id를 참조한 것으로, Constructor DI 방식으로 값을 주입한다.

 

 

어제 했던 MyBatis DB 연동 실습(1) 과 가장 많이 달라진 점이 이 root-context.xml 파일이다.

 

 

 

 

 


 

 

 

환경설정에 대한 내용을 살펴보고 index를 실행해보았다.

오라클에서 실습용으로 기본 제공하는 dept와 emp 테이블에 대한 내용이다.

 

사원이나 부서를 신규 등록하는 insert 기능,

선택한 부서와 사원의 정보를 보여주는 select 기능,

두 테이블을 등가 조인하여 전체 목록을 출력하는 select 기능,

기존의 사원이나 부서의 정보를 수정하는 update 기능이 구현되어 있다.

단, 삭제는 링크는 걸려있으나 기능이 구현되어 있지는 않다.

 

이 프로젝트에 대한 상세 내용을 살펴본다.

 

 

 

 

 

 

 

 

DTO 클래스

 

각 컬럼명의 이름, 개수와 동일한 내용으로 프로퍼티와 메소드가 생성되어 있다.

단, emp에는 기존에 없던 새로운 컬럼이 추가되어 있다.

dept 테이블에만 존재하던 근무지 loc, 부서명 dname 컬럼을 끼워넣은 것이다.

이 deptno 컬럼을 기준으로 두 테이블을 매핑(조인)하여 데이터를 정렬하기 때문에 이 프로퍼티가 추가되었다.

 

테이블이 2개이기 때문에 클래스도 2개이다.

 

 

 

 

아까 잠깐 보고 지나갔던 configuration.xml을 다시 살펴보면

typeAlias로 두 DTO 클래스의 경로와 (type) 별칭이 (alias) 지정되어 있는 것을 확인할 수 있다.

 

 

mapper 파일, 컨트롤러, 서비스, 뷰 페이지 모두 2개씩이다.

테이블이 2개이기 때문이다. 각 테이블을 기준으로 필요한 클래스들을 생성하기 때문에 파일이 2개씩 있다.

 

 

 

 

 

 

인덱스를 실행하면 가장 먼저 요청하는 값은 deptList.do이다.

dept로 시작하므로 두 개의 컨트롤러 중

dept 컨트롤러에 해당 값을 받으면 어떤 기능을 수행할지 설정이 되어 있다.

컨트롤러 클래스를 찾아가본다.

 

 

 

deptList.do 값을 받으면 실행하는 내용이다.

 

부서 목록을 구해오는 SQL문을 실행하여 그 데이터를 List 객체에 담아

뷰 페이지에서 출력하는 내용이 들어있다.

 

여태까지는 단일 테이블의 내용을 출력하는 실습을 했기 때문에

mapper 파일의 namespace에 대한 중요성을 잘 몰랐지만

이 실습을 진행하면서 중요성을 알게 되었다.

두 테이블의 컬럼명 일부가 겹치기 때문에 namespace를 지정하지 않으면 혼동이 생길 것 같다.

 

 

 

 

deptList.do에서 실행하는 SQL문은 다음과 같은 내용이다.

사실 컬럼명과 프로퍼티가 일치하기 때문에 이 프로젝트에서는 굳이 resultMap을 사용할 필요가 없지만

사용 방법을 알아두면 좋을 것 같다.

 

 

값을 구했으니 이제 역순으로 돌아간다.

mapper > DAO > Service > Controller 

 

	@RequestMapping("deptList.do")
	public String deptList(Model model) {
		List<Dept> list = ds.list();
		model.addAttribute("list", list);
		return "deptList";
	}

 

SQL문을 실행하여 얻은 값을 받은 컨트롤러에서는

이 값을 list라는 이름의 리스트 객체에 저장한다.

그리고 model 객체를 통해 deptList.jsp 뷰 페이지로 전달한다.

 

이 뷰 페이지에서는 리스트에 데이터가 있을 경우, 없을 경우로 나누어

forEach 태그를 돌려 테이블 형태로 값을 출력해낸다.

마지막으로 부트스트랩을 이용해 잘 정돈하여 브라우저에 값을 출력하게 된다.

 

 

 

 

결과물

 

 

 

 

 

dept 의 내용을 전체 출력 했으니 (전체 부서 목록)

emp의 내용을 전체 출력 해본다. (전체 직원 목록)

 

전체 직원목록에 걸린 링크의 값은 empAllList.do이다.

emp 컨트롤러로 찾아가본다.

 

 

컨트롤러에서 주의할 점은, 객체를 es, ds 두개를 이용하고 있는데

객체의 개수에 따라 @Autowired도 여러개 필요하다.

 

만일

@Autowired

private EmpService es;

private DeptService ds; 라고 작성하게 되면

EmpService에만 값이 주입되므로 주의해야 한다.

 

 

전체 직원 목록을 가져와 출력하기 때문에 model 외 매개변수는 딱히 없어도 된다.

출력할 데이터를 선별하는 것은 mapper파일의 SQL문, 뷰 페이지에서 작업한다.

 

이때, 주목해야 할 것이 컨트롤러의 return 값인데,

여태까지는 Servlet-context.xml의 ViewResolver에 prefix의 value 값으로 등록한

최상위 디렉토리인 views에 뷰 페이지 파일이 저장되어 있었으므로 별다른 경로를 지정하지 않았지만

emp테이블 관련 뷰 페이지는 views 하위에 따로 디렉토리를 생성하여 저장하고 있다.

때문에 경로를 설정해주어야 한다.

 

 

 

mapper파일을 열어본다.

 

dept, emp 두 테이블의 공통 컬럼인 deptno를 매개로 등가 조인하여

emp 테이블의 전체 컬럼과 dept 테이블의 dname, loc 를 출력하는 내용을 SQL문으로 작성하여

id를 empAllList로 지정해둔 내용이다.

 

resultMap을 지정하여 컬럼과 값을 받는 변수를 매핑한 내용도 들어있다.

컬럼명과 변수명이 같고, 프로퍼티를 DTO에 작성했기 때문에 굳이 작성할 필요는 없다.

 

 

 

필요한 데이터를 선별했으니 역순으로 각 클래스들을 거쳐 컨트롤러에 return 값으로 지정된 

뷰 페이지 empAllList.jsp로 이동한다.