23.05.10

이준영·2023년 5월 10일
0

🌕프레임 워크 (p. 542)

장점 : 개발 시간 단축 / 성능 향상 / 유지 보수성 향상

단점 : 프레임워크 학습 필요, 선택의 어려움, 유연성 부족



🌙 myBatis (=sql mapper framework)

http://blog.mybatis.org (참조)

개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크

JDBC로 처리하는 상당부분의 코드와 파라미터 설정및 결과 매핑을 대신해준다

xml파일에 데이터베이스 처리에 관한 sql문 설정 후 자바 소스에서 간단하게 연결하여 데이터를 처리할 수 있음

매핑하기 위해 XML과 애노테이션을 사용 (XML -> 애노테이션으로 가는 추세)

Mybatis 설정

lib

  • jdbc 드라이버
  • mybatis 프레임워크
  • log출력용 라이브러리 (3가지 필요)

설정파일

  • 데이터베이스 접속용
  • sql mapper 파일
    log4j.xml(작업진행에 대한 로그 출력하는 프레임 워크)

    데이터베이스와 접속되는 내용을 설정해줌
    dynamic web project --> maven(gradle) project로 대치



🌕 자바로 Mybatis 프로젝트 만들기

  1. java-workspace로 변경

  1. 프로젝트 생성 후 API 3개 집어넣기


  1. Mybatis와 연결되는 설정 파일 집어넣기


  1. 설정 파일 설정해주기

log4.xml - 작업진행에 대한 로그 출력하는 프레임 워크

myBatisConfig.xml - 데이터베이스와 접속되는 내용을 설정해줌
(2개도 설정 가능, enviroments의 default에 적힌 것에 따라 사용 결정)


  1. java class 파일 생성해서 sqlSessionFactory 연결
import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MyBatisEx01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//넣은 설정파일 xml 이름 변수에 넣기
		String resource = "myBatisConfig.xml";
		
        
		InputStream is = null;
		
		try {
			is  = Resources.getResourceAsStream( resource );
	
    		// sqlSessionFactory 연결
			SqlSessionFactory sqlSessionFactory 
			= new SqlSessionFactoryBuilder().build( is );
			
			System.out.println("설정 호출");
			
		} catch (IOException e) {
			System.out.println("[에러]" + e.getMessage());
		} finally { 
			if(is != null) try { is.close(); } catch(IOException e) {} 
		}
		}
	
}


  1. 5번에서 추가로 sqlSession 만들어서 연결하기 (5,6 - 설정 파일 만들어서 데이터베이스 연결)
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 MyBatisEx01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//넣은 설정파일 xml 이름 변수에 넣기
		String resource = "myBatisConfig.xml";
		
		InputStream is = null;
		
		SqlSession sqlSession = null;
		
		try {
			is  = Resources.getResourceAsStream( resource );
	
			SqlSessionFactory sqlSessionFactory 
			= new SqlSessionFactoryBuilder().build( is );
			System.out.println("설정 호출");
			//session 얻기
			sqlSession = sqlSessionFactory.openSession();
			System.out.println("연결 성공");
			
			
		} catch (IOException e) {
			System.out.println("[에러]" + e.getMessage());
		} finally { 
			if(sqlSession != null) sqlSession.close();
			if(is != null) try { is.close(); } catch(IOException e) {} 
		}
		}
	
}


  1. model1 패키지 만들어서 mapper.xml 붙여넣기


  1. mapper.xml 작성 후 데이터를 가져오기 위해 TO 클래스 하나 만들기


  1. myBatisConfig.xml에 가서 mapper.xmp에서 만든 mapper를 environments 밑에 추가


  1. MyBatisEx01로 가서 한 줄 데이터 가져오기 (자바 코드에서 sql 구문이 없어짐)
//데이터 가져오기
			//한 줄의 데이터 가져오기 = selectOne (데이터가 여러 개면 에러남)
			DeptTO to = (DeptTO) sqlSession.selectOne("deptlist");
			System.out.println(to.getDeptno());
			System.out.println(to.getDname());
			System.out.println(to.getLoc());
			//여러 줄의 데이터 가져오기 = selectList
            
            연결성공 밑에 쓰기


  1. 여러 줄 가져오기
//여러 줄의 데이터 가져오기 = selectList
			List<DeptTO> lists =  sqlSession.selectList("selectall"); //select의 id부분 넣기
			for(DeptTO to : lists) {
			System.out.println(to.getDeptno());
			System.out.println(to.getDname());
			System.out.println(to.getLoc());
			}

list(arraylist) 형식으로 가져오기 (ArrayList로 가져올 때는 형변환 해줘야함)




🌕 web 프로젝트로 mybatis 만들기

  1. dynamic web project 만들고 lib에 아까 API 3개 넣기

  1. 설정 파일(xml) 설정
log4j.xml

     <root>
     	<level value="DEBUG" />
     	<appender-ref ref="console" />
     </root>

myBatisConfig.xml

<configuration>
	<environments default="mariadb1">
		<environment id="mariadb1">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="org.mariadb.jdbc.Driver"/>
				<property name="url" value="jdbc:mariadb://localhost:3306/sample"/>
				<property name="username" value="root"/>
				<property name="password" value="123456"/>
			</dataSource>
		</environment>
	</environments>
</configuration>

mapper.xml

<mapper namespace="mybatis1">
	<select id="selectone" resultType="model1.DeptTO">
		select deptno, dname, loc
		from dept
		where deptno = 10;
	</select>
</mapper>

후에 model1 패키지 - DeptTO 클래스 만들고 myBatisConfig.xml 가서 mapper 위치 잡아주기

environments 밑에

	<mappers>
		<mapper resource="model1/mapper.xml" />
	</mappers>

  1. jsp 파일 만들어서 기본적으로 import 시키고 코드 작업
<%@ page import="java.io.IOException" %>    
<%@ page import="java.io.InputStream" %>    

<%@ page import="org.apache.ibatis.io.Resources" %>    
<%@ page import="org.apache.ibatis.session.SqlSession" %>    
<%@ page import="org.apache.ibatis.session.SqlSessionFactory" %>    
<%@ page import="org.apache.ibatis.session.SqlSessionFactoryBuilder" %> 

<%@ page import="model1.DeptTO" %>   

한 줄 받기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.IOException" %>    
<%@ page import="java.io.InputStream" %>    

<%@ page import="org.apache.ibatis.io.Resources" %>    
<%@ page import="org.apache.ibatis.session.SqlSession" %>    
<%@ page import="org.apache.ibatis.session.SqlSessionFactory" %>    
<%@ page import="org.apache.ibatis.session.SqlSessionFactoryBuilder" %> 


<%@ page import="model1.DeptTO" %>   

<%
	String resource = "myBatisConfig.xml";

	InputStream is = null;
	SqlSession sqlSession = null;
	
	StringBuilder sbHtml = new StringBuilder();
	
	try {
		is = Resources.getResourceAsStream(resource);
		
		SqlSessionFactory sqlSessionFactory 
		= new SqlSessionFactoryBuilder().build(is);
		
		sqlSession = sqlSessionFactory.openSession();
		
		DeptTO to = (DeptTO) sqlSession.selectOne("selectone");
		
		sbHtml.append("<table border='1' width='800'>");
		sbHtml.append("<tr>");
		sbHtml.append("<td>" + to.getDeptno() + "</td>");
		sbHtml.append("<td>" + to.getDname() + "</td>");
		sbHtml.append("<td>" + to.getLoc() + "</td>");
		sbHtml.append("</tr>");
		sbHtml.append("</table>");
		
	} catch(IOException e) {
		System.out.println("[에러] : " + e.getMessage());
	} finally { 
		if(sqlSession != null) sqlSession.close();
		if(is != null) try { is.close(); } catch(IOException e) {} 
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=sbHtml %>
</body>
</html>


실행 로그




🌙 mapper에서 sql 파라미터 받기

	<select id="selectparamone1" parameterType="String" resultType="model1.DeptTO">
		select deptno, dname, loc
		from dept
		where deptno = #{deptno};  <-- #{deptno}를 줘서 ? 와 같은 효과 주기
	</select>

후에 jsp 파일에서

		DeptTO to = (DeptTO) sqlSession.selectOne("selectparamone1", "20"); 
        <-- 매개변수 하나 더 추가(deptno 20을 가져오겠다!)


🌙 2개 이상 받을 때

parameterType을 model.DeptTO로 받아준다.

<select id="selectparamone3" parameterType="model.DeptTO"  resultType="model1.DeptTO">
		select deptno, dname, loc
		from dept
		where deptno = #{deptno} and dname=#{dname}
	</select>

jsp 파일에서 DeptTO 타입 변수 하나 만들고 set으로 값 집어넣기 - > sqlSession에 변수 넣기

	DeptTO paramTO = new DeptTO();
		paramTO.setDeptno("30");
		paramTO.setDname("SALES");
		
		
		DeptTO to = (DeptTO) sqlSession.selectOne("selectparamone3", paramTO);
		




🌙 응용 : ename으로 emp정보 like 써서 가져오기

변경점 : emp정보이므로, 데이터베이스 dept -> emp에 맞게 설정 바꾸기
like를 쓸 경우 정보가 하나 이상이 나올 확률이 높으니까 selectList를 사용

mapper.xmp 설정

<select id="selectone2" parameterType="String" resultType="model1.EmpTO">
		select empno, ename, job, hiredate, sal, comm, deptno
		from emp
		where ename like #{ename}
	</select>

jsp 작업

<% 
	String resource = "myBatisConfig.xml";
	
	InputStream is = null;
	SqlSession sqlSession = null;
	
	StringBuilder sbHtml = new StringBuilder();
	
	try {
		is = Resources.getResourceAsStream(resource);
		
		SqlSessionFactory sqlSessionFactory
		= new SqlSessionFactoryBuilder().build(is);
		
		sqlSession = sqlSessionFactory.openSession();
		
		ArrayList<EmpTO> lists = (ArrayList) sqlSession.selectList("selectone2", "S%");
		
			sbHtml.append("<table border='1' width='800'>");
			sbHtml.append("<tr>");
			sbHtml.append("<td>" + to.getEmpno() + "</td>");
			sbHtml.append("<td>" + to.getEname() + "</td>");
			sbHtml.append("<td>" + to.getJob() + "</td>");
			sbHtml.append("<td>" + to.getHiredate() + "</td>");
			sbHtml.append("<td>" + to.getSal() + "</td>");
			sbHtml.append("<td>" + to.getComm() + "</td>");
			sbHtml.append("<td>" + to.getDeptno() + "</td>");
			sbHtml.append("</tr>");
			sbHtml.append("</table>");
		
	} catch(IOException e) {
		System.out.println("[에러] : " + e.getMessage());
	} finally { 
		if(sqlSession != null) sqlSession.close();
		if(is != null) try { is.close(); } catch(IOException e) {} 
	}
%>


mapper.xml에서 아예 %를 붙여도 된다.

<select id="selectone3" parameterType="String" resultType="model1.EmpTO">
		select empno, ename, job, hiredate, sal, comm, deptno
		from emp
		where ename like concat(#{ ename }, '%');  <--concat(문자열 결합)을 이용하여 처음부터 %를 붙여버림
	</select>
여기서는 s%에서 %빼주면 된다( 실행결과는 위와 동일 )
ArrayList<EmpTO> lists = (ArrayList) sqlSession.selectList("selectone2", "S");



🌕 mapper : insert 사용

mapper.xml

	<insert id="insert1" parameterType="model1.DeptTO">
		insert into dept2 (deptno, dname, loc)
		values (#{deptno}, #{dname}, #{loc})
	</insert>
<%
	String resource = "myBatisConfig.xml";

	InputStream is = null;
	SqlSession sqlSession = null;
	
	StringBuilder sbHtml = new StringBuilder();
	
	try {
		is = Resources.getResourceAsStream(resource);
		
		SqlSessionFactory sqlSessionFactory 
		= new SqlSessionFactoryBuilder().build(is);
		
		sqlSession = sqlSessionFactory.openSession();
		
		DeptTO to = new DeptTO();
		to.setDeptno("80");
		to.setDname("총무부");
		to.setLoc("도쿄");
		
		int result = sqlSession.insert("insert1", to);
		
		if(result == 1) {
			sqlSession.commit();
			sbHtml.append("입력 성공 : " + result);
		}
		
	} catch(IOException e) {
		System.out.println("[에러] : " + e.getMessage());
	} finally { 
		if(sqlSession != null) sqlSession.close();
		if(is != null) try { is.close(); } catch(IOException e) {} 
	}
%>



실행하면 정상 실행되어도 db에 들어가져있지 않음 <- insert, update, delete를 사용할 경우 정상 검사되기 전까지는 메모리에서 보관하고 있음(transaction)

commit - 인정 / rollback - 되돌림
을 통하여 보관된 메모리 사용 가능


if(result == 1) {
			sqlSession.commit();  //보관된 것 적용시킨다! 라는 뜻
			sbHtml.append("입력 성공 : " + result);
		}


매번 하기 번거로워서 openSession()에다 true를 줘서 무조건 commit 시키게 만든다(auto commit)

		sqlSession = sqlSessionFactory.openSession(true);  <-- true 넣기
        
        DeptTO to = new DeptTO();
		to.setDeptno("90");
		to.setDname("인사부");
		to.setLoc("서울");
		
		int result = sqlSession.insert("insert1", to);
		

		sbHtml.append("입력 성공 : " + result);



🌕 mapper : update / delete

insert와 형식은 같다.

mapper.xml

<update id="update1" parameterType="model1.DeptTO">
		update dept2 
		set dname=#{dname}
		where deptno=#{deptno} 
	</update>
	
	<delete id="delete1" parameterType="model1.DeptTO">
		delete from dept2
		where deptno=#{deptno}
	</delete>


기존 db


update

		DeptTO to = new DeptTO();
		to.setDeptno("80");
		to.setDname("회계부");
		
		int result = sqlSession.update("update1", to);


delete
		DeptTO to = new DeptTO();
		to.setDeptno("80");
		
		int result = sqlSession.delete("delete1", to);




🌕 to, dao 이용하여 만들기 (model1 기법)

to dao -> select

package model1;

import java.io.IOException;
import java.io.InputStream;
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 DeptDAO {
	private SqlSession sqlSession;
	
	public DeptDAO() {
		String resource = "myBatisConfig.xml";
		
		InputStream is = null;
		
		try {
			is = Resources.getResourceAsStream(resource);
			
			SqlSessionFactory sqlSessionFactory 
			= new SqlSessionFactoryBuilder().build(is);
			
			sqlSession = sqlSessionFactory.openSession(true);
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally { 
			if(is != null) try { is.close(); } catch(IOException e) {} 
		}
		
	}
	public List<DeptTO> selectList() {
		List<DeptTO> lists = sqlSession.selectList("selectlist");
		if(sqlSession != null) sqlSession.close();
		return lists;
	}



🌕 우편번호 검색기 만들기

zipcodeDAO

package model1;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

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 ZipcodeDAO {
	private SqlSession sqlSession;
	
	public ZipcodeDAO() {
		String resource = "myBatisConfig.xml";
		
		InputStream is = null;
		
		try {
			is = Resources.getResourceAsStream(resource);
			
			SqlSessionFactory sqlSessionFactory 
			= new SqlSessionFactoryBuilder().build(is);
			
			sqlSession = sqlSessionFactory.openSession(true);
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally { 
			if(is != null) try { is.close(); } catch(IOException e) {} 
		}
		
	}
	
	public ArrayList<ZipcodeTO> zipcodeSearch(String strDong) {
		ArrayList<ZipcodeTO> lists = (ArrayList) sqlSession.selectList("zipcodelist", strDong + "%");
		
		if(sqlSession != null) sqlSession.close();
		
		return lists;
	}
	}

zipcodeSearch.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="model1.ZipcodeTO" %>    
<%@ page import="model1.ZipcodeDAO" %>    
<%@ page import="java.util.ArrayList" %>



<%
	request.setCharacterEncoding("utf-8");
	
	String strDong = "";
	if(request.getParameter("dong") != null) {
		strDong = request.getParameter("dong");
	}

	ZipcodeDAO dao = new ZipcodeDAO();
	ArrayList<ZipcodeTO> lists = dao.zipcodeSearch(strDong);
	StringBuilder sbHtml = new StringBuilder();
	
	
		sbHtml.append("<table>");
	for(ZipcodeTO to : lists)	{
		sbHtml.append("<tr>");
		sbHtml.append("<td>" + to.getZipcode() + "</td>");
		sbHtml.append("<td>" + to.getSido() + "</td>");
		sbHtml.append("<td>" + to.getGugun() + "</td>");
		sbHtml.append("<td>" + to.getDong() + "</td>");
		sbHtml.append("<td>" + to.getRi() + "</td>");
		sbHtml.append("<td>" + to.getBunji() + "</td>");
		sbHtml.append("</tr>");
		}
		sbHtml.append("</table>");
%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="zipcodeSearch.jsp" method="post">
	동 이름 : <input type="text" name="dong" />
	<input type="submit" value="검색" />
</form>

<br><hr><br>

<%=sbHtml %>
</body>
</html>



🌕 model1 게시판 myBatis로 만들기

기존의 dao에 sql구문을 myBatis mapper.xml에서 써줘, 완전히 변환하여 dao에 sql구문이 없어야 함
-> 기존 쓰던 작업시간보다 훨씬 더 줄어든다.

board.xml

<mapper namespace="mybatis1">

	<select id="list"  resultType="model1.BoardTO">
		select seq, subject, writer, date_format(wdate,'%Y-%m-%d') wdate, hit 
		from board 
		order by seq desc;
	</select>
	
  	//view처럼 seq 정보를 받는 애들은 select시에 seq을 같이 가져온다.
	<select id="view" parameterType="model1.BoardTO"  resultType="model1.BoardTO">
		select seq, subject, writer, mail, wip, date_format(wdate,'%Y-%m-%d')wdate, hit, content 
		from board 
		where seq=#{seq}
	</select>
	
	<update id="view_hit" parameterType="model1.BoardTO">
		update board set hit=hit+1 
		where seq=#{seq}
	</update>
	
	<insert id="write_ok" parameterType="model1.BoardTO">
		insert into 
		board values(0,#{subject}, #{writer}, #{mail}, #{password}, #{content}, 0, #{wip}, now());
	</insert>
	
	<select id="modify" parameterType="model1.BoardTO" resultType="model1.BoardTO">
		select seq, subject, writer, mail, content 
		from board 
		where seq = #{seq};
	</select>
	
	<update id="modify_ok" parameterType="model1.BoardTO">
		update board set  subject = #{subject}, mail = #{mail}, content = #{content} 
		where seq = #{seq} and password = #{password};
	</update>
	
	<select id="delete" parameterType="model1.BoardTO" resultType="model1.BoardTO">
		select seq, subject, writer, mail, content 
		from board 
		where seq = #{seq};
	</select>
	
	<delete id="delete_ok" parameterType="model1.BoardTO">
		delete from board 
		where seq = #{seq} and password = #{password};
	</delete>
</mapper>
BoardDAO

package model1;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.naming.NamingException;

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 BoardDAO {
	private SqlSession sqlSession;
	
	
	// 생성자가 필요
	public BoardDAO() {
		String resource = "myBatisConfig.xml";
		
		InputStream is = null; 
		try {
			is = Resources.getResourceAsStream(resource);
			
			SqlSessionFactory sqlSessionFactory 
			= new SqlSessionFactoryBuilder().build(is);
			
			sqlSession = sqlSessionFactory.openSession(true);
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally { 
			if(is != null) try { is.close(); } catch(IOException e) {} 
		}
	} 

	public void boardWrite() {
		
	}
	
	// BoardTO to는 write에서 받은 데이터를 집어넣는다
	public int boardWriteOk(BoardTO to) {
		
		int flag = 1;

		int result = sqlSession.insert("write_ok", to);
		if(result == 1) {
			flag = 0;	
		}
		
		if(sqlSession != null) sqlSession.close();
		
		return flag;

	}
	
	// list는 ArrayList로 받아온다
	public ArrayList<BoardTO> boardList() {
		
		ArrayList<BoardTO> datas = (ArrayList)sqlSession.selectList("list");
		
		if(sqlSession != null) sqlSession.close();
		
		return datas;
	}
	
	// to에 seq가 들어가서 update하고 select 함
	public BoardTO boardView(BoardTO to) {
		
		sqlSession.update("view_hit", to);
		
		to = sqlSession.selectOne("view", to);
		
		if(sqlSession != null) sqlSession.close();

		
		return to;
	}
	
	public BoardTO boardModify(BoardTO to) {

		to = sqlSession.selectOne("modify", to);
		
		if(sqlSession != null) sqlSession.close();

		
		return to;
	}
	
	public int boardModifyOk(BoardTO to) {

		int flag = 2;

		int result = sqlSession.update("modify_ok",to);
		if(result == 0) {
			flag = 1;
		}
		else if(result == 1) {
			flag = 0;
		}
		if(sqlSession != null) sqlSession.close();

		return flag;
	}
	
	public BoardTO boardDelete(BoardTO to) {
		
		to = sqlSession.selectOne("delete", to);
		
		if(sqlSession != null) sqlSession.close();

		return to;
	}
	
	public int boardDeleteOk(BoardTO to) {
		
		int flag = 2;
		
		int result = sqlSession.delete("delete_ok",to);
		if(result == 0) {
			flag = 1;
		}
		else if(result == 1) {
			flag = 0;
		}

		if(sqlSession != null) sqlSession.close();

		return flag;
	}
}

JSP쪽은 수정 X

결과도 똑같다.

profile
끄적끄적

0개의 댓글