Mybatis의 기능으로 DB를 매우 간편하게 조회할 수 있는데
다음의 로그인 예제를 컨트롤러부터 보고 확인해보자.
순서는 controller -> Service -> dao
String userId = request.getParameter("userId");
String userPwd = request.getParameter("userPwd");
System.out.println("userId : " + userId);
System.out.println("userPwd : " + userPwd);
// myBatis는 데이터 한개만 받기 때문에 처리를 해야함
Member m = new Member();
m.setUserId(userId);
m.setUserPwd(userPwd);
// 객체간의 의존성을 줄여줌, Spring의 핵심기능
// 예) Service에서 메소드를 수정하면 Controller에서도 수정을 해야함 -> 의존성이 강하다.
MemberService ms = new MemberServiceImpl();
try {
Member member = ms.selectMember(m);
HttpSession session = request.getSession();
session.setAttribute("loginUser", member);
response.sendRedirect("index.jsp");
} catch (LoginFailException e) {
RequestDispatcher error = request.getRequestDispatcher("WEB-INF/views/common/errorPage.jsp");
request.setAttribute("message", e.getMessage());
error.forward(request, response);
}
컨트롤러에서 Service의 인터페이스 생성, 일반 클래스 객체화 방법을 통해서 호출
JSP 페이지로부터 받은 값 m을 전달한다.
public interface MemberService {
// 로그인용 메소드
// public abstract가 전부 들어가기 때문에 애초에 생략해도 된다.(Interface)
Member selectMember(Member m) throws LoginFailException;
}
import org.apache.ibatis.session.SqlSession;
import com.kh.mb.member.model.dao.MemberDao;
import com.kh.mb.member.model.exception.InsertFailException;
import com.kh.mb.member.model.exception.LoginFailException;
import com.kh.mb.member.model.vo.Member;
import static com.kh.mb.common.Template.*;
public class MemberServiceImpl implements MemberService{
// 자동으로 더 넓거나 같은 접근제한자가 잡힌다.
// 이러한 인터페이스를 사용한 구조는 딱 정해져있는 메소드를 사용하므로(매개변수도 바꿀 수 없다.)
// 행위를 강제한다고 한다.
@Override
public Member selectMember(Member m) throws LoginFailException {
// SqlSession은 MyBatis에서 커넥션 대신 사용
SqlSession session = getSqlSession();
Member member = new MemberDao().selectMember(session, m);
session.close();
return member;
}
}
인터페이스를 이용한 구조로 강제와된 selectMember 메소드드를 통해 Dao에 값을 전달
SqlSession session = getSqlSession();의 SqlSession 객체는 myBatis 라이브러리의 객체이다.
getSqlSession은 myBatis의 SQLSession을 생성하기 위해 공통적으로 이용하는 기능이므로
따로 common에 Template 자바 파일을 만들어 생성/관리 한다.
해당 템플릿 파일은 다음과 같다.
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class Template {
public static SqlSession getSqlSession() {
SqlSession session = null;
try {
InputStream stream = Resources.getResourceAsStream("resources/mybatis-config.xml");
System.out.println(stream);
// openSession 인자에 false를 주면 Auto Commit이 차단 됨
session = new SqlSessionFactoryBuilder().build(stream).openSession(false);
System.out.println(session);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return session;
}
}
Resources.getResourceAsStream("resources/mybatis-config.xml"); 를 통해서 해당 경로에 있는
mybatis-config.xml에 작성 해 둔 설정을 불러와 SqlSession 객체를 생성한다.
mybatis-config.xml 파일은 다음과 같이 쓰여져있다.
<?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>
<settings>
<!-- 만약에 null로 데이터가 전달 되었다면 빈칸이 아닌 null로 인식해라 라는 뜻 -->
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<!-- vo 객체들의 풀 네임을 사용하기 번거롭기 때문에 별칭을 등록하는 부분 -->
<typeAliases>
<!-- 클래스에 대한 별칭 -->
<typeAlias type="com.kh.mb.member.model.vo.Member" alias="Member"/>
<typeAlias type="com.kh.mb.board.model.vo.Board" alias="Board"/>
<typeAlias type="com.kh.mb.board.model.vo.Reply" alias="Reply"/>
</typeAliases>
<!-- DB 연결할 설정에 대한 정보를 선언하는 부분 -->
<environments default="firstDev">
<environment id="firstDev">
<!-- 트랙잭션 매니저는 JDBC 혹은 MANAGED 둘 중 하나를 선택할 수 있음 -->
<!-- JDBC는 JDBC가 commit과 rollback의 기능을 직접 사용 가능하게 하는 옵션(수동 commit) -->
<!-- MANAGED는 트랙잭션에 대해 어떤 영향도 행사하지 않는다는 뜻(자동 commit) -->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="username" value="mybatis"/>
<property name="password" value="mybatis"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="resources/mappers/member-mapper.xml"/>
<mapper resource="resources/mappers/board-mapper.xml"/>
</mappers>
</configuration>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
이 부분은 mybatis홈페이지에서 가져와야 한다.
http://www.mybatis.org/mybatis-3/ko/getting-started.html
위 링크에 가면 자세히 설명이 되어있다
mybatis의 경우 페이지 한글화가 정말 잘 되 있어서
위의 페이지에서 xml 태그들의 설명을 위의 예제와 함께 이해해보자.
예제로 돌아와서 서비스에서
Member member = new MemberDao().selectMember(session, m);으로
SqlSession객체와 로그인 정보를 담고있는 멤버 객체를 Dao에 전달한다.
import org.apache.ibatis.session.SqlSession;
import com.kh.mb.member.model.exception.InsertFailException;
import com.kh.mb.member.model.exception.LoginFailException;
import com.kh.mb.member.model.vo.Member;
public class MemberDao{
public Member selectMember(SqlSession session, Member m) throws LoginFailException {
Member member = null;
member = session.selectOne("Member.loginMember", m);
if (member == null) {
session.close();
throw new LoginFailException("로그인 실패");
}
return member;
}
}
selectMember 메소드에서 m에 담겨있는 정보를
selectOne이라는 mybatis 메소드를 이용하게 된다.
Member.loginMember 이라는 키워드를 통해서
Member라는 해당 namespace로 지정된 xml 파일을 찾아 loginMember에 지정된 쿼리문을 실행시킨다.
그 쿼리문에는 Member 객체를 받아서 이용하게 된다.
먼저 아까 SqlSession에 설정한 mybatis-config xml 파일을 살펴보면
<mappers>
<mapper resource="resources/mappers/member-mapper.xml"/>
<mapper resource="resources/mappers/board-mapper.xml"/>
</mappers>
mappers 태그에 member-mapper.xml이라는 파일을 볼 수 있다.
그리고 member-mapper.xml 파일은 다음과 같이 쓰여져있다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 파일의 별칭 -->
<mapper namespace="Member">
<resultMap type="com.kh.mb.member.model.vo.Member" id="memberResultSet">
<id property="mid" column="MID"/>
<result property="userId" column="USER_ID"/>
<result property="userPwd" column="USER_PWD"/>
<result property="userName" column="USER_NAME"/>
<result property="email" column="EMAIL"/>
<result property="birthDay" column="BIRTHDAY"/>
<result property="gender" column="GENDER"/>
<result property="phone" column="PHONE"/>
<result property="address" column="ADDRESS"/>
<result property="enrollDate" column="ENROLL_DATE"/>
<result property="modifyDate" column="MODIFY_DATE"/>
<result property="status" column="STATUS"/>
</resultMap>
<select id="loginMember" parameterType="Member" resultMap="memberResultSet">
SELECT *
FROM MEMBER
WHERE USER_ID = #{userId}
AND USER_PWD = #{userPwd}
</select>
<insert id="insertMember" parameterType="Member">
INSERT INTO member
VALUES (SEQ_MID.NEXTVAL, #{userId}, #{userPwd}, #{userName}, #{email}, #{birthDay}, #{gender}, #{phone}, #{address}, SYSDATE, SYSDATE, DEFAULT)
</insert>
</mapper>
<mapper namespace="Member">
namespace가 Member로 설정되서
session.selectOne("Member.loginMember", m);라는 메소드에서 이 xml까지 찾아와서
<select id="loginMember" parameterType="Member" resultMap="memberResultSet">
SELECT *
FROM MEMBER
WHERE USER_ID = #{userId}
AND USER_PWD = #{userPwd}
</select>
id가 loginMember 라고 지정되어 있는 이 쿼리문을 사용하게 된다.
parameterType과 resultMap, #{userId} 등 특이한 키워드들이 보이는데
이에 대한 설명은 myBatis xml 파일을 설명하는 게시글에서 추가로 한다.
참고로 mybatis 홈페이지에도 충분히 이해하기 쉽게 설명이 되어있다.
xml에 지정해놓은 여러가지 키워드들을 통해서 DB를 조회하고 값을 리턴하게 된다.
'Spring Framework, MyBatis > 02. 사용법' 카테고리의 다른 글
[Spring Framework]02-11.Spring Framework에서의 서블릿 연결 원리 (0) | 2019.01.31 |
---|---|
[MyBatis]02-10. Mybatis에서 사용하는 xml 키워드 간단 설명 (0) | 2019.01.27 |
[MyBatis]02-08. FrontController를 통한 페이지 맵핑 관리 (0) | 2019.01.20 |
[MyBatis]02-07. 인터페이스를 통한 Framework 구조 (0) | 2019.01.20 |
[MyBatis]02-06. JSP Exception 오류 처리 (0) | 2019.01.20 |