티스토리 뷰

JDBC

검색 메뉴 붙이고 서비스 추가

Programmers 2021. 5. 9. 12:58
반응형
public void inputSearchWord() {
		Scanner scan = new Scanner(System.in);
			//함수안에서 다른곳과 공유안하는게 좋다. 공유안해도되는거면 안하는게 낫다
		System.out.println("검색 범주(title/content/writer_Id)중에 하나를 입력하세요");
		System.out.println(">");
		searchField = scan.nextLine();
		
		System.out.print("검색어 > ");
		searchWord = scan.nextLine();
		
	}

목표: 검색 메뉴 구현

 

program5.java 전체 코드

/* program5.java */
package ex1;

import java.sql.SQLException;

import com.newlecture.app.console.NoticeConsole;

public class program5 {
	/* 탑다운 방식 구현 */
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		NoticeConsole console = new NoticeConsole();
		//console객체가 page를 가지고 있는게 바람직하다.
		
		/* 현재 페이지를 저장하기 위한 상태변수 */
		//int page;
		
		EXIT:
		while(true) {
		console.printNoticeList();	
								//출력할수있게 page를 알려준다.
		int menu = console.inputNoticeMenu();	//

			/* 메뉴 함수 구현*/
			switch(menu){
			case 1:	//상세조회C
				break;
			case 2:	//이전
				/*이전목록으로 돌아가는 함수 */
				console.movePrevList();
				//page--;
				break;
			case 3:	//다음
				/*다음목록으로 넘어가는 함수*/
				console.moveNextList();
				//page++;
				break;
			case 4:	//글쓰기
				break;
			case 5:	//검색
				/* console에서 검색생성 맡긴다 */
				console.inputSearchWord();
				break;	
			case 6:	//종료
				System.out.println("Bye~~");
				break EXIT;
			default:
				System.out.println("<<사용방법 오류: 1~4까지만 입력하세요>>");
				break;
			}
		}
	}
}

program5.java 코드 수정 부분

switch(menu){
			case 1:	//상세조회C
				break;
			case 2:	//이전
				/*이전목록으로 돌아가는 함수 */
				console.movePrevList();
				//page--;
				break;
			case 3:	//다음
				/*다음목록으로 넘어가는 함수*/
				console.moveNextList();
				//page++;
				break;
			case 4:	//글쓰기
				break;
			case 5:	//검색
				/* console에서 검색생성 맡긴다 */
				console.inputSearchWord();
				break;	
			case 6:	//종료
				System.out.println("Bye~~");
				break EXIT;
			default:
				System.out.println("<<사용방법 오류: 1~4까지만 입력하세요>>");
				break;
			}

case 5에 검색기능 추가 및 console에서 검색함수 추가

 

NoticeConsole.java 전체 코드

/* NoticeConsole.java */
package com.newlecture.app.console;

import java.sql.SQLException;
import java.util.List;
import java.util.Scanner;

import com.newlecture.app.entity.Notice;
import com.newlecture.app.service.NoticeService;

public class NoticeConsole {
	
	private NoticeService service;
	/* page를 가질 수있는 상태변수 page추가*/
	private int page;
	/* page내의 개시글 개수 - 계속해서 변하기 때문에 전역변수로 구하는 것은 바람직하지 X*/
	//private int count;
	private String searchField;
	private String searchWord;
	
	
	public NoticeConsole() {
		service = new NoticeService();
		page=1;
		//count=0;
		searchField="TITLE";	//기본값 title을 선택
		searchWord="";
	}
	
	/* 내용 UI*/ 
	public void printNoticeList() throws ClassNotFoundException, SQLException {
		List<Notice> list = service.getList(page, searchField, searchWord);	//인자값을 넘겨받는다.
		int count = service.getCount();	//현제 대이터베이스의 테이블에 몇개의 개시글이 있는지
		int lastPage = count/10;	//100 -> 10, 90 -> 9, 93 -> 9
		lastPage = count%10 == 0?lastPage:lastPage+1;	//나머지가 0이면 그대로, 아니면 +1
		
		System.out.println("──────────────────────────────────────");
		System.out.printf("<공지사항> 총 %d 게시글\n", count);	//게시글수
		System.out.println("──────────────────────────────────────");
		
		for(Notice n : list) {
		System.out.printf("%d. %s / %s / %s\n",
							n.getId(),
							n.getTitle(),
							n.getWriterId(),
							n.getRegDate());
		
		}
		System.out.println("──────────────────────────────────────");
		System.out.printf("         %d/%d pages \n", page, lastPage);
		
		
	}

	/* 메뉴 UI*/
	public int inputNoticeMenu() {
		Scanner scan = new Scanner(System.in);
		
		System.out.printf("1. 상세조회/ 2.이전/ 3.다음/ 4.글쓰기 / 5.검색 / 6.종료 >");
		String menu_ = scan.nextLine();
		int menu = Integer.parseInt(menu_);
		
		return menu;
		
	}
	
	/*이전목록으로 돌아가는 함수 구현*/
	public void movePrevList() {
		if(page == 1) {	//1페이지 일경우 이전페이지없음 조건검사
			System.out.println("==================");
			System.out.println("[이전 페이지가 없습니다.]");
			System.out.println("==================");
			return;
		}
		page--;
	}

	/*다음목록으로 돌아가는 함수 구현*/
	public void moveNextList() throws ClassNotFoundException, SQLException {
		/* 전역변수로 쓰는게 아니라 여기서 값을 다시 호출해서 받아와야한다. 그사이에 값이 또 변경될 수도 있다.*/
		int count = service.getCount();	//현제 대이터베이스의 테이블에 몇개의 개시글이 있는지
		int lastPage = count/10;	//100 -> 10, 90 -> 9, 93 -> 9
		lastPage = count%10 == 0?lastPage:lastPage+1;	//나머지가 0이면 그대로, 아니면 +1
		
		
		if(page == lastPage) {	//현제 페이지가 마지막 페이지인지 조건검사
			System.out.println("==================");
			System.out.println(" [마지막 페이지입니다.]");
			System.out.println("==================");
			page = lastPage;
		}
		else page++;
	}

	public void inputSearchWord() {
		Scanner scan = new Scanner(System.in);
			//함수안에서 다른곳과 공유안하는게 좋다. 공유안해도되는거면 안하는게 낫다
		System.out.println("검색 범주(title/content/writer_Id)중에 하나를 입력하세요");
		System.out.println(">");
		searchField = scan.nextLine();
		
		System.out.print("검색어 > ");
		searchWord = scan.nextLine();
	}
}

 

NoticeConsole 코드 수정 부분 

public class NoticeConsole {
	
	private NoticeService service;
	/* page를 가질 수있는 상태변수 page추가*/
	private int page;
	/* page내의 개시글 개수 - 계속해서 변하기 때문에 전역변수로 구하는 것은 바람직하지 X*/
	//private int count;
	private String searchField;
	private String searchWord;
	
	
	public NoticeConsole() {
		service = new NoticeService();
		page=1;
		//count=0;
		searchField="TITLE";	//기본값 title을 선택
		searchWord="";
	}
	
	/* 내용 UI*/ 
	public void printNoticeList() throws ClassNotFoundException, SQLException {
		List<Notice> list = service.getList(page, searchField, searchWord);	//인자값을 넘겨받는다.
		int count = service.getCount();	//현제 대이터베이스의 테이블에 몇개의 개시글이 있는지
		int lastPage = count/10;	//100 -> 10, 90 -> 9, 93 -> 9
		lastPage = count%10 == 0?lastPage:lastPage+1;	//나머지가 0이면 그대로, 아니면 +1
		
		System.out.println("──────────────────────────────────────");
		System.out.printf("<공지사항> 총 %d 게시글\n", count);	//게시글수
		System.out.println("──────────────────────────────────────");
		
		for(Notice n : list) {
		System.out.printf("%d. %s / %s / %s\n",
							n.getId(),
							n.getTitle(),
							n.getWriterId(),
							n.getRegDate());
		
		}
		System.out.println("──────────────────────────────────────");
		System.out.printf("         %d/%d pages \n", page, lastPage);
		
		
	}

	/* 메뉴 UI*/
	public int inputNoticeMenu() {
		Scanner scan = new Scanner(System.in);
		
		System.out.printf("1. 상세조회/ 2.이전/ 3.다음/ 4.글쓰기 / 5.검색 / 6.종료 >");
		String menu_ = scan.nextLine();
		int menu = Integer.parseInt(menu_);
		
		return menu;
		
	}

searchField 기본값 title로, searchWord 전역 변수 추가
내용 UI에서 service.getList를 통해서 searchField 값과 searchWord 값을 받아와서 저장
메뉴 UI에서 검색기능 추가

NoticeService.java 전체 코드

/* NoticeService.java */
package com.newlecture.app.service;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import com.newlecture.app.entity.Notice;
/* CRUD 서비스 목록을 반환하는 함수 */ 
public class NoticeService {
	/* 반복되는 url을 올려서 정의 */
	private String url = "jdbc:oracle:thin:@localhost:1521/XE";
	
	/* 반복되는 id, pwd를 올려서 정의 */
	private String uid = "programmers";
	private String pwd = "111111";
	
	/* 반복되는 Driver를 올려서 정의 */
	private String driver = "oracle.jdbc.driver.OracleDriver";
	
	/*List-> java.util import */
	/*List<Notice>라는 목록으로 반환 */
	public List<Notice> getList(int page, String field, String query) throws ClassNotFoundException, SQLException{
								//getList()함수를 가지고 반환을 하겠다.
								//List<>라는 컬렉션에 담아서 준다. getlist(int page)로 page값을 받아온다.
								// field는 검색할 목록, query 검색어
		int start = 1 + (page-1)*10 ;	//1, 11, 21, 31, ..
		int end = 10*page;	// 10, 20, 30, ..
				
		String sql = "SELECT * FROM NOTICE_VIEW	WHERE " +field+ " LIKE ? AND NUM BETWEEN ? AND ?";
								//+field를 통해서 문자열을 바로 대입해야한다. ? 사용하면 예를들어 'title'처럼 ''와 같이 값이 들어간다. 
								//PreparedStatement로 ? ? ?를 받아와라
		
		Class.forName(driver);
		Connection con = DriverManager.getConnection(url, uid, pwd);
		/* PreparedStatement를 설정해서 page 설정*/
		PreparedStatement st = con.prepareStatement(sql);
		st.setString(1, "%"+query+"%");	//query를 받아오는 preparedStatement
		st.setInt(2,  start);
		st.setInt(3,  end);
		ResultSet rs = st.executeQuery();
		
		/*반환 하기 위한 목록을 만든다 */
		List<Notice> list = new ArrayList<Notice>();
		
		
		/* Notice를 담을 수있는 그릇이 필요 -> 클래스 추가 entity 이름 Notice.java 추가(그릇, 서비스x)*/
		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");
			/*files 추가 */
			String files = rs.getString("FILES");
			
			/*Notice라는 객체를 통해서 notice를 하나 만들면서 초기화하는 생성*/
			Notice notice = new Notice(
					/*Notice.java 생성자와 담을때 딱 맞게 객체를 만들어야 한다. */
					id,
					title,
					writerId,
					regDate,
					content,
					hit,
					files //files 반환값 추가
					);
			/*notice라는 놈을 추가해서 목록에 하나하나 추가 */
			list.add(notice);
			}
				
		rs.close();
		st.close();
		con.close();
		
		return list;
	}

	public int insert(Notice notice) throws ClassNotFoundException, SQLException {
		/*title, writerId, content, files를 정의*/
		/* Notice클래스 내의 함수 호출 */
		String title = notice.getTitle();	
		String writerId =notice.getWriterId();
		String content = notice.getContent();
		String files = notice.getFiles();	//Notice수정해서 files 추가
	
		/*INSERT SQL문 */
		String sql = "INSERT INTO notice ("
				+ "    title,"
				+ "    writer_id,"
				+ "    content,"
				+ "    files"
				+ ") VALUES (?,?,?,?)";	//PreparedStatement를 통한 전달
		
		Class.forName(driver);
		Connection con = DriverManager.getConnection(url, uid, pwd);
		
		/*PreparedStatement도구 사용*/
		PreparedStatement st = con.prepareStatement(sql);	
			//sql문 prepareStatement를 이용해서 st에 저장
		
		/*preparedStatement이용, setString(인덱스값[1부터], 변수)로 저장 */
		st.setString(1, title);
		st.setString(2, writerId);
		st.setString(3, content);
		st.setString(4, files);
		
		/*preparedStatement를 사용 할때에는 sql문을 전달하지 않는다! 이미 전달 되어있다.*/
		int result = st.executeUpdate();
			//excuteUpdate는 int로 실행된 row값을 result에 전달

		st.close();
		con.close();
		
		return result;
	}
	
	public int upate(Notice notice) throws ClassNotFoundException, SQLException {
		/*title, content, files, id를 정의*/
		/* get함수로 변경 */
		String title = notice.getTitle();
		String content = notice.getContent();
		String files = notice.getFiles();
		int id = notice.getId();
	
		/*UPDATE SQL문 */
		String sql = "UPDATE notice "
				+ "SET title=?,"
				+ "    content=?,"
				+ "    files=?"
				+ "WHERE id=?";	//PreparedStatement를 통한 전달
		
		Class.forName(driver);
		Connection con = DriverManager.getConnection(url, uid, pwd);
		
		/*PreparedStatement도구 사용*/
		PreparedStatement st = con.prepareStatement(sql);	
			//sql문 prepareStatement를 이용해서 st에 저장
		
		/*preparedStatement 저장 */
		st.setString(1, title);
		st.setString(2, content);
		st.setString(3, files);
		st.setInt(4, id);	//id는 int형이기 때문에 setInt로 저장
		
		/*preparedStatement를 사용 할때에는 sql문을 전달하지 않는다! 이미 전달 되어있다.*/
		int result = st.executeUpdate();
			//excuteUpdate는 int로 실행된 row값을 result에 전달

		st.close();
		con.close();
		
		return result;
	}
	
	//scalar 단일값을 가지는 함수
	public int getCount() throws ClassNotFoundException, SQLException {
		int count = 0;
		String sql = "SELECT COUNT(ID) count FROM NOTICE";
			//테이블에서 count함수를 통해서 ID개수를 가져온다. 별칭 COUNT

		Class.forName(driver);
		Connection con = DriverManager.getConnection(url, uid, pwd);
		Statement st = con.createStatement();
		
		ResultSet rs = st.executeQuery(sql);
		
		if(rs.next())		
			count = rs.getInt("COUNT");
						
		rs.close();
		st.close();
		con.close();
		// TODO Auto-generated method stub
		return count;
	}
	
	
	
	public int delete(int id) throws ClassNotFoundException, SQLException {
	
		/*DELETE SQL문 */
		String sql = "DELETE notice WHERE id=?";	//?:PreparedStatement를 통한 전달
		
		Class.forName(driver);
		Connection con = DriverManager.getConnection(url, uid, pwd);
		
		/*PreparedStatement도구 사용*/
		PreparedStatement st = con.prepareStatement(sql);	
			//sql문 prepareStatement를 이용해서 st에 저장
		
		/*preparedStatement 저장 */
		st.setInt(1, id);	//id는 int형이기 때문에 setInt로 저장
		
		/*preparedStatement를 사용 할때에는 sql문을 전달하지 않는다! 이미 전달 되어있다.*/
		int result = st.executeUpdate();
			//excuteUpdate는 int로 실행된 row값을 result에 전달
				
		st.close();
		con.close();
		
		return result;
	}	
}

 

NoticeService 코드 수정 부분

		String sql = "SELECT * FROM NOTICE_VIEW	WHERE " +field+ " LIKE ? AND NUM BETWEEN ? AND ?";
		//+field를 통해서 문자열을 바로 대입해야한다.
		// ? 사용하면 예를들어 'title'처럼 ''와 같이 값이 들어간다. 
		//PreparedStatement로 ? ? ?를 받아와라
		
		Class.forName(driver);
		Connection con = DriverManager.getConnection(url, uid, pwd);
		/* PreparedStatement를 설정해서 page 설정*/
		PreparedStatement st = con.prepareStatement(sql);
		st.setString(1, "%"+query+"%");	//query를 받아오는 preparedStatement
		st.setInt(2,  start);
		st.setInt(3,  end);
		ResultSet rs = st.executeQuery();

SQL 쿼리문에서 field(검색할 목록)는 문자열로 바로 대입하고 -> 값으로 대입하면 ''이 붙어서 오류발생
query(검색어)는 preparedStatement를 통해서 값을 대입한다.

 

검색 메뉴 구현

검색을 통해서 게시글을 받아온다.
문제점: 게시글의 총 갯수가 아닌 현재 받아온 결과값은 갯수 및 Page 수가 출력되어야한다.

반응형
댓글
공지사항