spring - 마이바티스 프레임워크
등장 배경
기존의 JDBC 코드의 과정을 보면 복잡하다.
과정 : connection -> Statement 객체 생성 -> SQL문 전송 -> 결과 반환 -> close
이렇듯 SQL문이 프로그래밍 코드에 섞여 있는 모양이라 코드를 복잡하게 하고, 사용 및 유지 보수가 어렵게 만든다
마이바티스 프레임 워크는 SQL문의 가독성을 높여 사용이 편리하게끔 만들었다. 코드와 SQL문을 분리해 사용 및 유지 보수를 편리하게 한 것.
특징
- SQL 실행 결과를 자바 빈즈 또는 Map 객체에 매핑해주는 Persisitance 솔루션으로 관리한다 -> 즉, SQL을 소스코드가 아닌 XML로 분리하는 것
- SQL문과 프로그래밍 코드를 분리해서 구현한다
- 데이터소스(DataSource) 기능과 트랜잭션 처리 기능을 제공한다.
실습해보기 01 - 회원정보 조회
마이 바티스 관련 설정 파일
- SqlMapConfig.xml : 데이터 베이스 연동시 반환되는 값을 저장할 빈이나 트랜잭션, 데이터소스 등 마이바이스 관련 정보를 설정한다
- member.xml : 회원 정보 관련 SQL문을 설정
- 파일 모양 (SqlMapConfig는 myatis패키지에 / member.xml은 mybatis/mappers 패키지에 위치해있다)
SqlSession 클래스에서 제공하는 여러 메소드
1. SqlMapConfig.xml 작성
<dataSource>
태그를 이용해 마이바티스가 연동하는 DB에 대한 데이터 소스 설정<mappers>
태그를 이용해 마이바이스에서 사용하는 SQL문이 있는 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>
<!-- DAO에서 SQL문으로 값을 전달할 때
또는 SQL문을 실행한 후 가져온 값을 DAO로 전달할 때 사용할 빈을 생성한다 -->
<typeAliases>
<!-- type : "위치" alias="사용할 것" -->
<typeAlias type="com.spring.ex01.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="System" />
<property name="password" value="hb0317vd"/>
</dataSource>
</environment>
</environments>
<!-- 회원 기능 관련 SQL문이 있는 member.xml을 읽어들이기 -->
<mappers>
<mapper resource="mybatis/mappers/member.xml" />
</mappers>
</configuration>
2. member.xml 작성
<mapper namespace="">
: member.xml의 네임 스페이스슬 지정<resultMape type="" id="">
: SQL문을 실행한 후 반환되는 레코드들을 SqlMapConfig.xml에서 typeAlias태그에 지정한 memberVO빈에 저장하겠다<result property="" column="">
: 레코드의 컬럼 이름에 대해 memberVO와 같은 속성 값을 지정<select id="" resultMap="">
: id는 DAO에서 id를 이용해 해당 SQL문을 호출하고 / resultMap은 반환되는 레코드를 memResult에 저장할 것이다.
<?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">
<!-- member.xml의 네임 스페이스 지정 -->
<mapper namespace="mapper.member">
<!-- type
: SQL문을 실행한 후 반환되는 레코드들을 TypeAlias태그에서 지정한 memberVO빈에 저장하겠다 -->
<resultMap type="memberVO" id="memResult">
<!-- 레코드의 컬럼 이름에 대해 memberVO와 같은 속성 값을 지정 -->
<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 : 반환되는 레코드를 memResult에 저장 -->
<select id="selectAllMemberList" resultMap="memResult">
<![CDATA[ select * from t_member order by joinDate desc ]]>
</select>
</mapper>
3. MemberServlet.java
- 브라우저에서 요청하면 MemberDAO 객체를 생성한 후 selectAllMemberList()를 호출하는 서블릿
package com.spring.ex01;
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/mem.do")
public class MemberServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doHandle(request, 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 객체를 생성하고
MemberDAO dao = new MemberDAO();
// selectAllMemberList()를 호출한다
List membersList = dao.selectAllMemberList();
request.setAttribute("memberList", membersList);
RequestDispatcher dispatch =
request.getRequestDispatcher("test01/listMembers.jsp");
dispatch.forward(request, response);
}
}
4. MemberDAO.java
- SqlMapConfig.xml 파일을 이용해 SqlMapper 객체를 생성한다
그 다음 select AllMemberList() 메소드를 호출해 인자로 mapper.member.selectAllMemberLsit 를 전달, member.xml 에서 해당 네임스페이스와 id에 해당하는 sql문을 실행한다.
package com.spring.ex01;
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 {
private static SqlSessionFactory sqlMapper = null;
public static SqlSessionFactory getInstance() {
if(sqlMapper == null) {
try {
// MemberDAO의 각 메소드 호출 시 src/mybatis/SqlMapConfig.xml에서
// 설정정보를 읽은 후 데이터베이스와의 연동을 준비한다
String resouce = "mybatis/SqlMapConfig.xml";
Reader reader = Resources.getResourceAsReader(resouce);
// 마이바이스를 이용하는 sqlMapper 객체를 가져온다
sqlMapper = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return sqlMapper;
}
public List<MemberVO> selectAllMemberList() {
sqlMapper = getInstance();
// 실제 member.xml의 SQL문을 호춣하는데 사용되는 sqlSession 객체를 가져온다
SqlSession session = sqlMapper.openSession();
List<MemberVO> memList = null;
// 여러개의 레코드를 조회하기 때문에 selectList() 메소드에
// 실행하고자 하는 SQL문 id를 인자로 전달해야 한다
memList = session.selectList("mapper.member.selectAllMemberList");
return memList;
}
}
5. MemberVO.java
SQL문으로 전달할 값이나 SQL문을 실행한 후 반환되는 레코드들의 값을 각 속성에 저장합니다
package com.spring.ex01;
import java.sql.Date;
public class MemberVO {
private String id;
private String pwd;
private String name;
private String email;
private Date joinDate;
public MemberVO() {}
public MemberVO(String id, String pwd, String name, String email) {
this.id = id;
this.pwd = pwd;
this.name = name;
this.email = email;
}
// 각 속성들의 getter와 setter
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;
}
}
6. listMembers.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<% request.setCharacterEncoding("utf-8"); %>
<html>
<head>
<meta charset=utf-8">
<title>회원 정보 출력창</title>
</head>
<body>
<table border="1" align="center" width="80%">
<tr align="center" bgcolor="lightgreen">
<td><b>아이디</b></td>
<td><b>비밀번호</b></td>
<td><b>이름</b></td>
<td><b>이메일</b></td>
<td><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>
<a href="${contextPath}/member/memberForm.do">
<h1 style="text-align: center">회원가입</h1></a>
</body>
</html>
리스트 jsp를 실행하게 되면 테이블에 회원을 안 집어넣어 그런지 이런식으로 떴다.
그래서 오라클에 테이블을 만들어줬다.
create table t_member(
id varchar(10) not null,
pwd varchar(10) not null,
name varchar(20),
email varchar(20),
joinDate date);
insert into t_member values ('a1', '123', '홍길동', '[email protected]', to_date('2020/10/10') );
insert into t_member values ('a2', '456', '김유신', '[email protected]', to_date('2020/8/7') );
insert into t_member values ('a3', '789', '이진아', '[email protected]', to_date('2019/11/16') );
insert into t_member values ('a4', '145', '곽용권', '[email protected]', to_date('2021/01/10') );
insert into t_member values ('a5', '243', '진홍섭', '[email protected]', to_date('2020/12/04') );
insert into t_member values('hong', '123','김유신','[email protected]',to_date('20/05/31') );
select * from t_member;
엥 근데 값을 넣어도 여전히 빈 표가 출력된다.
알고보니 오라클에서 테이블을 만들어준 후 커밋을 안해줘서.. 제대로 안나온거였음. commit까지 해주고 나니 아래와 같이 넣어준 값이 제대로 나왔다.
실습해보기 02 - 회원정보 조회
1. 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">
<resultMap type="memberVO" id="memResult">
<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>
<select id="selectAllMemberList" resultMap="memResult">
<![CDATA[
select * from t_member order by joinDate desc
]]>
</select>
<select id="selectName" resultType="String">
<![CDATA[
select name from t_member
where id = 'hong'
]]>
</select>
<select id="selectPwd" resultType="String">
<![CDATA[
select pwd form t_member
where id='hong'
]]>
</select>
</mapper>
2. MemberServlet.java
package com.spring.ex02;
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;
@WebServlet("/mem2.do")
public class MemberServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, 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>");
}
}
3. MemberDAO.java
package com.spring.ex02;
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 {
private static SqlSessionFactory sqlMapper = null;
private static SqlSessionFactory getInstance() {
if (sqlMapper == null) {
try {
String resource = "mybatis/SqlMapConfig.xml";
Reader reader = Resources.getResourceAsReader(resource);
sqlMapper = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return sqlMapper;
}
public String selectName() {
sqlMapper = getInstance();
SqlSession session = sqlMapper.openSession();
String name = session.selectOne("mapper.member.selectName");
return name;
}
public String selectPwd() {
sqlMapper = getInstance();
SqlSession session = sqlMapper.openSession();
String pwd = session.selectOne("mapper.member.selectPwd");
return pwd;
}
}
실행해보니까.. 'hong'의 id에 해당하는 이름이 잘 출력되었다.
실습해보기 03 - 조건으로 회원 조회
마이바티스로 조건값 전달 방법
- MemberDAO에서 메소드 호출 시 전달된 조건 값은, 매개변수 이름으로 SQL문의 조건식에 전달
- SQL문에서 조건값 사용 방법
#{전달될 매개변수의 이름}
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">
<resultMap type="java.util.HashMap" id="memResult">
<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>
<select id="selectAllMemberList" resultMap="memResult">
<![CDATA[
select * from t_member order by joinDate desc
]]>
</select>
<!-- id : MemberDAO에서 호출하는 id 지정
resultType : 조회되는 한 개의 레코드를 memberVO에 저장
parameterType : MemberDAO에서 SQL문 호출시 전달되는 매개변수의 데이터 타입 지정 -->
<select id="selectMemberById" resultType="memberVO" parameterType="String">
<!-- MemberDAO에서 메소드를 호출하면 parameterType으로 전달된 매개변수 이름을
select 문의 id 조건 값으로 사용한다 -->
<![CDATA[
select name from t_member
where id = #{id}
]]>
</select>
<select id="selectMemberByPwd" resultType="memResult" parameterType="String">
<![CDATA[
select pwd form t_member
where id = #{pwd}
]]>
</select>
</mapper>
MemberServlet.java
브라우저의 요청에 대해 MemberDAO 클래스의 메소드를 호출, 그 결과를 브라우저로 출력하는 곳
package com.spring.ex03;
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 com.spring.ex01.MemberVO;
@WebServlet("/mem3.do")
public class MemberServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, 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");
MemberDAO dao = new MemberDAO();
MemberVO memberVO = new MemberVO();
String action = request.getParameter("action");
String nextPage = "";
if (action== null || action.equals("listMembers")) {
List<MemberVO> membersList = dao.selectAllMemberList();
request.setAttribute("membersList", membersList);
nextPage = "test02/listMembers.jsp";
// 검색 조건이 selectMemberById이면 전송된 값을 getParameter()로 가저온 후
// SQL문의 조건식에서 id의 조건 값으로 전달
} else if (action.equals("selectMemberById")) {
String id = request.getParameter("value");
memberVO = dao.selectMemberById(id);
request.setAttribute("member", memberVO);
nextPage = "test02/memberInfo.jsp";
// 검색 조건이 selectMemberByPwd이면 전송된 값을
// getParmeter()로 가져온 후 sql문의 조건식 pwd의 조건값으로 전달
} else if (action.equals("selectMemberByPwd")) {
String pwd = request.getParameter("value");
List<MemberVO> membersList = dao.selectMemberByPwd(pwd);
request.setAttribute("membersList", membersList);
nextPage = "test02/listMembers.jsp";
}
RequestDispatcher dispatch = request.getRequestDispatcher(nextPage);
dispatch.forward(request, response);
}
}
MemberDAO.java
selectOne() 메소드는 하나의 레코드를 조회할 때 사용한다. 두 번째 인자는 첫번째 인자의 sql문에서 매개변수 이름 id로 조건값을 전달
package com.spring.ex03;
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 com.spring.ex01.MemberVO;
public class MemberDAO {
public static SqlSessionFactory sqlMapper = null;
private static SqlSessionFactory getInstance() {
if (sqlMapper == null) {
try {
String resource = "mybatis/SqlMapConfig.xml";
Reader reader = Resources.getResourceAsReader(resource);
sqlMapper = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return sqlMapper;
}
public List<MemberVO> selectAllMemberList() {
sqlMapper = getInstance();
SqlSession session = sqlMapper.openSession();
List<MemberVO> memlist = null;
memlist = session.selectList("mapper.member.selectAllMemberList");
return memlist;
}
public MemberVO selectMemberById(String id) {
sqlMapper = getInstance();
SqlSession session = sqlMapper.openSession();
// selectOne : 레코드 하나만 조회할 때 사용
// selectOne(인자1, 인자2) : 인자2는 서블릿에서 넘어온 id의 값을 메소드 호출 시 해당 sql 문의 조건값으로 전달
MemberVO memberVO = session.selectOne("mapper.member.selectMemberById", id);
return memberVO;
}
public List<MemberVO> selectMemberByPwd(String pwd) {
sqlMapper = getInstance();
SqlSession session = sqlMapper.openSession();
List<MemberVO> membersList = null;
// selectList : 말 그대로 list로 저장하겠다. 비밀번호가 같은 회원은 여러명일 수도 있으니까
membersList = session.selectList("mapper.member.selectMemberByPwd", pwd);
return membersList;
}
}
search.jsp
검색창에 입력한 값과 셀렉트 박스의 검색 조건을 선택해 서블릿으로 전송
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>회원 검색 창</title>
</head>
<body>
<form action="${pageContext.request.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>
memberinfo.jsp
검색 조건으로 조회한 회원 정보 출력
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="java.io.*,java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>회원 정보 출력</title>
</head>
<body>
<table border="1" align="center" width="100%">
<tr align="center" bgcolor="lightgreen">
<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>
Author And Source
이 문제에 관하여(spring - 마이바티스 프레임워크), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@cyhse7/spring-04-마이바티스-프레임워크저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)