Mybatis - 전체 회원 목록 조회 / resultMap
전체 회원 조회
MemberServiceTest 작성
@Test
@DisplayName("전체 회원 목록 조회 테스트")
public void findAllTest() {
List<Member> members = null;
members = service.findAll();
assertThat(members).isNotNull()
.isNotEmpty()
.extracting("id")
.isNotNull()
.contains("admin1", "admin2");
}
DB에는 회원 2명밖에 없음. admin1 / admin2
일단은 회원이 null이 아닌 것을 알 수 있으니까 테스트 코드 작성하여 확인해보면서 코드를 늘려갔다.
null이 아닌 이유는 객체는 만들어져있고 회원이 없어도 빈리스트를 반환해줄 것이기 때문에.
-
Member 객체 생성
package com.kh.mbatis.member.model.vo;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Member {
private int no;
private String id;
private String password;
private String role;
private String name;
private String phone;
private String email;
private String address;
private String hobby;
private String status;
private Date enrollDate;
private Date modifyDate;
public Member(String id, String password, String name) {
super();
this.id = id;
this.password = password;
this.name = name;
}
}
-
MemberService 작성
- MemberServiceTest에 작성했던 findAll() 메서드 생성
public class MemberService {
private MemberDao dao = new MemberDao();
public List<Member> findAll() {
List<Member> members = null;
SqlSession session = getSession();
members = dao.findAll(session);
// 우리가 TDD에 익숙치 않아서 진짜로 memebrs 를 리턴해주는지 보기 위해 직접 작성해 본 코드
System.out.println(members);
session.close();
return members;
}
}
-
MemberDao작성
- namespace가 memberMapper인 것과 연결하고,
- selectAll이라는 ID를 가진 쿼리문을 실행시키도록 작성
public class MemberDao {
public List<Member> findAll(SqlSession session) {
return session.selectList("memberMapper.selectAll");
}
}
-
mapper.xml 작성
- Dao와 연결 할 쿼리문 작성
- resultType : Member 객체의 풀패키지명 작성
- Member 객체의 필드명과 쿼리문의 아이디가 자동 매핑
- 쿼리문 작성 시 세미콜론(;) 제외
<mapper namespace="memberMapper"> <!-- Dao Session 객체의 첫번째 매개값으로 작성한 namespace -->
<select id="selectAll" resultType="com.kh.mbatis.member.model.vo.Member"> <!-- id도 잘 맞는지 확인하기 -->
SELECT NO,
ID,
PASSWORD,
ROLE,
NAME,
PHONE,
EMAIL,
ADDRESS,
HOBBY,
STATUS,
ENROLL_DATE AS enrollDate,
MODIFY_DATE AS modifyDate
FROM MEMBER
WHERE STATUS = 'Y'
</select>
</mapper>
상태값을 N으로도 수정해서 해보기.
테스트 해보면 테스트가 통과되는데 그 이유는 조회되는 데이터가 없어도 빈리스트를 넘겨주는 것이 확인 가능하다!
ResultMap
- DB 조회 결과와 자바 클래스 매핑
- JDBC 코드를 줄여주는 역할
- type 속성 : resultSet의 결과를 담을 자바 객체 타입 작성
- ex) resultType=”com.kh.mbatis.member.model.vo.Member”
- typeAlias 사용 가능
- typeAlias 미 지정 시, 패키지명부터 클래스명까지 모두 작성 필수
- id 속성 : resultMap의 고유값. select문에서 연결할 때 사용
- 객체의 필드명 / 쿼리문의 ID 맞추기
위 Service에서 print로 찍어본 결과.
다른 것들은 잘 나오는데 enrollDate / modifyDate는 null로 찍힌다.
쿼리문을 실행한 후 나온 resultSet은 자동으로 resultType에 작성한 객체와 자동으로 매핑이 된다.
하지만 아래처럼 Member 객체의 필드명과 쿼리문에 사용한 ID명이 일치하지 않기 때문에 매핑이 되지 않아 null이 찍힌다.
-
일치하지 않는 것이 확인된다. 이 때 두 가지 방법을 사용해서 매핑시켜줄 수 있다.
-
방법 1)
- 쿼리문에서 ‘as 별칭’ 지정하여 사용
- 유지보수 불편
SELECT NO,
ID,
PASSWORD,
ROLE,
NAME,
PHONE,
EMAIL,
ADDRESS,
HOBBY,
STATUS,
ENROLL_DATE AS enrollDate, <!-- 별칭 지정 -->
MODIFY_DATE AS modifyDate <!-- 별칭 지정 -->
FROM MEMBER
WHERE STATUS = 'Y'
필드명을 변경하지 않고 쿼리문을 변경한 이유는..
필드명을 enroll_date로 쓰는 건 관례적으로 사용하는 네이밍 규칙에 어긋나기 때문.
-
방법 2)
- resultMap을 이용하여 명시적으로 매핑
- 이 방법을 추천하셨다.
- 위에 resultMap 작성
- typeAlias를 지정하지 않았기 때문에 type 패키지명과 클래스명을 모두 작성했다.
- property : 객체의 필드명
- column : 컬럼명
- id 태그 : 기본키 매핑
- 나머지는 result 태그 사용
- select 태그에서는 resultMap=”memberResultMap” 작성하여 연결
<resultMap type="com.kh.mbatis.member.model.vo.Member" id="memberResultMap">
<id property="no" column="NO" /> <!-- 기본키 컬럼 -->
<result property="id" column="ID" />
<result property="password" column="PASSWORD" />
<result property="role" column="ROLE" />
<result property="name" column="NAME" />
<result property="phone" column="PHONE" />
<result property="email" column="EMAIL" />
<result property="address" column="ADDRESS" />
<result property="hobby" column="HOBBY" />
<result property="status" column="STATUS" />
<result property="enrollDate" column="ENROLL_DATE" />
<result property="modifyDate" column="MODIFY_DATE" />
</resultMap>
<select id="selectAll" resultMap="memberResultMap"> <!-- resultMap의 id와 맞춰서 매핑 -->
SELECT NO,
ID,
PASSWORD,
ROLE,
NAME,
PHONE,
EMAIL,
ADDRESS,
HOBBY,
STATUS,
ENROLL_DATE,
MODIFY_DATE
FROM MEMBER
WHERE STATUS = 'Y'
</select>