java / jsp 프레임워크
프레임워크와 라이브러리의 차이점은 "제어 흐름"의 권한의 위치
라이브러리 : 사용자가 애플리케이션 코드의 흐름을 직접 제어
프레임워크 : 애플리케이션의 코드가 프레임워크에 의해 사용, 애플리케이션 코드는 프레임워크가 짜 놓은 틀에서 수동적으로 동작
코드를 연결할 수 있는 위치를 제공, 필요에 따라 사용자가 연결한 코드 호출하는 제어흐름 권한 가짐
제어의 역전(IoC, Inversion of Control)
어떠한 일을 하도록 만들어진 Framework에 Control 권한을 위임하는 것
간단히 말해 프로그램의 제어 흐름 구조가 뒤바뀐 것
프레임워크
프리젠테이션 티어
비즈니스 티어
데이터 티어
sql mapper 프레임워크 => myBatis
java + sql => java / sql 분리
설정
프레임워크 위치
xml
log4j.xml(이름 거의 안바뀜)
myBatisConfig.xml
mapper.xml (상황에 맞게 바꿈)
게시판
model1
client <-> jsp <-> dao < - > mybatis(db와 연동)
model2
client -> servlet -> xxxAction -> dao < - > mybatis
테이블 / 프로그램 종류 따라서 다중으로 만들 수 있음
만들고 myBatisConfig.xml에 넣어주기
별 다른 건 없지만, 아이디가 중복되는 경우 에러가 나온다.
이 경우, namespace(패키지와 비슷) 부분을 다르게 줘서 해결한다.
List<EmpTO> lists = sqlSession.selectList("mybatis2.selectone", "S%"); <-- namespace.id
따라서 같은 id라도 namespace가 다르다면 namespace.id 를 해주면 된다.
중복되는 sql구문을 위에 선언하고, include해서 사용할 수 있다.
아무것도 구현하지않고 상속받지 않은 순수한 자바파일 형태 --> 설정파일을 대신
myBatisConfig.xml에서 mapper구문없어도 됨
후에 생성자 만들고 위에 애노테이션 사용하여 sql구문 만들기
opensession 밑에 추가
sqlSession.getConfiguration().addMapper( SqlMapperInter.class );
SqlMapperInter mapper = (SqlMapperInter)sqlSession.getMapper(SqlMapperInter.class);
DeptTO to = mapper.selectByDeptTO();
완성 코드
<%@ 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" %>
<%@ page import="mapper.SqlMapperInter" %>
<%
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();
//
sqlSession.getConfiguration().addMapper( SqlMapperInter.class );
SqlMapperInter mapper = (SqlMapperInter)sqlSession.getMapper(SqlMapperInter.class);
DeptTO to = mapper.selectByDeptTO();
sbHtml.append("<table border='1' width='800'>");
sbHtml.append("<tr>");
sbHtml.append("<td>" + to.getDeptno() + "</td>");
sbHtml.append("<td>" + to.getLoc() + "</td>");
sbHtml.append("<td>" + to.getDname() + "</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>
위 코드에서 이 부분만 변경
DeptTO to = mapper.selectByDeptTO();
sbHtml.append("<table border='1' width='800'>");
sbHtml.append("<tr>");
sbHtml.append("<td>" + to.getDeptno() + "</td>");
sbHtml.append("<td>" + to.getLoc() + "</td>");
sbHtml.append("<td>" + to.getDname() + "</td>");
sbHtml.append("</tr>");
sbHtml.append("</table>");
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
List<DeptTO> lists = mapper.selectList();
sbHtml.append("<table border='1' width='800'>");
for(DeptTO to :lists){
sbHtml.append("<tr>");
sbHtml.append("<td>" + to.getDeptno() + "</td>");
sbHtml.append("<td>" + to.getLoc() + "</td>");
sbHtml.append("<td>" + to.getDname() + "</td>");
sbHtml.append("</tr>");
}
sbHtml.append("</table>");
where문을 주고 싶다면 인터페이스에서
@Select("select deptno, dname, loc from dept where deptno = #{deptno}")
public List<DeptTO> selectListByDeptno(String deptno);
해주고
List<DeptTO> lists = mapper.selectList("10"); 해주기
list로 전체 가져오기
where문을 통하여 10번만 가져오기
인터페이스에서 설정
@Insert("insert into dept2 values (#{deptno},#{dname}, #{loc})")
public int insert(DeptTO to);
@Update("update dept2 set dname = #{dname} where deptno=#{deptno}")
public int update(DeptTO to);
@Delete("delete from dept2 where deptno = #{deptno}")
public int delete(DeptTO to);
각각 코드작업
insert
DeptTO to = new DeptTO();
to.setDeptno("60");
to.setDname("회계부");
to.setLoc("인천");
int result = mapper.insert(to);
sbHtml.append("결과 :" + result);
-------------------------------------------------
update
DeptTO to = new DeptTO();
to.setDeptno("60");
to.setDname("생산부");
int result = mapper.update(to);
sbHtml.append("결과 :" + result);
-------------------------------------------------
delete
DeptTO to = new DeptTO();
to.setDeptno("60");
int result = mapper.delete(to);
sbHtml.append("결과 :" + result);
어제했던 거 가져와서 pojo로 변경하기
변경점
mapper지우고 interface만들기
public interface SqlMapperInter {
@Select("select zipcode, sido, gugun, dong, ri, bunji from zipcode where dong like #{dong}")
public ArrayList<ZipcodeTO> zipcodeList(String dong);
}
dao에 연결구문 추가하기(아래에 넣어도 되지만, 위에 같이 넣어주기 위해 필드변수로 인터페이스 타입 변수 선언하기, zipcodeSearch 부분 변경하기
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;
import mapper.SqlMapperInter;
public class ZipcodeDAO {
private SqlSession sqlSession;
private SqlMapperInter mapper;
public ZipcodeDAO() {
String resource = "myBatisConfig.xml";
InputStream is = null;
try {
is = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory
= new SqlSessionFactoryBuilder().build(is);
this.sqlSession = sqlSessionFactory.openSession(true);
this.sqlSession.getConfiguration().addMapper(SqlMapperInter.class);
this.mapper = (SqlMapperInter)sqlSession.getMapper(SqlMapperInter.class);
} catch (IOException e) {
System.out.println("[에러] : " + e.getMessage());
} finally {
if(is != null) try { is.close(); } catch(IOException e) {}
}
}
public ArrayList<ZipcodeTO> zipcodeSearch(String dong) {
ArrayList<ZipcodeTO> lists = mapper.zipcodeList(dong);
if(sqlSession != null) sqlSession.close();
return lists;
}
}
zipcodesearch.jsp 부분은 바꿀 건 거의 없고 lists 부분만 바꿔주기
ZipcodeDAO dao = new ZipcodeDAO();
ArrayList<ZipcodeTO> lists = dao.zipcodeSearch(dong + "%");
기존의 mapper 지우고 인터페이스 만들어서 작업하기
package mapper;
import java.util.ArrayList;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import model1.BoardTO;
public interface BoardMapperInter {
@Insert("insert into board values(0,#{subject}, #{writer}, #{mail}, #{password}, #{content}, 0, #{wip}, now())")
public int boardWriteOks(BoardTO to);
@Select("select seq, subject, writer, date_format(wdate,'%Y-%m-%d') wdate, hit from board order by seq desc")
public ArrayList<BoardTO> boardLists();
@Select("select seq, subject, writer, mail, wip, date_format(wdate,'%Y-%m-%d')wdate, hit, content from board where seq=#{seq}")
public BoardTO boardViews(BoardTO to);
@Update("update board set hit=hit+1 where seq=#{seq}")
public int boardViewHit(BoardTO to);
@Select("select seq, subject, writer, mail, content from board where seq = #{seq};")
public BoardTO boardModifys(BoardTO to);
@Update("update board set subject = #{subject}, mail = #{mail}, content = #{content} where seq = #{seq} and password = #{password};")
public int boardModifyOks(BoardTO to);
@Select("select seq, subject, writer, mail, content from board where seq = #{seq};")
public BoardTO boardDeletes(BoardTO to);
@Delete("delete from board where seq = #{seq} and password = #{password};")
public int boardDeleteOks(BoardTO to);
}
DAO에서 맞게 바꿔주기 (jsp는 건들지 않는다) : 마찬가지로 to가 새로 만들어지기 때문에 seq를 가져와야 한다.
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;
import mapper.BoardMapperInter;
public class BoardDAO {
private SqlSession sqlSession;
private BoardMapperInter mapper;
// 생성자가 필요
public BoardDAO() {
String resource = "myBatisConfig.xml";
InputStream is = null;
try {
is = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory
= new SqlSessionFactoryBuilder().build(is);
this.sqlSession = sqlSessionFactory.openSession(true);
this.sqlSession.getConfiguration().addMapper(BoardMapperInter.class);
this.mapper = (BoardMapperInter) sqlSession.getMapper(BoardMapperInter.class);
} 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 = mapper.boardWriteOks(to);
if(result == 1) {
flag = 0;
}
if(sqlSession != null) sqlSession.close();
return flag;
}
// list는 ArrayList로 받아온다
public ArrayList<BoardTO> boardList() {
ArrayList<BoardTO> datas = mapper.boardLists();
if(sqlSession != null) sqlSession.close();
return datas;
}
// to에 seq가 들어가서 update하고 select 함
public BoardTO boardView(BoardTO to) {
mapper.boardViewHit(to);
to = mapper.boardViews(to); <-- 두 개의 to는 다른 것,
mapper.boardViews(to)가 new로 새롭게 생성된다고 보면 된다.
따라서 우리가 받았던 seq가 초기화되기 때문에 다시 받는 것이다.
if(sqlSession != null) sqlSession.close();
return to;
}
public BoardTO boardModify(BoardTO to) {
to = mapper.boardModifys(to);
if(sqlSession != null) sqlSession.close();
return to;
}
public int boardModifyOk(BoardTO to) {
int flag = 2;
int result = mapper.boardModifyOks(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 = mapper.boardDeletes(to);
if(sqlSession != null) sqlSession.close();
return to;
}
public int boardDeleteOk(BoardTO to) {
int flag = 2;
int result = mapper.boardDeleteOks(to);
if(result == 0) {
flag = 1;
}
else if(result == 1) {
flag = 0;
}
if(sqlSession != null) sqlSession.close();
return flag;
}
}