-
7. MyBatis Framework 사용 (수정중)개발자 수업/Spring 2021. 12. 31. 14:39
1. MyBatis 개요
1) 자바 오브젝트와 SQL문 사이의 자동 Mapping 기능 지원하는 ORM 프레임워크임
2) SQL문을 별도 파일로 분리해서 관리
- SQL문과 자바 코드의 분리
- SQL에 변경이 있을 때마다 다시 컴파일하지 않아도 됨
3) SQL을 그대로 이용하면서 도메인 객체나 VO 객체를 중심으로 개발이 가능함
4) 퍼시스턴스 프레임워크
5) XML 형태로 서술된 JDBC 코드라고 할 수 있을 정도로 JDBC 모든 기능을 제공함
6) 데이터소스(DataSource) 기능과 트랜잭션 처리 기능 제공
2. MyBatis3의 주요 컴포넌트
1) MyBatis 설정파일(SqlMapConfig.xml)
- DB 접속 주소 정보, Mapping 파일의 경로 등 고정된 환경정보 설정
2) Mapping 파일(member.xml, board.xml, ...)
- SQL문과 OR Mapping 설정
3) SqlSessionFactoryBuilder
4) SqlSessionFactory
5) SqlSession
- 핵심적인 역할하는 클래스
- SQL실행이나 트랜잭션 관리를 실행함
3. 마이바티스 설정 파일
1) SqlMapConfig.xml
- 데이터베이스 연동 시 반환되는 값을 저장할 빈이나 트랜잭션, 데이터소스 등 마이바티스 관련 정보 설정함
4. SqlSession 클래스에서 제공하는 메서드들
1) List selectList(id)
- id에 대한 select문 실행한 후 여러 레코드를 List로 반환함
2) T selectOne(id)
- id에 대한 select문 실행한 후 지정한 타입으로 한 개의 레코드를 반환함
3) int insert(id, Object obj)
- id에 대한 insert문을 실행하면서 obj 객체의 값을 테이블에 추가함
4) int update(id, Object obj)
- obj 객체의 값을 조건문의 수정 값으로 사용해 id에 대한 update문을 실행함
5) int delete(id, Object obj)
- obj 객체의 값을 조건문의 조건 값으로 사용해 id에 대한 delete문을 실행함5. 마이바티스로 조건값 전달 방법
1) DAO에서 메서드 호출 시 전달된 조건값은 매개변수 이름으로 SQL문의 조건식에 전달
2) SQL문에서 조건값 사용 방법
- #{전달된 매개변수이름}
6. 회원 정보 추가
- HashMap을 이용해서 추가
7. 회원 정보 수정
8. 회원 정보 삭제
9. 동적 SQL문 사용하기
1) SELECT * FROM T_MEMBER
SELECT * FROM T_MEMBER
WHERE ID = 'ezenac'
SELECT * FROM T_MEMBER
WHERE ID = 'ezenac'
AND PWD = '0311'
2) 주로 SQL문의 조건절에서 사용함
조건절 (WHERE)에 조건을 동적으로 추가
JSTL과 XML 기반으로 동적 SQL문 작성
3) 마이바티스 동적 SQL문 구성 요소
- if
- choose(when, otherwise)
- trim
- foreach
4) <if> 태그로 동적 SQL문 만들기
<where>
<if test='조건식'>
추가할 구문
</if>
</where>
5) <choose> 태그로 동적 SQL문 만들기
<where>
<choose>
<when test='조건식1'>
구문1
</when>
<when test='조건식2'>
구문2
</when>
<otherwise>
구문
</otherwise>
</choose>
</where>
6) <foreach> 태그로 회원 정보 조회하기
<foreach item="item" collection="list" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
- collection
전달받은 인자 값을 의미
배열과 List 계열 인스턴스를 전달할 수 있음
- List 인스턴스 전달 시에는 list로 표시함
- 배열 전달 시에는 array로 표시함
- index
접근하는 값의 위치를 나타냄
최초 값의 위치는 0
- item
반복문이 실행될 때마다 collection 속성에 지정된 값이 접근하여 차례대로 사용함
- open
해당 구문이 시작될 때의 지정한 기호를 추가함
- close
해당 구문이 끝날 때 지정한 기호를 추가함
- separator
한 번 이상 반복될 때마다 반복되는 사이에 지정한 기호를 추가함
공통 사용 파일
SqlMapConfig.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> <typeAliases> <typeAlias type="kr.co.ezenac.orm01.MemberVO" alias="memberVO"/> </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="wdsql"/> <property name="password" value="0311"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mybatis/mappers/member.xml"/> </mappers> </configuration>
memberVO.java
import java.sql.Date; public class MemberVO { private String id; private String pwd; private String name; private String email; private Date joinDate; public MemberVO() { // TODO Auto-generated constructor stub } public MemberVO(String id, String pwd, String name, String email, Date joinDate) { this.id = id; this.pwd = pwd; this.name = name; this.email = email; this.joinDate = joinDate; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getJoinDate() { return joinDate; } public void setJoinDate(Date joinDate) { this.joinDate = joinDate; } }
member.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="mapper.member"> <!-- member.xml의 네임스페이스 지정 --> <resultMap type="memberVO" id="memResult"> <!-- SQL문 실행한 후 반환되는 레코드들을 typeAlias 태그에서 지정한 memberVO 빈에 저장함 --> <result property="id" column="id"/> <!-- 레코드의 컬럼 이름에 대해 memberVO의 같은 속성에 값을 설정함 --> <result property="pwd" column="pwd"/> <result property="name" column="name"/> <result property="email" column="email"/> <result property="joinDate" column="joinDate"/> </resultMap> <!-- <resultMap type="java.util.HashMap" id="memResult"> 조회한 레코드를 지정한 컬럼 이름을 Key, 값을 value로 지정 <result property="id" column="id"/> <result property="pwd" column="pwd"/> <result property="name" column="name"/> <result property="email" column="email"/> <result property="joinDate" column="joinDate"/> </resultMap> --> <!-- id : DAO에서 id를 이용해 SQL문을 호출함 --> <!-- resultMap : 반환되는 레코드를 memReslut에 저장함 --> <select id="selectAllMemberList" resultMap="memResult"> <![CDATA[ SELECT * FROM T_MEMBER ORDER BY JOINDATE DESC ]]> </select> <!-- resultType : 문자열로 지정해 SQL문으로 조회한 이름(문자열)을 호출한 메서드로 반환함 --> <select id="selectName" resultType="String"> <![CDATA[ SELECT NAME FROM T_MEMBER WHERE ID = 'ezenac' ]]> </select> <!-- resultType : 속성을 int로 지정해 SQL문으로 조회한 정수를 호출한 메서드로 반환함 --> <select id="selectPwd" resultType="int"> <![CDATA[ SELECT PWD FROM T_MEMBER WHERE ID = 'ezenac' ]]> </select> <!-- resultType : 조회되는 한 개의 레코드를 memberVO에 저장함 --> <!-- parameterType : MemberDAO에서 SQL문 호출 시 전달되는 매개변수의 데이터 타입을 지정 --> <select id="selectMemberById" resultType="memberVO" parameterType="String"> <![CDATA[ SELECT * FROM T_MEMBER WHERE ID = #{id} ]]> </select> <select id="selectMemberByPwd" resultMap="memResult" parameterType="int"> <![CDATA[ SELECT * FROM T_MEMBER WHERE PWD = #{pwd} ]]> </select> <!-- parameterType : dao에서 회원정보를 memberVO의 속성에 저장해서 넘김 --> <!-- values : memberVO의 속성 이름에 저장된 값을 value로 설정함 --> <insert id="insertMember" parameterType="memberVO"> <![CDATA[ INSERT INTO T_MEMBER (id, pwd, name, email) VALUES (#{id}, #{pwd}, #{name}, #{email}) ]]> </insert> <!-- values : HashMap에 각각의 key로 저장된 value를 가져와 테이블에 추가함 --> <insert id="insertMember2" parameterType="java.util.HashMap"> <![CDATA[ INSERT INTO T_MEMBER (id, pwd, name, email) VALUES (#{id}, #{pwd}, #{name}, #{email}) ]]> </insert> <!-- parameterType : SQL문에 사용될 데이터를 memberVO 빈에 설정해 전달함 --> <!-- set ... : memberVO 빈의 속성 값을 각 컬럼의 수정 값으로 설정함 --> <update id="updateMember" parameterType="memberVO"> <![CDATA[ UPDATE T_MEMBER SET PWD = #{pwd}, NAME = #{name}, EMAIL = #{email} WHERE ID = #{id} ]]> </update> <!-- parameterType : 회원 ID는 문자열이므로 parameterType을 String으로 설정함 --> <!-- #{id} : 전달된 ID를 조건 값으로 해당 회원 정보를 삭제 --> <delete id="deleteMember" parameterType="String"> <![CDATA[ DELETE FROM T_MEMBER WHERE ID = #{id} ]]> </delete> <!-- 동적 SQL --> <!-- <select id="searchMember" parameterType="memberVO"> <![CDATA[ SELETE * FROM T_MEMBER ]]> <where> <if test=" NAME != '' AND NAME != null"> NAME = #{name} </if> <if test=" EMAIL != '' AND EMAIL != null"> AND EMAIL = #{email} </if> </where> ORDER BY JOINDATE DESC </select> --> <select id="searchMember" parameterType="memberVO"> <![CDATA[ SELETE * FROM T_MEMBER ]]> <where> <choose> <when test="name != '' AND name != null AND email != '' AND email != null "> NAME = #{name} AND EMAIL = #{email} </when> <when test="name != '' AND name != null"> NAME = #{name} </when> <when test="email != '' AND email != null"> EMAIL = #{email} </when> </choose> </where> ORDER BY JOINDATE DESC </select> <select id="foreachSelect" resultMap="memResult" parameterType="java.util.Map"> <![CDATA[ SELETE * FROM T_MEMBER ]]> WHERE NAME IN <foreach collection="list" item="item" open="(" separator="," close=")"> #{item} </foreach> ORDER BY JOINDATE DESC </select> </mapper>
MemberServlet.java
import java.io.IOException; import java.util.List; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class MemberServlet */ @WebServlet("/mem.do") public class MemberServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doHandle(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doHandle(request, response); } private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=utf-8"); MemberDAO dao = new MemberDAO(); List<MemberVO> membersList = dao.selectAllMembersList(); request.setAttribute("membersList", membersList); RequestDispatcher dispatcher = request.getRequestDispatcher("orm01/listMembers.jsp"); dispatcher.forward(request, response); } }
memberDAO.java
import java.io.IOException; import java.io.Reader; import java.util.List; 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 MemberDAO { public static SqlSessionFactory sqlMapper = null; public static SqlSessionFactory getInstance() { if(sqlMapper == null) { String resource = "mybatis/SqlMapConfig.xml"; //설정 정보를 읽은 후 DB와의 연동 준비함 try { Reader reader = Resources.getResourceAsReader(resource); //마이바티스를 이용하는 sqlMapper 객체를 가져옴 sqlMapper = new SqlSessionFactoryBuilder().build(reader); reader.close(); } catch (IOException e) { e.printStackTrace(); } } return sqlMapper; } public List<MemberVO> selectAllMembersList() { sqlMapper = getInstance(); //실제 member.xml의 SQL문을 호출하는데 사용되는 SqlSession 객체를 가져옴 SqlSession session = sqlMapper.openSession(); //여러 개의 레코드를 조회하므로 selectList() 메서드에 실행하고자하는 SQL문의 id를 인자로 전달함 List<MemberVO> memlist = session.selectList("mapper.member.selectAllMemberList"); return memlist; } }
listMembers.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <c:set var="contextPath" value="${pageContext.request.servletContext.contextPath }"/> <% request.setCharacterEncoding("utf-8"); %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>회원 정보 출력</title> </head> <body> <table border="1" align="center" width="80%"> <tr align="center" bgcolor="#98c8fa"> <td width="%"><b>아이디</b></td> <td width="%"><b>비밀번호</b></td> <td width="%"><b>이름</b></td> <td width="%"><b>이메일</b></td> <td width="%"><b>가입일</b></td> </tr> <c:forEach var="member" items="${membersList }"> <tr align="center"> <td>${member.id }</td> <td>${member.pwd }</td> <td>${member.name }</td> <td>${member.email }</td> <td>${member.joinDate }</td> </tr> </c:forEach> </table> </body> </html>
memberDAO.java
package kr.co.ezenac.orm02; import java.io.IOException; import java.io.Reader; 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 MemberDAO { public static SqlSessionFactory sqlMapper = null; public static SqlSessionFactory getInstance() { if(sqlMapper == null) { String resource = "mybatis/SqlMapConfig.xml"; //설정 정보를 읽은 후 DB와의 연동 준비함 try { Reader reader = Resources.getResourceAsReader(resource); //마이바티스를 이용하는 sqlMapper 객체를 가져옴 sqlMapper = new SqlSessionFactoryBuilder().build(reader); reader.close(); } catch (IOException e) { e.printStackTrace(); } } return sqlMapper; } public String selectName() { sqlMapper = getInstance(); SqlSession session = sqlMapper.openSession(); //selectOne() 메서드로 인자로 지정한 SQL문을 실행한 후 한 개의 데이터(문자열)를 반환함 String name = session.selectOne("mapper.member.selectName"); return name; } public int selectPwd() { sqlMapper = getInstance(); SqlSession session = sqlMapper.openSession(); //selectOne() 메서드로 인자로 지정한 SQL문을 실행한 후 한 개의 데이터(정수)를 반환함 int pwd = session.selectOne("mapper.member.selectPwd"); return pwd; } }
MemberServlet.java
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class MemberServlet */ @WebServlet("/mem2.do") public class MemberServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doHandle(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doHandle(request, response); } private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=utf-8"); MemberDAO dao = new MemberDAO(); String name = dao.selectName(); PrintWriter pw = response.getWriter(); pw.write("<script>"); pw.write("alert('이름 : " + name + "')"); pw.write("</script>"); } }
MemberDAO.java
import java.io.IOException; import java.io.Reader; import java.util.List; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import kr.co.ezenac.orm01.MemberVO; public class MemberDAO { public static SqlSessionFactory sqlMapper = null; public static SqlSessionFactory getInstance() { if(sqlMapper == null) { String resource = "mybatis/SqlMapConfig.xml"; //설정 정보를 읽은 후 DB와의 연동 준비함 try { Reader reader = Resources.getResourceAsReader(resource); //마이바티스를 이용하는 sqlMapper 객체를 가져옴 sqlMapper = new SqlSessionFactoryBuilder().build(reader); reader.close(); } catch (IOException e) { e.printStackTrace(); } } return sqlMapper; } public List<MemberVO> selectAllMembersList() { sqlMapper = getInstance(); //실제 member.xml의 SQL문을 호출하는데 사용되는 SqlSession 객체를 가져옴 SqlSession session = sqlMapper.openSession(); //여러 개의 레코드를 조회하므로 selectList() 메서드에 실행하고자하는 SQL문의 id를 인자로 전달함 List<MemberVO> memlist = session.selectList("mapper.member.selectAllMemberList"); return memlist; } public MemberVO selectMemberById(String id) { sqlMapper = getInstance(); SqlSession session = sqlMapper.openSession(); MemberVO memberVO = session.selectOne("mapper.member.selectMemberById", id); return memberVO; } public List<MemberVO> selectMemberByPwd(int pwd) { sqlMapper = getInstance(); SqlSession session = sqlMapper.openSession(); List<MemberVO> membersList = session.selectList("mapper.member.selectMemberByPwd", pwd); return membersList; } public int insertMember(MemberVO memberVO) { sqlMapper = getInstance(); SqlSession session = sqlMapper.openSession(); int result = session.insert("mapper.member.insertMember", memberVO); session.commit(); //수동 커밋이므로 반드시 commit() 메서드 호출하여 반영해야 함 return result; } }
MemberServlet.java
import java.io.IOException; import java.util.List; import javax.servlet.RequestDispatcher; 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 kr.co.ezenac.orm01.MemberVO; /** * Servlet implementation class MemberServlet */ @WebServlet("/mem3.do") public class MemberServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doHandle(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doHandle(request, response); } private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=utf-8"); MemberDAO dao = new MemberDAO(); MemberVO memberVO = new MemberVO(); String action = request.getParameter("action"); String forwardPage = ""; if(action == null || action.equals("listMembers")) { List<MemberVO> membersList = dao.selectAllMembersList(); request.setAttribute("membersList", membersList); forwardPage = "orm02/listMembers.jsp"; } else if(action.equals("selectMemberById")) { String id = request.getParameter("value"); memberVO = dao.selectMemberById(id); request.setAttribute("member", memberVO); forwardPage = "orm02/memberInfo.jsp"; } else if(action.equals("selectMemberByPwd")) { int pwd = Integer.parseInt(request.getParameter("value")); List<MemberVO> membersList = dao.selectMemberByPwd(pwd); request.setAttribute("membersList", membersList); forwardPage = "orm02/listMembers.jsp"; } RequestDispatcher dispatcher = request.getRequestDispatcher(forwardPage); dispatcher.forward(request, response); } }
listMembers.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <c:set var="contextPath" value="${pageContext.request.servletContext.contextPath }"/> <% request.setCharacterEncoding("utf-8"); %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>회원 정보 출력</title> </head> <body> <table border="1" align="center" width="80%"> <tr align="center" bgcolor="#98c8fa"> <td width="%"><b>아이디</b></td> <td width="%"><b>비밀번호</b></td> <td width="%"><b>이름</b></td> <td width="%"><b>이메일</b></td> <td width="%"><b>가입일</b></td> </tr> <c:forEach var="member" items="${membersList }"> <tr align="center"> <td>${member.id }</td> <td>${member.pwd }</td> <td>${member.name }</td> <td>${member.email }</td> <td>${member.joinDate }</td> </tr> </c:forEach> </table> </body> </html>
memberInfo.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>회원 정보 출력</title> </head> <body> <table border="1" align="center" width="100%"> <tr align="center" bgcolor="#98c8fa"> <td><b>아이디</b></td> <td><b>비밀번호</b></td> <td><b>이름</b></td> <td><b>이메일</b></td> <td><b>가입일</b></td> </tr> <tr align="center"> <td>${member.id }</td> <td>${member.pwd }</td> <td>${member.name }</td> <td>${member.email }</td> <td>${member.joinDate }</td> </tr> </table> </body> </html>
search.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>회원 검색창</title> </head> <body> <form action="${pageContext.request.servletContext.contextPath }/mem3.do"> 입력 : <input type="text" name="value"> <!-- 검색할 값 입력 --> <select name="action"> <!-- 셀렉트 박스의 검색조건을 선택 --> <option value="listMembers">전체</option> <option value="selectMemberById">아이디</option> <option value="selectMemberByPwd">비밀번호</option> </select><br> <input type="submit" value="검색"> </form> </body> </html>
'개발자 수업 > Spring' 카테고리의 다른 글
9. 스프링 어노테이션 (0) 2022.01.04 8. 스프링 트랜잭션 (0) 2022.01.04 6. Spring MVC (0) 2021.12.30 5. AOP (0) 2021.12.29 4. IoC와 DI (0) 2021.12.29