본문으로 바로가기

서블릿에 MyBatis 적용하기

category WEB/Servlet,JSP 2020. 7. 14. 22:26
  • 서블릿을 사용할때 지금까지 DB에 접근하는 DAO 클래스는 단순한 JDBC를 통해 일일히 쿼리문을 작성 해줬지만 Mybatis를 이용하여 코드의 양을 많이 축소할 수있다.
  • SqlSessionFactory 사용하기

    마이바티스를 쓰기 위해선 SqlSessionFactory 객체를 생성해야하는데 SqlSessionFactoryBuilder를 사용하여 생성할 수 있다.

    먼저 SqlSessionFactoryBuilder에서 빌드할 xml 설정파일을 작성해야한다.

  • sqlConfig.xml (MyBatis 설정파일)
    <?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>
      <environments default="development">
        <environment id="development">
          <transactionManager type="JDBC"/>
          <dataSource type="UNPOOLED">
            <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
            <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
            <property name="username" value="mvc"/>
            <property name="password" value="mvcpass"/>
          </dataSource>
        </environment>
      </environments>
      <mappers>
        <mapper resource="com/java/member/model/mapper/MemberMapper.xml"/>
      </mappers>
    </configuration>
    JDBC에서 설정한거 처럼 driver, url, username, password 를 본인의 DB에 맟춰서 작성한다.
  • 작성된 설정파일(xml)을 이용하여 SqlSessionFactory 객체를 생성할 수 있다.
    String resource = "org/mybatis/example/mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    생성된 SqlSessionFactory를 이용하여 후에 SqlSession 객체를 생성하여 직접 DAO와 DB를 연결할 수 있게 된다.
  • 먼저 SqlSession을 사용하기 전 SQL 구문을 사용할 mapper.xml를 설정해야 한다.
    boardMapper.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="com.java.member.model.mapper.MemberMapper">
    
    <!-- DB에서의 컬럼 값이랑 DTO 객체의 필드명이 다를땐 resultMap을 사용하여 매핑시켜준다. -->
        <resultMap type="com.java.member.model.MemberDto" id="member_dto">
            <result column="num" property="num"/>
            <result column="id" property="id"></result>
            <result column="password" property="password"></result>
            <result column="name" property="name"></result>
            <result column="jumin1" property="jumin1"></result>
            <result column="jumin2" property="jumin2"></result>
            <result column="email" property="email"></result>
            <result column="zipcode" property="zipcode"></result>
            <result column="address" property="address"></result>
            <result column="job" property="job"></result>
            <result column="mailng" property="mailing"></result>
            <result column="interest" property="interest"></result>
            <result column="member_level" property="memberLevel"></result>
            <result column="register_date" property="registerDate"></result>
        </resultMap>
    
    <!--     select는 resultType을 명시하지만 insert,update,delete는 내부적으로 제공해주기때문에 명시하지 않는다. -->
        <insert id="member_insert" parameterType="com.java.member.model.MemberDto">
            insert into member values (
                    member_num_seq.nextval, 
                    #{id},
                    #{password},
                    #{name},
                    #{jumin1},
                    #{jumin2},
                    #{email},
                    #{zipcode},
                    #{address},
                    #{job},
                    #{mailing},
                    #{interest},
                    #{memberLevel}, 
                    sysdate
            )
        </insert>
    
    <!--     기본타입의 자료형을 parameterType을 입력할때 앞에 패키지명은 생략가능하다. -->
        <select id="member_id_check" parameterType="String" resultType="String">
            select id from member where id = #{id}
        </select>
    
    <!--     resultType에서 내가 만든 DTO 클래스는 풀패키지명을 작성해주어야 한다. -->
        <select id="member_zipcode" parameterType="String" resultType="com.java.member.model.ZipcodeDto">
            select * from zipcode where dong = #{dong}
        </select>
    
    <!--     parameterType이 HashMap으로 된 이유는 String으로 id, password를 같이 전달해줄수 없으니 
             DAO 객체에서 HashMap으로 키밸류 값으로 전달해주어야 한다. -->
        <select id="member_login" parameterType="HashMap" resultType="String">
            select member_level from member where id = #{id} and password = #{password}
        </select>
    
    <!--     DB에서의 컬럼 값이랑 DTO 객체의 필드명이 다를땐 resultMap을 사용하여 매핑시켜준다. -->
        <select id="member_select" parameterType="String" resultMap="member_dto">
            select * from member where id = #{id}
        </select>
    
        <update id="member_update" parameterType="com.java.member.model.MemberDto">
            update member set 
                password = #{password}, 
                email = #{email}, 
                zipcode = #{zipcode}, 
                address = #{address}, 
                job = #{job}, 
                mailing = #{mailing}, 
                interest = #{interest}
            where num = #{num}
        </update>
    
        <delete id="member_delete" parameterType="Map">
            delete from member where id = #{id} and password = #{password}
        </delete>
    </mapper>
  • 위와 같이 SQL 구문 Mapper가 작성되면 DAO 객체를 만들어 접근 한다.
    public class MemberDao { //Data Access Object
        // singleton pattern : 단 한개의 객체를 가지고 설계한다.
        private static MemberDao instance = new MemberDao();
    
        private static SqlSessionFactory sqlSessionFactory = SqlManager.getInstance();
    
        private SqlSession session;
    
        private MemberDao() {}
    
        public static MemberDao getInstance() {
            return instance;
        }
    
    //    회원가입
        public int insert(MemberDto memberDto) {
            int value = 0;
    
            try {
                session = sqlSessionFactory.openSession();
                value = session.insert("member_insert", memberDto);
                session.commit();
            } catch(Exception e) {
                e.printStackTrace();
            } finally {
                session.close();
            }
    
            return value;
        }
    
    //    회원가입 시 ID 중복체크
        public int idCheck(String id) {
            int value = 0;
    
            try {
                session = sqlSessionFactory.openSession();
                String checkId = session.selectOne("member_id_check", id);
    
                if(checkId != null) value = 1;
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                session.close();
            }
    
            return value;
        }
    
    //    우편번호 목록 불러오기
        public List<ZipcodeDto> zipcodeReader(String checkDong) {
            List<ZipcodeDto> arrayList = null;
    
            try {
                session = sqlSessionFactory.openSession();
                arrayList = session.selectList("member_zipcode", checkDong);
    
            } catch(Exception e) {
                e.printStackTrace();
            } finally {
                session.close();
            }
            return arrayList;
        }
    
    //    로그인
        public String loginCheck(String id, String password) {
    
            String value = null;
    
            try {
                HashMap<String, String> memberMap = new HashMap<String, String>();
                memberMap.put("id", id);
                memberMap.put("password", password);
    
                session = sqlSessionFactory.openSession();
                value = session.selectOne("member_login", memberMap);
    
            } catch(Exception e) {
                e.printStackTrace();
            } finally {
                session.close();
            }
    
            return value;
        }
    
    //    회원정보화면 출력
        public MemberDto updateId(String id) {
            MemberDto memberDto = null;
    
            try {
                session = sqlSessionFactory.openSession();
                memberDto = session.selectOne("member_select", id);
                System.out.println("test    "+memberDto);
            } catch(Exception e) {
                e.printStackTrace();
            } finally {
                session.close();
            }
    
            return memberDto;
        }
    
    //    회원정보 수정
        public int update(MemberDto memberDto) {
            int value = 0;
    
            try {
                session = sqlSessionFactory.openSession();
                value = session.update("member_update", memberDto);
    
            } catch(Exception e) {
                e.printStackTrace();
            } finally {
                session.close();
            }
    
            return value;
        }
    
    //    회원 탈퇴
        public int delete(String id, String password) {
            int value = 0;
    
            try {
                Map<String,String> hMap = new HashMap<>();
                hMap.put("id", id);
                hMap.put("password", password);
    
                session = sqlSessionFactory.openSession();
                value = session.delete("member_delete", hMap);
                session.commit();
            } catch(Exception e) {
                e.printStackTrace();
            } finally {
                session.close();
            }
            return value;
        }
    }
    MemberDAO의 각각의 기능들을 MyBatis로 적용하여 쿼리문을 작성하고 DTO의 데이터를 집어넣는 과정이 매우 간소해졌고 JDBC의 Connection 객체를 사용할 때보다 코드의 수가 매우 줄어드는 이점이 있다.