JSP & Servlet

85.Index 페이지 추가하기

사용자가 보는 공지목록과 공지내용을 만들었다.
이제 관리자 페이지로 해야한다. 그전에 관리자든 일반유저든 기본으로 보는내용 = 인덱스페이지이다.

인덱스.jsp만들기
인덱스 컨트롤러가 컨트롤러 패키지에 다들어갔다. 사실 여러개의 컨트롤러가 다 만드는게 아니다.
controller.notice이런식으로 패키지를 세분화 해주자.

86. Admin 페이지를 위한 서비스 목록 추가하기


admin 페이지를 위한 서비스 목록 추가하기
공개를위한 버튼 삭제를 위한 버튼이 따로 있다.
1.일괄공개요청 pubNoitceAll(ids)
2.일괄삭제요청 removeNoticeAll(ids)
3.글쓰기-글등록 공지등록요청 insertNotice(notice)
4.자세한페이지 수정 삭제등 버튼 공자삭에 요청 deleteNotice(id)
5.공지수정요청 수정페이지ㄱ서 요청 updateNotice(noitce)
6.인덱스페이지에서의 페이지 요청 getNoticeNewestList()

intert delete등은 실행한 후에 반환값으로 몇개에 영향을 주었는지를 반환값으로 받는다.

87. admin/index 페이지 추가하기

관리자 홈 공지사항 메뉴가있음. 일반적으로는 대시보드 형태로 집계된 데이터를 가져옴.
프로젝트에 같은 컨트롤러가 있어서 이상하게 url이 입력이된다. 클래스자체가 요청된다.
정상적으로 url매핑을 못함.

88. admin/notice/list 페이지 추가하기

일반유저가 봣던거랑 다른것은 관리를 위한 것들이 있다.

89. 다중 선택 값 POST 하기

관리자페이지 공개 삭제 등 다중값보내기다중값이 두종류잇을때 구분하는 방법
값을 전달하는 방법 24강 다중값보내기 참조하자
<td><input type="checkbox" name="open-id" value="${n.id}"></td>
<td><input type="checkbox" name="del-id" value="${n.id}"></td>
open-일괄공개 버튼 del-일괄삭제 버튼연동을 어떻게 하는가?
체크박스는 이름은 open-id로 가는데 전달되는 값이 없는데 전달할 값은 id로 선택해서 지우니 id로 하자.
del도 마찬가지로 값을 id로 받자.
<input type="submit" class="btn-text btn-default" value="일괄공개">
<input type="submit" class="btn-text btn-default" value="일괄삭제">
값이 전달되기 위해서는 submit버튼이 checkbox가 같은 폼안에 있어야한다.
<form action="list" method="post"> post요청을 하자.
같은 폼안에 있으니 어떤 것을 체크하던 submit버튼을 누르면 다 전달이된다.
그래서 어떤 값을 처리할것인지 구분해줘야한다.
개발자도구에서 이름이 잘지정되고 있는지를 확인해주자.
체크를 하고 일괄삭제 버튼을 누르면 체크한 것들이 전달되는 것을 알 수 있다.
사진참조
그런데 서버쪽에선 이것들을 어떻게 받을 것인가?
doPost메소드로 받으면된다.
admin ListController보기
String[] openIds = request.getParameterValues("open-id");
String[] delIds = request.getParameterValues("del-id");

90. 다중 submit 요청 구분하기

체크된내용들이 다 같게 들어갔다. 이를 어떻게 서버쪽에서 구분할까?
submit 밸류를 버튼의 값으로 사용한다. 일반적인 입력버튼과는 다르게 눌리지 않은 버튼은 가지 않는다.
그래서 키를 같게 name="cmd" 로해도 구분을 할 수 있게 된다.
<input type="submit" class="btn-text btn-default" name="cmd" value="일괄공개">
<input type="submit" class="btn-text btn-default" name="cmd" value="일괄삭제">
admin ListController보기
String cmd = request.getParameter("cmd");
switch(cmd){
case "일괄공개":
break;
case "일괄삭제":
break;
}
버튼 요청을 처리 하는데 실제로 공개/비공개를위한 컬럼이 필요하다.
이러면 db수정, entity수정, 몇가지 수정 스트레스 받기위해 알아보자.
먼저 컬럼을 추가해보자
PUB컬럼 추가 TRUE FALSE값을 받기위해 NUMBER 크기는 1 기본값은 0(FALSE)

91.일괄삭제 구현하기

삭제버튼 누르고 일괄삭제
case "일괄삭제":
NoticeService service = new NoticeService();
service.deleteNoticeAll(delIds);
break;
}
정상적으로 지우면 지워진상태에서 목록을 볼 수있는 겟요청을 하면된다.
response.sendRedirect("list");
같은 서블릿에서 같은 url을 사용하고 있지만 다른페이지에서 post요청에서 get요청을 하기위해서 리디렉트를 한다.
클라이언트가 아니라 서버가 서버에서 다른 페이지를 요청하듯이 요청함.
그런데 아이디 기본적으로 정수형이니 정수형으로 전달하는게 낫다.
int[] ids = new int[delIds.length];
for(int i =0; i<delIds.length; i++) {
ids[i] = Integer.parseInt(delIds[i]);
}
int result = service.deleteNoticeAll(ids);
배열복사해서 int 배열로 바꿔주자.

String sql = "DELETE NOTICE WHERE ID IN (1,2,3)"
배열이 들어가야하는데 JDBC에서 배열이 들어가는게 있느냐? 없다. 그래서 값을 꽃아넣기 위해 배열을 넣을 수있도록
String params = "";를 만들어서 배열을 만들어주자.
for (int i = 0 ; i<ids.length; i++) {
params += ids[i];
if(i < ids.length-1) {
params += ",";
}
}
i가 마지막보다 작을 경우를 제외하고 ,를 넣어서 ,가 포함된 문자열을 만들어주자.

92. 공지사항 등록을 위한 Controller/View 준비하기

먼저 regController생성해준다.
여기서 해야하는 일은 1.겟요청 2.포스트요청
글쓰기버튼을 누르면 글쓰기 위한 페이지 제공(get) ->등록시 포스트(post)
나중에 폼에 추가//enctype="multipart/form-data"
문제점 1.open이 null or true라 직접 db에 가기 힘들다.
2.한글이깨진다. 필터이용하기

93. pub 컬럼 추가에 대한 변경사항 처리

열하나 추가했을 뿐인데 수정사항이 정말 많다!
db테이블에만 pub가잇고 응용프로그램에는 준비가 안되있다.
가끔 기획자, 운영자가 컬럼 하나만 추가해달라할때 기술자가 인상을 팍쓰는경우가 있다.
그런데 말한사람은 쉽지만 고칠사람은 정말 많은 것을 고쳐야하기 때문이다.
받을 수있는 담는 그릇의 속성도 바꿔줘야한다.
1.클래스 다시쓰기
컨트롤 f3누르면 해당 클래스 열림!
1.pub 필드만들기 2.생성자에 추가하기 3.값을 받기위해 게터세터 추가하기
자동으로 만들면 boolean의 게터는 isXX이름이니 get이름으로 바꿔서 쉽게 사용할수 있도록 하자.

2.데이터베이스 수정
NOITCE_VIEW PUB추가하기

3.NOTICEVIEW의 생성자 변경하기

4.NoticeService에서 데이터를 담는 쿼리들이 모두 오류가 발생한다.

정말 할게 많다!!
수정하는게 쉽지않음. 하나 고치는것에서 매우 할게 많음 빠르게 고치는 것도 능력이긴함.

94. 공지사항 등록하기

public int insertNotice(Notice notice){}
인서트문 작성하고 제목, 내용. 작성자(원래는 관리자를 해서 권한을 설정해야하지만 그냥), pub넣어준다.
그리고 작성후 list페이지를 다시 보여준다.
response.sendRedirect("list");
경로를 지정하지 않으면 현재 가지고 있는 url의 것을 요청하게 됨.

95. 관리자 공지사항 자세한 페이지 추가

사용자가 보는 디테일 페이지와 크게 다르지 않다.
일반페이지와 다른점은 수정과 삭제 버튼이있다.

96. 파일업로드를 위한 인코드 multipart/form-data

파일업로드를 위해서는 파일을 어떻게 인코딩하는지 멀티파트인코디이란 뭘의미하는지
등록페이지를 통해 등록데이터는 어떻게 등록이 되는지?
reg.jsp의 폼태그
<form method="post" action="reg" enctype="application/x-www-form-urlencoded">
하면 인코딩타입을 정해줄수있다. 기본인코딩타입은 url을 사용할 수 있는 형태로 인코딩이 된다는 것임.
그러나 이렇게하면 파일면ㅇ만 전송된다.
인코딩 타입을 multipart/form-data로 바꿔주자


url인코딩방식으로 가면 문자열만가고
multipart 는 문자열, 문자열, 바이너리 데이터가 가게된다.
인코딩방식이 바꼇는데 제목이 인식이안될때 어떻게 해야하나? 다음강의로 가자

97. 파일업로드를 위한 서블릿 설정

인코딩을 받았는데 서버쪽에서도 인코딩 설정을 받아야한다.

web.xml에 설정하기
<multipart-config>
<location>/tmp</loaction>
<max-file-size>20848820</max-file-size>
<max-request-size>418018841
<file-size-threshold>1048576
</multipart-config>

annotation으로 설정하기
@MultipartConfig(
location="/tmp",
fileSizeThreshold=1024*1024,
maxFileSize=1024*1024*5,
maxRequestSize=1024*1024*5*5)
전자를 사용하면 어떤파일에서 설정하든 필요하면 가져다쓰면됨
어노테이션은 클래스마다 설정해줘야함.
location fileSizeThreshold 이 두속성은 연결되어있다. 용량이 클경우 메모리에 저장하면 서버쪽메모리가 넘어간다.
일정메모리가 넘어가면 디스크를 사용한다. 1메가바이트가 넘으면 디스크를 사용하자.
maxFileSize, maxRequestSize은 파일을 보낼때 첨부파일을 여러개 보낼수도있다. 파일두개가 전송된다.
전체네트워크를 통해 받는 데이터가 굉장히 큰사이즈가 된다. 너무많이 받으면 디도스처럼 서비스가 마비되는 수가있다.
이것을 제한을 거는 것이다.
maxFileSize은 한개의 파일이다. 하나의 파일 사이즈가 맥시멈 5메가바이트
이걸 여러개 보낼수잇으니 maxRequestSize 전체요청에 대한 파일을 25메가 로한다는 것.
너무 적은양이라 50메가씩 최대 5개로 설정하였다.
location fileSizeThreshold은 속성에 대한 내용이 애매하다.
로케이션은 절대경로를 사용해야한다.? -> 기본값이 있다.
상대경로를 쓸수없고 절대경로를 구해야하는데 config하는동안 코딩이되는 것이아니기때문에 미리 설정하는 것이 불가능하다.
그래서 설정을 하지 않는다.
@MultipartConfig(
fileSizeThreshold=1024*1024,
maxFileSize=1024*1024\50,
maxRequestSize=1024\
1024*50*5)
멀티파트로 인코딩방식을 바꾸면 그것을 서버쪽에서도 멀티파트로 인코딩할수있도록 설정을 해줘야한다.

98. 파일저장을 위한 물리경로 얻기

파일을 포스트하기 위해서 인코디을 하고 서버가 받는 설정을 했다.
클라이언트가 보낸 내용을 서버쪽에서 받고 저장하기 위해 저장경로를 어떠헥 할 것인가를 설정해보자.
<td colspan="3" class="text-align-left text-indent"><input type="file"name="file" />
이름은 파일이고 형식은 파일로 담아져있다. 우리가 필요한것은 키값인 'file'이다.
이 파트정보의 컨텐츠를 얻어야한다.
request.getPart() request.getParts() 두가지가있다.
전자는 전달한 매개 값을 가지고 특정파트를 얻는것임.
후자는 파트전체를 받아오는것임.
Part filePart = request.getPart("file");
filePart.getInputStream(); Part객체를 만들고 인풋스트림을 얻는다.

/upload라는 디렉토리에 저장하려면 어떻게 해야할까ㅣㅣ?
request.getServletContext();를 사용하면 웹루트를 통해서 루트를 통한 상대경로를 넘겨주면 시스템의 실제물리경로를 얻어주는 함수가있다.
request.getServletContext().getRealPath("/upload"); 겟리얼패스로 물리경로를 얻자.
upload라는 파일을 만들고 하면 왜안되나? 이것은 개발을 하기 위한 임시 위치일뿐이다.
이클립스 workspace에 .metadata안에 저장된다. 서비스되고있는 어플리케이션에 저장이된다.

99. 단일 파일 업로드

사용자가 전달한 파일을 실제 물리경로에 저장하는 작업
출력을 어디에할건가? 리얼패스에 저장해야한다. 실제 풀경로를 얻어야한다.
realPath + File.separator +fileName에 파일명을 얹어야한다.
파일명은 String fileName = filePart.getSubmittedFileName();으로 얻을수있다.
/upload/fileName을 할건데 가운데 "//"이런식으로 넣으면안되고 자바가 사용하고 잇는 경로 구분방법인 File.separator을 사용해야한다.
Part filePart = request.getPart("file");
String fileName = filePart.getSubmittedFileName();
InputStream fis =filePart.getInputStream();

String realPath = request.getServletContext().getRealPath("/upload");
String filePath = realPath + File.separator +fileName;
FileOutputStream fos = new FileOutputStream(filePath);

byte[] buf = new byte[1024];
int size = 0;
while ( (size = fis.read(buf)) != -1) {
fos.write(buf, 0, size);

}
fos.close();
fis.close();

100. 다중 파일 업로드

파일이 여러개여도 차이가 크지는 않다.
<td colspan="3" class="text-align-left text-indent"> </td>
<td colspan="3" class="text-align-left text-indent"> </td>
두개를 만들어줘서 전체 목록화해서 받아주자.
if(!p.getName().equals("file")) continue;
파일이면 패스 파일이면 반복하게하기
Collection<Part> parts = request.getParts();
for(Part p : parts) {
if(!p.getName().equals("file")) continue;

Part filePart = p;
String fileName = filePart.getSubmittedFileName();
InputStream fis =filePart.getInputStream();

String realPath = request.getServletContext().getRealPath("/upload");
String filePath = realPath + File.separator +fileName;
FileOutputStream fos = new FileOutputStream(filePath);

byte[] buf = new byte[1024];
int size = 0;
while ( (size = fis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
fos.close();
fis.close();
}

파일업로드를 했으니 이제 db에 어떻게 저장하는가?
StringBuilder builder = new StringBuilder();
builder.append(fileName);
builder.append(",");
파일면 , 파일명, 해주기
마지막엔 ,가들어가면안되니까 마지막은 ,을 빼주자. 이번면 for문이 끝나면 마지막,을 없애도록 해보자.
builder.delete(builder.length()-1, builder.length());

notice.setFiles(builder.toString());해주기

101. 업로드 된 파일 사용하기

public int insertNotice(Notice notice)
INSERT구문에서 파일을 넣지 않았었다. FILE을 넣고 ?도 추가해주자.
st.setString(5, notice.getFiles()); 넣어주자.

그러면 파일이 넣어진다. 그런데 파일을 누르면 다운이 되지않고 404에러가뜬다.
detail의 첨부파일 영역을 수정해주자.
하이퍼링크가 경로가빠져있고 이름만 추가가되어있다.
그러면 현재 url을 기반으로해서 파일명이 추가가되는 것이다.
"/upload/${fileName}" upload에 있다는 것을 나타내주자.
그런데 이미지파일이 열리긴하는데 다운로드가 안된다.? 옛날에는 다운로드가 어려웠으나
a download href= "/upload/${fileName}" html 코드로 download만 추가해주면된다.
첨부파일로만 사용하는게 아니라 첨부한 파일을 태그화해서 게시판의 내용에 넣고 싶다면?
content에 파일넣는방법
<img src="/upload/img1.png"> 이런식으로 html을 넣으면된다.
그러면 태그를 모르면 어떻게쓰나? 보통은 웹 편집기가 있어서 클릭으로 될 수 있도록 하는 메뉴가 존재한다.

102. 파일 업로드 마무리

다중파일 업로드가 되도록 했는데 오류가 발생할 수있다.
1.파일을하나만 넣으면 오류발생한다.
for문을 돌리면서 넣는데 파일이 두개가 전달된다. 멀티파트로 가면서 파일을 선택하지 않아도 전달되다가 오류가 발생한다.
if(p.getSize() == 0) continue;
사이즈가 0인경우 파일이긴한데 실제 데이터로서 바이너리를 전달하지 않고 그냥 비어있는 데이터가 포스트가 될때 처리하는 것이다.
이렇게 하면 파일을 하나만 전달할 수있다.

2.개발하면서 upload파일을 만들었다.
실제서비스에서 이것을 배포한다면 만드는게 필요가없다. 그래서 삭제를 할것이다. 이걸 삭제하면 경로가없어서 에러가 날것이다.
실제 경로가 없다면 패스가 없다면 만들어주는 작업을 해줘야한다.
File path = new File(realPath);
실제 물리적인 경로를 얻어냇을때 물리적인 경로가 있느냐라는 것을 알아낼수잇다.
if(!path.exists()) {
path.mkdirs();
}
경로가 없을 경우 경로를 만들어주자.

책임져야할것이 두가지가있다.
1.예외가 발생이하면 사용자화면에도 오류가 뜬다. 그래서 예외처리를 통해 원하는 메시지로 해줘야한다.
2.파일을 저장할때 파일명이 기존의 파일명과 같을 수도 있다. 동일한 파일명이 잇을경우 어떻게 저장해줄까를 지정해줘야한다.
일련번호를 부착하던지 다른 것으로 해보자. 스스로 고민하기!

103. 공개 설정 이용하기

파일업로드 공지사항 등록을 했다.
공개 설정하기.
checkbox를 checked하면 체크가 된다.
<c:set var="open" value=""/>
<c:if test="${n.pub == true}">
<c:set var="open" value="checked"/>
</c:if>
기본값은 빈상태로 두고 pun가 true라면 체크상태로 바꿔주자.
<input type="checkbox" name="open-id" ${open} value="${n.id}">

그런데 사용자페이지에서도 공개된것만 보여야한다.
jsp파일에서 설정할수도있지만 조건처리를 여기서하면 레코드가 10개가 왔는데 다 비공개면 하나도 못보여줄소기앗다.
조건처리가 10번을 돌긴했지만 비어있는 공지성분을 보게된다.
여기서는 무조건 10개를 보고 컨트롤러에서 해야한다.
public List<NoticeView> getNoticeViewPubList(String field, String query, int page) {}
NoticeService에 공개된리스트 메소드를 만들어주자.
SQL문에 "WHERE PUB = 1 AND NUM BETWEEN ? AND ?";을 해줘서 1인것만 검색되게하자.

104. 공지사항 일괄 공개하기

관리자가 체크 한경우 배열이 보여지는 것임.
체크 안된거 사라졋으니 전달해야함. 체크가 id를 이용해서 전달되면1 아니면0
전달된것을 어떻게 하는가 체크가 안된것을 어딘가에 숨겨놓는거임.
페이의 공지사항에 id가 어떤것들이엇다늘 숨겨놓자. 다음에 일괄공개를 누를때 이것을 저달하고 숨겨져있는 목록에 있는 모든 공지사항에 id들을 한번에 전달하는것임
원래목록에 있던것들을 비교해서 체크하는 것이다.
list.jsp를보면 사용자에게 보여줄내용이 반복되고잇다.
서밋버튼위에 하나를 심어주자. 위에서는 사용자에게 보여질 목록을 위해 사용되엇다면 여기서는 그 id들만 추출해서 보여준다.
<c:forEach var="n" items="${list}">
<c:set var="ids" value = "${ids} ${n.id}" />
</c:forEach>
<input type="hidden" name="ids" value="${ids}">
<input type="text" name="ids" value="${ids}">
목록의 id들이 보여진다. text로하면 모두에게 보이니 안보이게 hidden으로 설정해주기
상태를 보고 체크가 된애는 pub를 0으로 된애는 목록에있는 녀석은 1로 바꾸게 전송할 수잇게하자.
사실 일괄공개를 누르고 10개 전부다 1로 업데이트되게 할 수는 있다
String[] openIds = request.getParameterValues("open-id"); //3,5,8
String ids_ = request.getParameter("ids");
String[] ids = ids_.split(" ");//1,2,3,4,5,6,7,8,9,10
각각 목록이 있을때 포함되어있는지를 비교해준다.
case "일괄공개":
//배열을 list로 바꾸어줌
List<String> oids = Arrays.asList(openIds);
for(int i=0; i< ids.length; i++) {
//1.현재 id가 open된 상태냐?
if(oids.contains(ids[i])) {
pub -> 1
}else {
pub -> 0;
}
service.pubNoitceList(openIds); //update notice set pub = 1 where id in(..);
service.closeNoticeList(clsIds); //update notice set pub = 0 where id in(..);
이렇게하면 한번에 처리할 수 있다.

105. 비공개할 id 목록 얻기

공개해야할 id를 얻는것도 중요하지만 이것을 기반으로 비공개할 id를 얻는 것도 중요하다.
지난시간에 for문으로 도는것도 좋지만 귀찮다.
//전체목록 1,2,3,4,5,6,7,8,9,10 - //공개목록 3,5,8
이라한다면 빼주면 비공개할 id목록이 얻어지는것이다.
List<String> oids = Arrays.asList(openIds);
//1,2,3,4,5,6,7,8,9,10 - //3,5,8
Arrays.asList(ids).removeAll(oids);
asList는 정적길이 list객체이기때문에 불가능하다.
List<String> oids = Arrays.asList(openIds);
List<String> cids = new ArrayList(Arrays.asList(ids));
cids.removeAll(oids);
그래서 새로운 객체로 가변길이 Arraylist 객체로 만들어주자.

106. 공개를 위한 서비스 함수의 수정사항

만약 서비스함수를 두개만들어서 공개비공개처리를햇을때 하나만 실행되고 하나는 예외가되어서 실행안되면?
오류가 발생한다.
하고싶은 단위가 하다가 실패하게 된다.
이 하고싶은 단위를 '트랜잭션' 이라고한다. Transaction
한번에 잘실행되어야한다. 실패하면 앞으로 돌려줘야한다. 업무단위를 완전히 하나로 하게 되어야한다.
서비스함수를 하나처럼 되도록하자.
public int pubNoitceAll(int[] ids) {
return 0;
}
설계단계에서 하나의 인자로 만들었엇지만 트랜젝션을 위해 이것을 수정해주자.
public int pubNoitceAll(int[] oids, int[] cids) {
return 0;
}
그러나 넘기고자한게 배열이아니라 컬렉션이다.
그럼 맞춰서 다시 배열로 바꿀건가 사용자(서버)를 위해서 다양하게 전달할수 있게 할가?
하나 더 만들어서 배열을 전달하던지
public int pubNoitceAll(int[] oids, int[] cids) {
return 0;
}
public int pubNoitceAll(List<String> oids, List<String> cids) {
return 0;
}
//"20, 30 ,43 56,"
public int pubNoitceAll(String oidsCSV, String cidsCV) {
return 0;
}
다양하게 넣을수있도록 인트배열, 컬렉션, CSV로받앗을때를 처리할수잇게해주자.
이렇게 오버로드를 통해서 제공자측에선 여러개 제공하고 사용자가 원하는 것을 사용할 수있게 해주자.
SQL구현할때 업데이트 문 안에 ?,?,?,?로 넣는거보다 CSV로 구분된 ?하나로 오는게 더좋을 수있다.

107. 오버로드 서비스 메소드 구현하기

1.인트배열로 바꾸기 String의 join함수를 사용하자.
String.join("구분자", 문자, 문자, ...) 구분자로 알아서 값을 넣을 수 있게 해준다.
그런데 이것은 가변데이터를 나열해야되서 그냥 배열을 넣는게 안된다.
그래서 배열을 문자열 리스트로 바꾸고 넣어주자.
public int pubNoitceAll(int[] oids, int[] cids) {
List<String> oidsList = new ArrayList<>();
for(int i = 0; i < oids.length; i++) {
oidsList.add(String.valueOf(oids[i]));
}
List<String> cidsList = new ArrayList<>();
for(int i = 0; i < cids.length; i++) {
oidsList.add(String.valueOf(cids[i]));
}
return pubNoitceAll(oidsList, cidsList);
}
-> public int pubNoitceAll(List<String> oids, List<String> cids)호출
public int pubNoitceAll(List<String> oids, List<String> cids) {
String oidsCSV = String.join(",", oids);
String cidsCSV = String.join(",", cids);;
return pubNoitceAll(oidsCSV, cidsCSV);
}
-> public int pubNoitceAll(String oidsCSV, String cidsCV) {}호출
이제 마지막 을 구현해주면된다.

108. pubNoticeAll 구현하기

1.문자열형태를 그대로 변영할수있다. 조건처리해서 바꾸기
둘다 실행되어야해서 SQL문을 두개 만들어주자.
PreparedStatement st = con.prepareStatement(sqlOpen);
st.setString(1, oidsCSV);
이런식으로하면 쿼리문에 '23,34,45'문자열로 들어가게된다.
String sqlOpen = "UPDATE NOTICE SET PUB=1 WHERE ID IN(" + oidsCSV + ")";
그래서 그냥 꼽아 넣어주자.
String.format("UPDATE NOTICE SET PUB=1 WHERE ID IN (%s)", oidsCSV);
String의 format을 이용해서 할수도잇다.

2023.01.06 후기

JSP & Servlet강의를 다 들었다. 다시한번 들을때 이해는 할 수 있는 정도는 된 것 같다.
좀 더 배우고 싶지만 끊겨서 아쉽다. 그런데 이제 응용단계라서 찾아보면서 하면될 것 같다.
진짜 얼마 남지 않았다. 매우 두렵다. 진짜 두렵다.

'기초단계 > JSP&Servlet' 카테고리의 다른 글

2023.03.15 Servlet  (1) 2023.03.15
2023.03.14 Servlet  (0) 2023.03.15
2023.01.04 JSP & Servlet  (0) 2023.01.05
2023.01.03 JSP & Servlet  (1) 2023.01.03
2023.01.02 JSP & Servlet  (0) 2023.01.02

+ Recent posts