2023.01.25-2 JDBC
JDBC
16 - 공지사항 메뉴 붙이기
public int inputNoticeMenu() {
Scanner sc = new Scanner(System.in);
System.out.print("1.상세조회/ 2.이전/ 3.다음/ 4.글쓰기 >");
String menu_ = sc.nextLine();
int menu = Integer.parseInt(menu_);
return menu;
}사용자가 선택할 수잇는 메뉴를 만들어주자. nextInt로할경우 버퍼가 남아잇거나 하는경우 문제가 생길수잇으니
nextLine을 하고 타입변환을 해주자.
라벨문 사용해서 종료하자. https://whereisusb.tistory.com/276
자바 반복문에서의 LABEL 확인해보자.
public static void main(String[] args) throws ClassNotFoundException, SQLException {
NoticeConsole console = new NoticeConsole();
EXIT:
while (true) {
console.printNoticeList();
int menu = console.inputNoticeMenu();
switch(menu) {
case 1: //상세조회
break;
case 2: //이전
break;
case 3: //다음
break;
case 4: //글쓰기
break;
case 5: //글쓰기
System.out.println("프로그램 종료");
break EXIT;
default:
System.out.println("<<사용방법>> 메뉴는 1~4까지만 입력할 수 있습니다.");
break;
}
}17. 페이징을 위한 쿼리 만들기
목록을 10개씩 나눠서 보고싶다. 그럼 일련번호가 있다면? 나눠서 볼 수잇다.
테이블을 정의하지않아도 ROWNUM을 사용하면된다.
SELECT ROWNUM, NOTICE.* FROM NOTICE
WHERE ROWNUM BETWEEN 1 AND 10;
테이블이 만들어진 후 ROWNUM이 붙여지기때문에 2부터하면 안나온다.
1.서브쿼리를 사용해서 ROWNUM을 붙인 후에 WHERE절을 하기
SELECT * FROM (SELECT ROWNUM NUM, NOTICE.* FROM NOTICE)
WHERE NUM BETWEEN 1 AND 10;
또다른 문제가 발생한다. 가장최신거부터 보여줘야하는데 역정렬을 해야한다.
1.역정렬을한다. -> 2.ROWNUM을 붙인다 -> 3.출력한다의 순으로 가야한다.
서브쿼리를 한것에 ROWNUM을 붙이는 것이니 별칭을 붙여줘서 N.*을 해주는 것을 잊지말자.
SELECT * FROM (
SELECT ROWNUM NUM, N.* FROM (
SELECT * FROM NOTICE ORDER BY REGDATE DESC
) N
)
WHERE NUM BETWEEN 1 AND 10;
18. 페이징 쿼리 이용하기
String sql = "SELECT * FROM ( "
+ " SELECT ROWNUM NUM, N.* FROM ( "
+ " SELECT * FROM NOTICE ORDER BY REGDATE DESC "
+ " ) N "
+ ") "
+ "WHERE NUM BETWEEN ? AND ?";
sql문이 달라지게 된다.
각각들어가야할 값은 다음과 같다. 첫숫자는 1 11 21 이니 시작이 1이고 공차가 10인 등차수열이다.
int startNum = 1+ (page -1 *10); //a1 + (n-1)*d(공차); 1,11,21
int endNum = 10*page; //10 20 30 40
19. 목록을 위한 View 생성하기
공지사항을 가지고 num을 붙이고 햇다. 정렬인상태로 붙엿다. 이런형태의 데이터가 없어서 서브쿼리를 하나씩 넣은 것이다.
create view NOTICE_VIEW3
AS
SELECT * FROM (
SELECT ROWNUM NUM, N.* FROM (
SELECT * FROM NOTICE ORDER BY REGDATE DESC
) N
);
그러면 이것을 뷰로 만들버리면 된다. (이전에도 만든게잇어서 3이다.)
SQL문이 한줄로 줄어버리게 된다.
String sql = "SELECT * FROM NOTICE_VIEW3 WHERE NUM BETWEEN ? AND ?";
20. 이전 / 다음 구현하기
public void movePrevList() {
if(page ==1 ) {
System.out.println("이전 페이지가 없습니다.");
}
page--;
}
다음페이지는 마지막페이지를 아직 알수없으니 미구현임.
public void moveNextList() {
if(page == lastPage ) {
System.out.println("다음 페이지가 없습니다.");
}
page++;
}
현재 몇개페이지에서 몇번 패이지인지 알아야한다. 1/2 pages
21. 게시글 갯수 구하기
총개수를 얻어내보자. 10개씩이니 몇게 게시글인지를 나누면 총 몇페이지인지 알 수 잇다.
private int count;를 넣어보자.
이 count를 어디서 얻어오냐? 리스트를 출력할때 count를 계속가져우야한다.
이런 단일 값을 얻어온다고 할때 Scalar값을 얻어온다라고 한다.
//Scalar
public int getCount() throws SQLException, ClassNotFoundException {
int count = 0;
String sql = "SELECT COUNT(ID) COUNT FORM NOTICE";
Class.forName(driver);
Connection con = DriverManager.getConnection(url, uid , pwd);
PreparedStatement st = con.prepareStatement(sql);
ResultSet rs = st.executeQuery();
if(rs.next()) {
count = rs.getInt("COUNT");
}
rs.close();
st.close();
con.close();
return count;
}22. 마지막 페이지 구하기
count = service.getCount();
count는 서비스를 부르면 값이 넣어지도록 객체를 생성해준다.
int lastPage = count/10;
lastPage =count%10>0?lastPage+1:lastPage ;
총게시물을 보여줄 게시물수로 나누면 총페이지수가 나오긴하는데 나머지가 잇을경우가 문제이다.
나머지가 잇을 경우에는 +1을 하도록 3항연산자를 해주자.
다음페이지에서의 count와 목록의 count가 다를 수잇기때문에 사용하기 위해서는 다시 service객체를 만들어준다.
public void moveNextList() throws ClassNotFoundException, SQLException {
count = service.getCount();
int lastPage = count/10;
lastPage =count%10>0?lastPage+1:lastPage ;
if(page == lastPage ) {
System.out.println("================");
System.out.println("다음 페이지가 없습니다.");
System.out.println("================");
}
page++;
}23. 검색 메뉴 붙이기
5번에 검색을 넣어보자.
public void inputSearchWord() {
Scanner sc = new Scanner(System.in);
System.out.println("검색 범주(title/content/writerId) 중에 하나를 입력하세요");
System.out.print(">");
searchFiled = sc.nextLine();
System.out.print("검색어 >");
searchWord = sc.nextLine();}
24. 검색 서비스 추가하기
public List<Notice> getList(int page, String filed, String query)
1.어떤 필드로 검색할 건지 2.실질적인 검색어 query로 받자.
"SELECT * FROM NOTICE_VIEW3 WHERE ? LIKE '%A%' AND NUM BETWEEN ? AND ?";
로하면 문자열로 들어가기때문에 'TITLE'이런식으로 들어가서 SQL문이 오류가 생긴다.
String sql = "SELECT * FROM NOTICE_VIEW3 WHERE" + field + "LIKE ? AND NUM BETWEEN ? AND ?";
%A%부분은 문자열로 들어가도되니 그냥 ?로 해준다.
st.setString(1, "%" + query + "%"); 을 해주면된다.
public List<Notice> getList(int page, String field, String query) throws ClassNotFoundException, SQLException {
int startNum = 1 + (page-1)*10; //a1 + (n-1)*10; 1,11,21
int endNum = 10*page; //10 20 30 40
String sql = "SELECT * FROM NOTICE_VIEW3 WHERE " + field + " LIKE ? AND NUM BETWEEN ? AND ?";
Class.forName(driver);
Connection con = DriverManager.getConnection(url, uid , pwd);
PreparedStatement st = con.prepareStatement(sql);
st.setString(1, "%" + query + "%");
st.setInt(2, startNum);
st.setInt(3, endNum);
ResultSet rs = st.executeQuery();
List<Notice> list = new ArrayList<>();
while(rs.next()) {
int id = rs.getInt("ID");
String title = rs.getString("TITLE");
String writerId = rs.getString("WRITER_ID");
Date regdate = rs.getDate("REGDATE");
String content = rs.getString("CONTENT");
int hit = rs.getInt("HIT");
String files = rs.getString("FILES");
Notice notice = new Notice(
id,
title,
writerId,
regdate,
content,
hit,
files
);
list.add(notice);
}
rs.close();
st.close();
con.close();
return list;
}filed기본값으로는 title이 들어가게 하고 찾을 값에는 빈문자열을 넣는다. 기본상태에서는 전부다 나오게 되는것이다.
여기서 문제점은 getList에 넣어버리니 보이는 10개중에 검색을 할 수있는게 문제다.
web을 할때 햇던것은 오버로딩을 해서 검색시, view보여주기를 나눳다. 여기서도 적용할 수 있을 것 같다.
25. 트랜잭션(Transaction) 처리란
하나의 단위로 수행되길 바라는 쿼리의 묶음(=업무 수행단위, 논리적인 수행단위)
예를들어 이체 -update를 두번해야한다.
트랜잭션 처리란?
ACID를 유지하는것
Automaticity :원자성
Consistency :일관성
Isolation : 고립성
Durability : 지속성
2023.01.25 리뷰
일단 보고싶었던 기초 부분들은 한번씩 훑어보기는 하게 된 것 같다. 백엔드 부분은 두번째 보면 조금 아주 조금은 이해를 쉽게 할 수 있을 것 같다.
당장 내일부터 국비 지원이다. 잘 되고 싶다.