MyBatis : 기초
MyBatis는 태그 형태의 코드로 간단하게 데이터베이스와 연결해 주도록 돕는 라이브러리이다!
사용해 보자.
https://github.com/mybatis/mybatis-3/releases
위 링크에서 zip파일 다운로드
zip파일의 압축을 풀고 파일 내의 모든 jar파일을 프로젝트 lib에 복사해 준다.
Eclipse의 상위 탭에서 "Help > Eclipse MarketPlace"
→ MyBatis 검색 및 설치
일반 xml파일로 Config.xml 을 만들고, MyBatis XML Mapper 파일로 board-mapper.xml을 만든다.
Config.xml은 데이터베이스와 연결하고 어떤 값을 어떻게 가져올 것인지 설정하는 파일,
board-mapper.xml은 실행할 쿼리 문장을 저장하는 곳이다.
아래와 같은 테이블에서 데이터를 가져온다고 해 보자.
1. Config.xml로 데이터베이스 연결 설정하기
xml파일에 이걸 추가해 주면 MyBatis가 제공하는 태그들을 다 볼 수 있도록 해준다.
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
위 코드를 추가하고 태그에 커서를 갖다 대면 아래와 같은 팝업이 표시된다.
configuration 태그 아래에 무슨 태그가 올 수 있는 지 보여주고 있음.
태그 작성 순서를 꼭 지켜야 한다. ex. setting 뒤에 properties 가 오면 안된다.
위 문서에서 볼 수 있듯이 특정 태그 아래에 올 수 있는 tag들은 태그명과 기호로 표기되어 있다.
각 기호는 아래와 같은 의미를 갖고 있다.
기호 | 의미 |
? | 필요시에 사용하되 한 번만 사용이 가능하다. |
* | 0번 이상 여러 번 사용이 가능 |
+ | 반드시 한 번 이상 사용해야 한다. |
| | 취사선택하여 사용한다. |
default(없음) | 반드시 한 번만 사용해야 한다. |
데이터베이스 연결을 위해 <configuration> 태그 아래에 작성하는 태그
<typeAliases>
VO를 등록한다. 어떤 VO에서 값을 가져올 것인지 선택한다.
<environments>
연결 환경을 설정한다.
↳ <dataSource>
DBCP를 사용할 것인지, JDBC를 사용할 것인지 선택한다.
↳ <properties>
데이터베이스 정보를 저장한다! .properties라는 파일을 읽는다.
<mappers>
어떤 xml파일에서 SQL문을 읽어올 것인지 지정한다.
그렇게 작성한 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">
<!--
Connection 관련 내용이 저장되는 곳
getConnection()과 disConnection()이 만들어짐
-->
<configuration>
<typeAliases>
<typeAlias type="doodoo.dao.MyBoardVO" alias="MyBoardVO"/>
<!-- SELECT문이 나가면 여기에 값을 채워 주세요 -->
</typeAliases>
<!-- 연결 설정 (getConnection, disConnection)-->
<environments default="development"> <!-- (environment+) -->
<environment id="development"> <!-- (transactionManager, dataSource) -->
<transactionManager type="JDBC"/> <!-- AutoCommit 사용하겠다는 뜻 -->
<dataSource type="POOLED">
<!-- POOLED : DBCP / UNPOOLED : JDBC -->
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
<property name="username" value="user"/>
<property name="password" value="pwd"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- (mapper*, package*) -->
<mapper resource="doodoo/dao/board-mapper.xml"/><!-- SQL문장 저장 위치 -->
</mappers>
</configuration>
2. mapper.xml에서 실행할 쿼리문 작성하기
mapper.xml은 SQL문을 모아 저장한다.
마찬가지로 태그형태로 작성할 수 있다. 단, 태그 사이에 SQL 문장은 한 개만 설정해야 한다.
<select>, <insert>, <update>, <delete> 등 SQL문의 종류에 따라 태그를 정하고,
해당 태그 내에 기존 SQL문을 작성할 때처럼 작성하면 된다.
아래와 같이 id로 해당 SQL 문의 이름을 지어 주고,
resultType 과 parameterType이라는 속성을 지정할 수 있다.
<select id="" resultType="" parameterType="hashMap">
resultType은 select문에서만 사용할 수 있으며 어떤 형태로 결과를 받아올 지 정할 수 있다.
parameterType으로 WHERE 문에 들어갈 매개변수 타입을 지정할 수 있다.
기존의 SQL문에서 ? 에 들어갈 값의 타입을 지정한다고 보면 된다.
단, #{param} 과 같이 변수의 이름을 지정해 주고, 이후 DAO에서 실행할 때 값을 넣어 준다.
일반적인 parameterType으로는 한 번에 한 가지만 지정이 가능하므로
여러 개의 변수를 넣고 싶을 때에는 map을 활용해야 한다.
<sql id=""> 이라는 태그도 있는데, 공통 SQL을 묶어 사용한다. 예시로 보는 게 빠름!
board-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">
<!-- 테이블마다 있어야 함. ResultSet, PreparedStatement 관련 내용 -->
<mapper namespace="doodoo.dao.board-mapper">
<!-- SQL 문장 저장 -->
<select id="boardListData" resultType="MyBoardVO">
SELECT * FROM myBoard
</select>
<select id="boardCount" resultType="int">
SELECT count(*) FROM myBoard
</select>
</mapper>
3. DAO.java로 xml파일을 읽고 데이터 받아오기
Reader로 Config.xml 파일을 읽어 오면, Config.xml 내에 등록된 mapper파일도 함께 읽어 온다.
그리고 SqlSessionFactory로 Connection을 생성하고, session을 열어 쿼리문을 실행할 수 있다!
MyBoardDAO.java
package doodoo.dao;
import java.util.*;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.*;
public class MyBoardDAO {
private static SqlSessionFactory ssf; //XML 읽는 역할
static {
try {
//XML Parsing
Reader reader = Resources.getResourceAsReader("Config.xml");
ssf = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static List < MyBoardVO > boardListData() {
return ssf.openSession().selectList("boardListData"); //mapper에서 작성한 select 쿼리의 id
}
public static int boardCount() {
return ssf.openSession().selectOne("boardCount"); //값을 하나만 받을 때는 selectOne
}
}
데이터가 잘 나오는지 확인
MainClass.java
package doodoo.dao;
import java.util.List;
public class MainClass {
public static void main(String[] args) {
List < MyBoardVO > list = MyBoardDAO.boardListData();
for (MyBoardVO vo: list) {
System.out.println(vo.getNo() + "/" + vo.getName() + "/" + vo.getSubject());
}
int cnt = MyBoardDAO.boardCount();
System.out.println(cnt + "개");
}
}
MVC구조 프로젝트에 MyBatis 적용하기
추가로.. MVC구조를 가진 프로젝트에 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>
<typeAliases>
<typeAlias type="doodoo.dao.BoardVO" alias="BoardVO"/>
</typeAliases>
<environments default="development"> <!-- 개발환경 만들기 -->
<environment id="development">
<transactionManager type="JDBC"/> <!-- AutoCommit을 쓰겠다. -->
<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="user"/>
<property name="password" value="pwd"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="doodoo/mapper/board-mapper.xml"/>
</mappers>
</configuration>
application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<component-scan base-package="doodoo.model"/>
</beans>
board-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="doodoo.mapper.board-mapper">
<select id="boardListData" resultType="BoardVO" parameterType="hashmap">
SELECT no, subject, name, regdate, hit, num
FROM (SELECT no, subject, name, regdate, hit, rownum as num
FROM (SELECT /*+ INDEX_DESC(myBoard myb_no_pk)*/no, subject, name, regdate, hit
FROM myBoard))
WHERE num BETWEEN #{start} AND #{end}
</select>
<sql id="where-no">
WHERE no = #{no}
</sql>
<update id="boardHitIncrement" parameterType="int">
UPDATE myBoard SET
hit = hit+1
<include refid="where-no"/>
</update>
</mapper>
BoardVO.java (Class)
package doodoo.dao;
import java.util.Date;
/*
* SELECT NVL(MAX(no)+1,1) as no FROM table 이런거 쓸때는 꼭 alias 써주어야 한다.
*/
public class BoardVO {
private int no, hit;
private String name, subject, content;
private Date regdate;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public int getHit() {
return hit;
}
public void setHit(int hit) {
this.hit = hit;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getRegdate() {
return regdate;
}
public void setRegdate(Date regdate) {
this.regdate = regdate;
}
}
BoardDAO.java (Class)
package doodoo.dao;
import java.util.*;
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 java.io.*;
public class BoardDAO {
private static SqlSessionFactory ssf;
static {
//XML을 읽고 데이터를 주입시킨다.
try {
Reader reader = Resources.getResourceAsReader("Config.xml");
ssf = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception ex) {
ex.printStackTrace();
}
}
//목록보기
public static List < BoardVO > boardListData(Map map) {
//Map을 주고 #{start}와 #{end}에 값을 넣어줄 것임.
SqlSession session = null; //SqlSession == Connection
List < BoardVO > list = new ArrayList < BoardVO > ();
try {
session = ssf.openSession();
list = session.selectList("boardListData", map);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
session.close(); //반환
}
return list;
}
}
BoardModel.java (Class)
package doodoo.model;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import controller.Controller;
import controller.RequestMapping;
import doodoo.dao.*;
@Controller
public class BoardModel {
@RequestMapping("board/list.do")
public String board_list(HttpServletRequest request, HttpServletResponse response) {
String page = request.getParameter("page");
if (page == null)
page = "1";
int curPage = Integer.parseInt(page);
Map map = new HashMap();
int start = (curPage * 10) - 9;
int end = curPage * 10;
map.put("start", start);
map.put("end", end);
List < BoardVO > list = BoardDAO.boardListData(map);
request.setAttribute("list", list);
return "../board/list.jsp";
}
}
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style type="text/css">
*{
}
.container{
margin-top:50px;
}
.row{
margin: 0px auto;
width: 960px;
}
</style>
</head>
<body>
<div class="container">
<h1 class="text-center">MyBatis 게시판</h1>
<div class="row">
<table class="table">
<tr class="warning">
<th class="text-center" width=10%>번호</th>
<th class="text-center" width=45%>제목</th>
<th class="text-center" width=15%>이름</th>
<th class="text-center" width=20%>작성일</th>
<th class="text-center" width=10%>조회수</th>
</tr>
<c:forEach var="vo" items="${list }">
<tr class="warning">
<td class="text-center" width=10%>${vo.no }</td>
<td width=45%>${vo.subject }</td>
<td class="text-center" width=15%>${vo.name }</td>
<td class="text-center" width=20%>
<fmt:formatDate value="${vo.regdate }" pattern="yyyy-MM-dd"/></td>
<td class="text-center" width=10%>${vo.hit }</td>
</tr>
</c:forEach>
</table>
</div>
</div>
</body>
</html>
'부트캠프(END) > Web' 카테고리의 다른 글
JavaScript 기초 (1) : 변수, 연산자, 제어문 (0) | 2022.08.01 |
---|---|
MVC(2) (0) | 2022.07.28 |
MVC (1) (0) | 2022.07.27 |