웹 : 3Tier로의 확장, DB연결하기 : 0320
🚩오늘의 할일
1. 미들티어와 데이터 베이터 베이스 사이의 관계
2. 그 사이의 jdbc 어떻게 작용하는가
3. 왜 필요한가 jdbc
사용파일 : LoginProcessControllerServlet
그동안의 복습...
클라이언트 요청을 WAS 미들티어가 받는다. 어떤 아키텍쳐, 디자인패턴, api를 사용하는가
SOLID원칙에 따라.
Http로 어떤 Line, Head, Body로 보내며 어떤 메세지 교환 규칙성을 가지고 주고 받는가
기본객체를 알아보고 데이터를 정리해봄.
컨트롤러 :LoginProcessControllerServlet 파일에서 보면 요청을 받으면 검증을 하고 Line에서 status 코드를 준다.
검증된 요청을 처리할 모델이 컨트롤러와 결합력을 가진다. 이것은 000을 통해서 낮출 수 있다.
저장된 데이터에 접근하는 DAO 레이어, 퍼시스턴트 레이어. 거기서 RowData 가져온다. 그것을 가지고 요리하는 비지니스 로직 레이어. DAO와 또 결합력이 발생한다. 사실상 모든 레이어에서 결합력이 생기고 그것을 나추기 위하여 인터페이스를 사용하였다. 인터페이스로 사용방법을 지정해두고 아직 퍼시스턴트 레이어가 생기지 않았어도 결합력을 낮췄기 때문에 동시에 개발을 할 수 있다. 협업. 가공을 하든 하지않든 데이터가 오고 가기 때문에 데이터를 묶어놓는 도메인 레이어가 필요하다.
<< 퍼시스턴트 레이어의 역할 >>
오라클, mariaDB, SQLlite : 관계형 데이터
엔터티와 엔터티 엔터티와 릴레이션 => 객체로 표현하지 않는다. 즉 자바로 오면 그대로 사용할 수 없다. 표현방법을 맞춰주는 역할은? 퍼시스턴트 레이어
1. 저장되어있는 결과를 가져오는 select역할, 2. 가져온 데이터를 자바 객체의 형태로 만들어주는 역할
==> 비지니스 로직레이어에 전달되는 것은 로직레이어의 자바객체
비지니스 로직 레이어는 인포메이션으로 만들어서 컨트롤러에 보내고 컨트롤러레이어는 뷰레이어로 이동하며 데이터를 이동한다.
flow Control
1. dispatch, 2. redirect ==> 현재 request를 이동 이후 살려야하는가 / 아닌가
인증 시스템 => 보안과 연관된다. 잘못된 요청을 발생시켰어도 redirect로 이동시켜서 불순한 요청을 남겨두지 않고 지운다.
페이지를 모듈화할 수 있는 include, 한 jsp페이지에 여러 페이지가 합쳐져서 이루어지는 것.
2023.03.17 - [Spring] - 웹 : scope : 0317(2)
웹 : scope : 0317(2)
🚩오후에 할일 Scope까지 알아보면 pageContext가 모두 설명된다. 👍 Scope알아보고 활용까지 ✌️ 2Tier -> 3Tier 이어주는 jdbc 까지 오후 사용할 파일 : propertyView.jsp , PropertyContollerServlet 👍 Scope알아보
bodong22.tistory.com
1.어트리부트 대신 해주면 좋겠다...
2.캐스팅하기 귀찮다...
이걸 대신 해주는 것? Expression Language인 EL이다.
EL은 어트리부트를 쉽게 가져오긴하지만 가지고 놀수는 없다.
랭귀지는 보통 이프문이나 제어문으로 데이터를 가지고 노는데 EL은 그런기능이 없다.
그래서 EL은 혼자 사용하지 않고 EL + JSP 합쳐서 사용한다.
-----
아키텍쳐는 전체, 하나의 객체, 하나의 메서드 안에서 사용하는 것 디자인 패턴
ContextResourceBrowsingServlet 여기에 보면 디자인 패턴, api없이 사용해본 예
FancytreeNode 인터페이스를 만들어서 fancytree 를 사용해봄.
이 대상이 무엇이 될지 모르기때문에 (파일?, 객체?) 인터페이스로 만들었다.
FileWrapper 가 fancytreenode구현체. ==> 어댑터이고 기본생성자 없다.
(MyWebResource 가 어댑터사용하지 않은 예. 비교해볼 수 있다.)
오늘 수업
2Tier -> 3Tier로 확장.
클라이언트와 미들티어 사이에는 http 프로토콜이 있지만 미들티어와 db사이에는 프로토콜이 없다.
연결을 해야하기때문에 커넥션을 수립해야한다. 그러려면 같은 언어를 사용해야한다. 그래서 이 커넥션 수립을 위해 사용할 방식을 모른다. 미들티어는 자바 디비는 무엇인지 모르니까. 그래서 인터페이스로 연결할수있도록 만들고 각 디비회사에서 구현체를 제공한다. 그렇다면 인터페이스는 어디에 있지?
각각의 벤더들은 밴더사들이 제공한다.
SELECT *
FROM DATABASE_PROPERTIES;
드라이버를 설치하려니까 프로젝트여러개에서 다같이 쓰고 싶어서 아예 서버에 넣어버리자!
그래서 카탈리나 홈에다 복사해넣기.
==> Facade pattern 가장 대표적인 퍼사이드 객체는 리모컨 : 퍼사이드 객체는 실제 동작하는 객체에게 명령을 내리는 것. 드라이버 사용법만 알면 디비가 무엇이든 사용하게 해주는 것. ==> 누르는 인터페이스는 모두 비슷하기 때문에 ==>이런것은 sql 패키지에 정의가 되어있다. ==> 퍼사드 동작만 알면 되는데 퍼사드도 알 필요가 없는게 인터페이스 누르는 방식만 알면 되기 때문 ==> 이것이 드라이버를 사용하는 이유.
▶jdbcDesc.jsp
1. driver 를 현재 빌드패스에 추가
2. 객체를 운영하는 버츄얼 머신에게 드라이버 클래스를 알려주기 위해 드라이버 로딩하는것.
<% MemberVO vo = new MemberVO(); %>
1. MemberVO 클래스를 method area(상수 메모리)에 적재(loading)
==>> method area(상수 메모리) 는 상수, 가비지 컬렉의 대상이 아니다. class가 저장되는 곳.
2.1번에서 로딩된 클래스를 바탕으로 인스턴스를 생성(생성자), heap area 에 적재
==>heap area는 가비지 컬렉션의 대상이다. 언제든지 널 레퍼런스가 나오면 사라진다.
3. vo 변수에 2번의 메모리 참조 주소(reference)를 할당
3. Connection 수립
<%
String url = "jdbc:oracle:thin:@localhost:1521:xe";
String user = "LDY92";
String password="java";
Connection conn = DriverManager.getConnection(url, user, password);
DatabaseMetaData metaData = conn.getMetaData();
out.println(metaData.getDriverVersion());
%>
4. 쿼리 객체 생성(Statement) : sql 컴파일과 실행 담당.
[IT정보] SQL(Structured Query Language) 개념
구조화 질의어(SQL: Structured Query Language)란? 의미 SQL은 데이터베이스를 사용할 때 데이터...
blog.naver.com
SQL 작업을 해주는 것이 statement
프로시져 펑션 : 절차적 형태...?
ResultSet: set의 인덱스없음, 중복없음의 특징을 가지고 있는 결과 집합. 프라이머리 키 중복없음 인덱스없음 랜덤액세스없음 => 이터레이터로 반복하여 다음것을 찾는다.
닫
이미 회피전략이 _jspservlet에 있었고 우리가 쓰는 모든 jsp코드는 그 안에 들어간다. trycatch가 이미 되고있다.
sqlexception은 톰캣에 알려줘야하는데 체크드 이셉션 그대로는 회피할 수 없다. 그래서 이셉션을 언체크드이셉션으로 전환해준후 회피해야한다.
1.8버전에선 AutoCloseable을 임플리먼츠하는지 확인하고 try에서 close 처리할 수 있다.
▶PropertyDAOImpl_FS , PropertyDAOImpl_DB , interface PropertyDAO
List<PropertyVO> list = new ArrayList<>();
query for list 는 null 을 반환하지 않고 길이 0을 반환하므로 어레이 리스트 를 생성한다.
quey for object는 null반
▶PropertyDAOImpl_DBTest junittest
import static org.junit.Assert.*;
static import : 자바 7버전에서 새로 생긴건데 assert안에 있는 것 모두를 담은 임포트
사실이것은 Assert.assert인건데 그냥 assert로 쓰게 해주려고.
▶jdbcDesc_case3.jsp , JdbcPropertiesControllerServlet
// 헤더받기
String accept = req.getHeader("accept");
List<PropertyVO> list = service.retrieveProperties();
req.setAttribute("list", list);
String viewName = null;
// 헤더가 json ? ==> 마샬링 JsonViewSerlvet.java
if(accept.contains("json")) {
viewName = "/jsonView.view";
}else {
// 헤더가 html ? ==> 그냥 XMLViewServlet.java
viewName = "/WEB-INF/view/13/jdbcDesc_case3.jsp";
}
// flow control
req.getRequestDispatcher(viewName).forward(req, resp);
<script type="text/javascript">
let listBody = $("#listBody");
$.getJSON("")
.done(function(resp){
let trTags = [];
$(resp.list).each(function(idx, propertyVO){
let tr = $("<tr>").append(
$("<td>").html(this.propertyName)
, $("<td>").html(this.propertyValue)
, $("<td>").html(this.description)
).data("source", this);
trTags.push(tr);
});
listBody.empty();
listBody.append(trTags);
});
</script>
(오후수업 시작)
문제점 찾기 : jdbcDesc_case1.jsp , PropertyDAOImpl_DB
1.드라이버 로딩은 맨처음 한번만 하면 된다. 메서드 영역(상수영역)에 저장되기 때문이다.
2.url, user, password가 하드코딩 되어있다.
Factory Object Pattern : 객체를 생성하는 공장 패
// 코드블럭 생성자 다음 실행
{
}
// static 코드블럭
static {
}
<%--
// 1. MemberVO 클래스를 method area(상수 메모리)에 적재(loading)
// static code block 실행
// 2. 1번에서 로딩된 클래스를 바탕으로 인스턴스를 생성(생성자), heap area 에 적재
// 3. vo 변수에 2번의 메모리 참조 주소(reference)를 할당
--%>
art + shift + c : 파라미터 추가하기
''가 있을 것을 생각하고 or를 연산자로 받고 뒤에를 참으로 만들어서 실행되도록 해버린 것. 동적쿼리문이라 가능했던것 state
==> 정적쿼리인 preparedStatement를 사용한다.
KISA
...https://www.kisa.or.kr/2060204
KISA 한국인터넷진흥원
www.kisa.or.kr
소프트웨어 개발 보안 가이드
웰컴페이지 저번시간에 만들었던 것을 db에 연결하여 만들어보자.
미션
1.
SELECT TABLE_NAME, TABLESPACE_NAME, NUM_ROWS
FROM USER_TABLES; => 딕셔너리 뷰. 조회만하면 됨.
모델2, 레이어 아키텍쳐,
몇개의 레이어로 쪼갤 것인지
2.
선택한 한 테이블의 스키마 정보를 출력
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM COLS
WHERE TABLE_NAME = 'MEMBER';
==>도메인 레이어 2개, > 퍼시스턴트레이어 인터페이스 2개 (VIEW 하나당 하나라서 ) > 비지니스로직레이어 > 컨트롤러, 뷰 설계 > JSON으로만, 비동기 case3