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 리뷰

일단 보고싶었던 기초 부분들은 한번씩 훑어보기는 하게 된 것 같다. 백엔드 부분은 두번째 보면 조금 아주 조금은 이해를 쉽게 할 수 있을 것 같다.
당장 내일부터 국비 지원이다. 잘 되고 싶다.

'기초단계 > DB&JDBC' 카테고리의 다른 글

2023.03.07 DB  (0) 2023.03.07
2023.03.06 DB  (1) 2023.03.06
2023.01.24-2 JDBC  (0) 2023.01.24
2023.01.11 DB  (1) 2023.01.11
2023.01.09 DB  (1) 2023.01.09

+ Recent posts