JSP/서블릿 공부 2021-02-26
유튜브 뉴렉처 JSP/서블릿 강의 66강
JSTl : forTokens로 첨부파일 목록 출력하기
첨부파일을 임시로 데이터 베이스에 추가해준다.

forTokens
items : 값을 입력하고
delims : 값을 주어진 값을 기준으로 끊어달라는 명령
forTokens를 이용해서 fileName이라는 변수로 ${n.files}를 ( , ) 단위로 끊어서 저장
현재단위를 알수있는 varStatus를 선언해 속성을 사용해서 last 값이 true 가 아닐경우 ( ! )에는
/ 를 출력하지 않도록 c:if문을 사용해준다.

c:forTokens 으로 나눈뒤에 / 를 사용하여 각각 나눠진것을 볼수있다(마지막은 c:if문을 이용해 출력되지않게함)

JSTL:format 태그로 날짜형식 변경하기

날짜의 형식을 바꿔주기위해서는 jstl format이라는 라이브러리를 사용해야한다.
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt">
지시자를 통해 라이브러리를 fmt 접두사를 사용하겠다
fmt태그의 종류
기능 |
태그 |
설명 |
숫자 날짜 형식 |
formatnumber |
숫자를 양식에 맞춰서 출력한다. |
formatDate |
날짜 정보를 담고 있는 객체를 포맷팅하여 출력할 때 사용한다. |
|
parseDate |
문자열을 날짜로 파싱한다. |
|
parseNumber |
문자열을 수치로 파싱한다. |
|
setTimeZone |
시간대별로 시간을 처리할 수 있는 기능을 제공한다. |
|
timeZone |
시간대별로 시간을 처리할 수 있는 기능을 제공한다. |
|
로케일 지정 |
setLocale |
국제화 태그들이 사용할 로케일을 지정한다. |
requestEncoding |
요청 파라미터의 인코딩을 지정한다. |
|
메시지 처리 |
bundle |
태그 몸체에서 사용할 리소스 번들을 지정한다. |
message(param) |
메시지를 출력한다. |
|
setBundle |
특정 리소스 번들을 사용할 수 있도록 로딩한다. |
list.jsp 페이지에서 지시자를사용해 fmt접두사 사용 (이때 항상 jsp가 들어가있는 jstl 을 사용해야함)

<fmt:formatDate>속성을 사용해 해당 데이터를 value 값으로 넣어주고 pattern 을 사용자가 원하는 방향으로 설정

이렇게 설정했을시에는 설정한 패턴으로 나온다.

pattern 기호 | |
y | 연도 |
M | 월 |
d | 일 |
h | 시 |
m | 분 |
s | 초 |
*MM은 대문자인이유가 분을 표시하는 m과 알파벳이 동일하기때문에 대소문자로 구분한다.
목록페이지는 일반적으로나오고 자세한페이지에서는 작성한 시간,분,초 까지 나오게 수정해준다.
list.jsp

detail.jsp

JSTL:format 태그로 숫자 형식 변경하기
fmt의 속성중 formatNumber를 사용해서 value값으로 조회수를 넣어주면
formatNumber는 일반적으로 통용되는 숫자형태의 자리수를 표현해준다 (기본적인형태:기본값)


formatNumber 속성은 type을 사용해서 단위 를 바꿔줄수도있다.
pattern을 사용해 사용자 패턴을 지정할수있다 ( # : 숫자 )
숫자의 형식을 바꿀때는 format태그의 formatNumber를 사용하면 된다. (옵션을 추가해 다른기능을 적절히 사용)
JSTL:functions로 EL에서 함수 이용하기
문서내의 문자열을 조작하고싶을때 사용할수 있는 태그

functions 태그는 일반적으로 태그형식으로 쓰이는게아니고 EL 표시 안쪽에서 사용된다.

toUpperCase() 함수는 문자열을 대문자로 바꿔주는 함수
이런방법으로도 사용할수있다 style의 값을 c:set을 이용하여 변수안에 넣어주고
c:if문에서 함수를사용해 fileName의 endsWith가 '.zip'으로 끝나는 경우에 style을 적용시키는 방법
endWith() 함수는 특정문자열로 끝나는지 확인하는 메소드

결과 통해 functions 의 조건처리가 된 것을 확인할수있다.

funtions 의 일반적인 사용방법
기업형으로 레이어를 나누는 이유와 설명
일반적으로 사용하는 기업형 형태
분업화를 위함 , 변경에 대한 부담을 줄이기위해서
Servlet : Controller , 입출력을 담당하는 부분
업무서비스 : 트랜잭션 , 사용자 요청 단위 EX)계좌이체
데이터서비스(DAO) : CRUD , 실제데이터 조작
문서출력 : View

서비스 함수 찾아내기
서비스함수의 구현할때의 기준은 시스템단위
데이터를 관리하는 기능을 별도의 클래스로 만들어 관리
현재 강의 진도 공지클래스의 공지목록조회와 공지상세조회 구현

*서비스를 구현할때에는 사용자요청이 가장 중요하다.

*페이지 이동시에는 사전조건이 있다. (id)값으로 현재페이지 다음글,이전글을 구현하는 서비스를 만들수있다.

서비스 클래스 구현하기
메소드 이름이 같다는것은 기능이같다는것 (코드가 유사하다) 오버로드 방식
같은 이름의 메소드는 하나를 먼저구현하고 그 메소드를 재호출하는 방식으로 해야한다.
인자값이 가장 많은것을 먼저구현해야 가져다 사용하기 편하다.

서비스코드의 구현

서비스 클래스 구현을 위한 SQL코드 작성하기
getNoticeList 구현
쿼리문을 작성할때 일련번호가 필요하기때문에 ROWNUM을사용
서브쿼리를 사용(정렬된 후에 결과값의 ROWNUM이 필요하기 때문)

1~5번까지의 페이징처리는 되지만 6~10 페이징처리는 WHERE이후에 ROWNUM이 만들어지기때문에 불가능하다
해결방법은 서브쿼리를 하나더 만들어주는 방법이다.
안쪽에서 만든 ROWNUM에 별칭을 하나 지어주고 그 별칭이 붙은 ROWNUM를 이용해 페이징 처리를 할수있다.

ROWNUM의 함수를 이용해 사용하는 방법또한 있다.

데이터베이스에서 실행을 해본뒤 이클립스로 복사해서 sql문을 가져온다.
String sql변수에다가 복사해온 sql문을 저장해준다.
\r\n을 제거해주고 문자열사이에 빈공간을 확보해서 sql문이 오류나는것을 방지한다.

getNextNotice를 위한 SQL 코드 작성하기
게시글은 삭제가 될수있기때문에 연속 되고있지 않을수가 있다.
다음게시글을 얻는방법 : 등록일자를 기준으로 역정렬한 상태에서 id코드보다 큰 기준(기준점 REGDATE)

목록에서의 첫번째 레코드를 가져오는방법

REGDATE를 기준으로 ID값을 구하는 서브쿼리문을 만든뒤
그 보다큰 값을 가지고있는 값들중에 ROWNUM가 1인 값을 구한다.
이때 서브쿼리를 사용해 NOTICE를 정렬해주는것이 좋다.

임시로 아이디값은 3 을 넣어줬다, 이클립스로 돌아가 복사 붙여넣기를 하고 수정을 해준다.

getPrevNotice를 위한 SQL 코드 작성하기
이전페이지 작성
정렬을 시키기위해서
SELECT * FROM NOTICE ORDER BY REGDATE DESC 로 역정렬된 NOTICE를 가져오고 (서브쿼리)
SELECT REGDATE FROM NOTICE WHERE ID=3 서브쿼리로 아이디 3의 REGDATE를 가져온다
아이디 3번의 REGDATE보다 작은 값들중에 ROWNUM가 1인값을 찾으면된다.

*다음번호 REGDATE 순으로 정렬된것중에 1번
*이전번호 REGDATE 순으로 역정렬된것중에 1번
getNoticeList의 JDBC 코드 구현하기
컨트롤러에서는 입력과 출력만 신경쓸수있게 수정해준다.
원하는 내용을 캐치 -> 서비스함수 사용
NoticeService 을 임포트해 service 객체를만들어주고
service객체를이용해 getNoticeList() 메소드를 불러와 list의 값을 넣어준다.

LIKE 필터링 서브쿼리중 제일 안쪽에 하는게 안전하다.
WHERE문뒤에 오는 field는 Prepared처리 하지않는이유가 문자열 방식으로 들어가기때문에 ' ' 가 붙기때문에
따로 + 를이용해 합쳐주는방식
LIKE 문에들어갈 quesry 또한 %?% 방식은 적용하지않기때문에 setString에서 "%"+query+"%"한것을 볼수있다.


리턴값으로는 list를 반환해준다.
NoticeService 클래스 완성하기
getNoticeCount(String field,String query) 메소드
반환값이 int이기때문에 count 변수선언 초기값은 0으로준다.
sql문에서 COUNT(ID) 값을이용해 count값을 조회하여 리턴하는 메소드
getInt() 안에는 COUNT(ID)의 별칭인 COUNT(소문자가능) 를 넣어준다
입력받은값을 count 변수안에넣어주고 반환시킨다.

getNotice(int id) 메소드
반환값이 Notice이기때문에 선언해주고 초기값을 null로준다.
인자값을 이용해 setInt()담아 쿼리문을 완성해준다
if(rs.next())를 사용해 조건에맞는 쿼리가있다면 notice객체에 값을 넣어준다.
(이때 if문 안에 id 변수가 중복이여서 nid로 임시방편으로 바꿔주었다)
반환값은 notice

getNextNotice(int id) 메소드
getNotice(int id)와 비슷하다
임시방편으로 주었던 숫자3을 ?로 바꿔주고 인자값인 id 를 받아 쿼리문을 완성

getPreNotice(int id)
getNotice(int id)와 비슷하다
임시방편으로 주었던 숫자3을 ?로 바꿔주고 인자값인 id 를 받아 쿼리문을 완성

뉴렉처 JSP/서블릿 강의 77강 완료