고래씌
[MyBatis] 1-2. 로그인 기능 본문
1. 로그인 기능 추가
▶ LoignController.java
▶ Member.java
package com.kh.member.model.vo;
import java.sql.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@NoArgsConstructor
// 매개변수 없는 생성자
@Getter
@Setter
@AllArgsConstructor
@ToString
@Builder
// lombok => 데이터 추가 삭제에 굉장히 편리하다!
// Builder도 사용가능하다!
public class Member {
private int userNo;
private String userId;
private String userPwd;
private String userName;
private String email;
private String birthday;
private String gender;
private String phone;
private String address;
private Date enrollDate;
private Date modifyDate;
private String status;
public void test() {
System.out.println(getUserName());
}
}
1) mybatis 설정정보 읽어들이기 위한 파일 설정하기
① MyBaitsProject 아래에 Source Folder 생성 (resources 폴더 생성)
② mybatis-config.xml 파일 생성
③ https://mybatis.org/mybatis-3/ko/getting-started.html 에서 mybatis-config.xml 파일 복사해서 붙여놓기
④ mybatis-config.xml 설정
☞ 이 문서의 형식이 configuration(환경설정)임을 알려줌 => configuration태그가 전체를 감쌈
DTD : 유효성을 체크해줌(내가 작성한 태그들이 configuration태그안에 존재해도 되는지를 체크해줌)
- settings : MyBatis구동시 사용할 설정들을 작성하는 영역
- typeAlias : VO/DTO클래스들의 풀 클래스명을 단순한 클래스명으로 사용하기 위한 별칭을 등록할 수 있는 영역
- environment : MyBatis에 연동할 db정보들을 등록하는 영역(여러개 db정보 등록 가능)
=> default속성으로 여러개의 id 중 어떤 db를 기본 db로 사용할건지 설정해줘야한다.
- transactionManger : JDBC OR MANAGED 둘 중 하나를 선택할 수 있음
=> JDBC : 트랜잭션 관리를 개발자가 하겠다(수동 commit)
=> Managed : 트랜잭션 관리를 트랜잭션매니저에게 위임하겠다. (자동 commit)
- dataSource : POLLED와 UNPOOLED 둘중 하나를 선택할 수 있음(ConnectionPool 사용여부)
* ConnectionPool : Connection객체를 담아둘 수 있는 영역. 한번 생성된 Connection객체를 담아두면서 재사용함
=> POOLED : ConnectionPool을 사용하겠다.
=> UNPOOLED : ConnectionPool을 사용하지 않겠다.
- property : DB와의 연결정보를 기술하는 영역
- mapper : 실행할 sql문들을 기록해둔 mapper파일들을 등록하는 영역
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--
이 문서의 형식이 configuration(환경설정)임을 알려줌 => configuration태그가 전체를 감쌈
DTD : 유효성을 체크해줌(내가 작성한 태그들이 configuration태그안에 존재해도 되는지를 체크해줌)
-->
<configuration>
<settings>
<!-- 만약 null로 데이터가 전달된다면 빈칸이 아닌 NULL로 인식하겠다는 설정 -->
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<typeAliases>
<typeAlias type="com.kh.memer.model.vo.Member" alias="member" />
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/> <!-- 오라클 정보 -->
<property name="username" value="MYBATIS"/> <!-- DB 이름 -->
<property name="password" value="MYBATIS"/> <!-- DB 비밀번호 -->
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="/mappers/member-mapper.xml"/>
</mappers>
</configuration>
⑥ mappers 폴더 아래에 member-mapper.xml 파일 생성 후, 붙여놓기
2) Template.java 에서 mybatis SqlSession 객체 생성 후 반환하기
▶ 기존 JDBC
① getConection함수 존재 => driver.properties파일을 읽어들여서 해당 db와 접속된 Connection객체를 생성해서 반환
② close함수들 => 전달받은 jdbc객체를 반납시키는 함수
③ 트랜잭션 함수들 (commit, rollback)
▶ mybatis를 이용해서 객체 반환
1단계) new SqlSessionFactoryBuilder() : SqlSessionFactoryBuilder객체
2단계) .build(stream) : 통로로부터 mybatis-config.xml파일을 읽어들임
3단계) .openSession(false) : sqlSession객체 생성 및 트랜잭션처리시 자동 커밋 지정 여부
=> false로 설정시 자동커밋을 하지않음.(수동 처리하겠다!) 기본값은 false
package com.kh.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.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class Template {
// mybatis
public static SqlSession getSqlSession() {
// mybatis 설정정보 읽어들이기
// mybatis-config.xml
// 설정정보안에 저장된 db와 접속하여 SqlSession객체를 생성후 반환할 예정
SqlSession sqlSession = null;
// SqlSession객체를 생성하기 위해서는 SqlSessionFactory객체가 필요
// SqlSessionFactory객체를 생성하기 위해서는 SqlSessionFactoryBuilder 객체가 필요
String resource = "/mybatis-config.xml"; // /는 최상위 폴더(classes).
// mybatis-cofig.xml 파일을 읽어들임
try {
InputStream stream = Resources.getResourceAsStream(resource);
// 1단계) new SqlSessionFactoryBuilder() : SqlSessionFactoryBuilder객체
// 2단계) .build(stream) : 통로로부터 mybatis-config.xml파일을 읽어들임
// 3단계) .openSession(false) : sqlSession객체 생성 및 트랜잭션처리시
// 자동 커밋 지정 여부
// => false로 설정시 자동커밋을 하지않음.(수동 처리하겠다!)
// 기본값은 false
SqlSessionFactory ssfb = new SqlSessionFactoryBuilder().build(stream);
sqlSession = ssfb.openSession(false);
// 섹션객체 생성해서 반환해줌
} catch (IOException e) {
e.printStackTrace();
}
return sqlSession;
}
}
3) LoginController.java (Servlet)
package com.kh.member.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.kh.member.model.service.MemberServiceImpl;
import com.kh.member.model.vo.Member;
/**
* Servlet implementation class LoginController
*/
@WebServlet("/login.me")
public class LoginController extends HttpServlet {
private static final long serialVersionUID = 1L;
public LoginController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Member m = new Member()
.builder()
.userId(request.getParameter("userId"))
.userPwd(request.getParameter("userPwd"))
.build();
Member loginUser = new MemberServiceImpl().loginMember(m);
if(loginUser == null) {
request.getSession().setAttribute("alertMsg", "로그인 실패");
}else {
request.getSession().setAttribute("loginUser", loginUser);
// loginUser라는 키값으로 loginUser 뿌려줌
}
response.sendRedirect("/mybatis");
}
}
4) MemberServiceImpl.java(인터페이스)
▶ MemberService.Impl.java
package com.kh.member.model.service;
import org.apache.ibatis.session.SqlSession;
import com.kh.common.template.Template;
import com.kh.member.model.dao.MemberDao;
import com.kh.member.model.vo.Member;
public class MemberServiceImpl implements MemberService{
private MemberDao memberDao = new MemberDao();
@Override
public Member loginMember(Member m) {
// Connection conn = getConnection();
SqlSession sqlSession = Template.getSqlSession();
Member loginUser = memberDao.loginMember(sqlSession, m);
// close(conn);
sqlSession.close();
return loginUser;
}
}
▶ MemberService.java
package com.kh.member.model.service;
import com.kh.member.model.vo.Member;
// 인터페이스 : 상수필드 + 추상메소드
public interface MemberService {
public Member loginMember(Member m); // 내부에 몸통구현하면 안됨. 묵시적 abstract붙음
}
5) MemberDao.java
① 필요한 변수 세팅
Member m = null;
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = "Select * from Member";
pstmt = conn.preparedStatement(sql);
② 예외처리, 위치홀더 변환, 조회된 결과값(rset)을 VO클래스(Member)로 변환
③ 자원반납 등..
☞ selectOne : 조회결과가 없다면 null값을 반환
☞ sqlSession.sql문 종류에 맞는 메소드("매퍼파일의 namespace.해당 sql문의 id값", sql문을 완성시킬 객체)
return sqlSession.selectOne("memberMapper.loginMember", m); |
6) 다시 member-mapper.xml 로 가서 SQL 쿼리문 작성
▶ namespace : 현재 mapper의 고유한 별칭. 겹치면 안된다!
▶ ★ resultMap ★ : 마이바티스 핵심 기능 중 하나. ResultSet으로부터 조회된 컬럼값을 하나씩 뽑아서 vo객체에 각 필드에 담는 JDBC코드를 대신 수행해 준다.
<resultMap id="식별자" type="조회된 결과를 담아서 반환하고자하는 vo객체의 타입"> <id column="조회결과를 뽑고자 하는 db의 PK컬럼명" property="결과값을 담아줄 필드명"/> <result column="조회결과를 뽑고자하는 DB테이블의 컬럼명" property="결과값을 담아줄 필드명"/> </reusltMap> |
☞ 우리는 mybatis-config 에서 member 별칭등록을 해두었었다.
▶ SELECT문일 경우
<select id="각 sql문들의 식별자" parameterType="전달받은 데이터의 타입 혹은 별칭"
resultType="조회결과를 반환하고자하는 자바타입"
resultMap="조회결과를 뽑아서 매핑할 resultMap의 id">
=> parameterType 속성은 생략가능하다.
=> select문은 반드시 resultType이나 resultMap으로 결과값에 대한 타입을 지정해야한다.
☞ DML문의 경우 어차피 처리된 행의 개수가 반환되기 때문에 생략가능한 것.
☞ ? 대신에 해당 SQL문에 전달된 객체로부터 값을 꺼낼때 #{필드명}, #{변수명}, #{키값}
=> mybatis에서는 ? 대신 #{}, ${} 을 사용한다!
# : preparedstatement방식으로 추가
$ : statement 방식으로 추가
■ member-mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="memberMapper">
<!-- namespace : 현재 mapper의 고유한 별칭. 겹치면 안된다! -->
<resultMap id='memberResultSet' type="member">
<!-- new Member(); -->
<id column="USER_NO" property="userNo" />
<!-- m.setUserNo(rest.getInt("USER_NO")) -->
<result column="USER_ID" property="userId" />
<!-- m.setUserId(rset.getString("USER_ID")) -->
<result column="USER_PWD" property="userPwd" />
<result column="USER_NAME" property="userName" />
<result column="EMAIL" property="email" />
<result column="BIRTHDAY" property="birthday" />
<result column="GENDER" property="gender" />
<result column="PHONE" property="phone" />
<result column="ADDRESS" property="address" />
<result column="ENROLL_DATE" property="enrollDate" />
<result column="MODIFY_DATE" property="modifyDate" />
<result column="STATUS" property="status" />
</resultMap>
<!-- 조회된 결과값을 id='memberResultSet'로 처리된 결과값을 반환하겠다! -->
<!-- mybatis-config에서 별칭등록했던 값을 사용할 수 있음(member) -->
<select id="loginMember" parameterType="member" resultMap="memberResultSet">
SELECT *
FROM MEMBER
WHERE USER_ID = #{userId}
AND USER_PWD = #{userPwd}
AND STATUS = 'Y'
</select>
<!-- # : preparedstatement방식으로 추가
$ : statement 방식으로 추가한다! -->
<!-- #{userId} => get.userID 값을 가져옴 -->
</mapper>
7) menubar.jsp에 alertMsg 등록
■ menubar.jsp
8) 결과화면
'Server > MyBatis' 카테고리의 다른 글
[MyBatis] 3-1. 게시판 설정(페이징 설정) (0) | 2023.12.24 |
---|---|
[MyBatis] 2. 암호화 설정 (0) | 2023.12.24 |
[MyBatis] 1-3. 회원가입 만들기 (0) | 2023.12.20 |
[MyBatis] 1-1. MyBaits 시작(lombok) (0) | 2023.12.19 |
[MyBatis] 0. MyBatis 설정 (0) | 2023.12.19 |