JSP서블릿 9일차

하파타카·2022년 1월 21일
0

JSP서블릿 수업

목록 보기
7/10
post-thumbnail

한 일

  • TODO App -2-
  • 기본페이지설정
  • todo페이지 CRUD 기능 만들기
  • CRUD 기능 테스트

Todo App 만들기 -2-

기본페이지설정

web.xml의 기본페이지를 수정.
WEB-INF/web.xml

<welcome-file-list>
  <welcome-file>login</welcome-file>
</welcome-file-list>

header.jsp의 로그인 링크 "<%=request.getContextPath()%>/login"로 수정해 LoginController서블릿으로 가도록 수정.

LoginController서블릿의 doGet메서드 수정
LoginController.java(servlet)

HttpSession session = request.getSession();
// get방식으로 넘어왔을땐 user창과 message창을 비워줌
session.setAttribute("user", "");	
session.setAttribute("message", "");

// 로그인 페이지로 이동
response.sendRedirect("login/login.jsp"); 	
// login폴더 안의 login.jsp로 이동. forward가 아니라 단순히 페이지만 이동함

=> 이제 맨 처음 방문시 로그인페이지의 메시지창과 id창에 null값이 안뜸

todo페이지 CRUD 기능 만들기

  • CRUD: Create, Read, Delete, Update의 줄임말로 입력, 읽기, 삭제, 업데이트 기능을 말한다.

TodoDao 인터페이스 만들기

TodoDao 인터페이스. 메서드와 매개변수, 리턴형을 지정한다.
구현은 안되어있으며 TodoDaoImpl클래스에서 이 인터페이스를 구현해서 기능을 완성해야함.

todoApp.dao/TodoDao.java(interface)

void insertTodo(Todo todo);			// Create 입력 => 할 일을 DB에 입력
Todo selectTodo(long todoId);		// Read => id로 할일을 검색 
List<Todo> selectAllTodos();		// Read => 모든 할일을 검색 (DB에서 <Todo>의 list타입으로 결과를 리턴받음) 
boolean deleteTodo(long todoId);	// Delete => id로 할일을 삭제 (제대로 삭제되었는지 true, false로 리턴)
boolean updateTodo(Todo todo);		// Update => 할일을 업데이트 (제대로 업데이트되었는지 true, false로 리턴) 

TodoDaoImpl 클래스 구현하기

TodoDao 인터페이스를 상속받아 TodoDaoImpl 클래스를 구현한다.
DB와 직접 연결되어 각 기능(CRUD)을 수행하는 작업을 할 예정.
앞서만든 TodoDao인터페이스에 메서드와 매개변수, 리턴형이 지정되어 있으므로 그대로 구현하면 된다.

todoApp.dao/TodoDaoImpl.class insert메서드

String INSERT_USER_SQL = "INSERT INTO todos(title, username, description, target_date, is_done) "
		+ "VALUES (?, ?, ?, ?, ?)";
try {
// 우변은 JDBCUtils클래스에 미리 만들어둔 getConnection()메서드를 말함
	Connection conn = JDBCUtils.getConnection(); 
	PreparedStatement pstmt = conn.prepareStatement(INSERT_USER_SQL);
	// 아래 속성들은 Todo클래스에서 가져와야함
	pstmt.setString(1, todo.getTitle());
	pstmt.setString(2, todo.getUsername());
	pstmt.setString(3, todo.getDescription());
	pstmt.setDate(4, JDBCUtils.getSQLDate(todo.getTargetDate()));	
        // JDBCUtils에서 만들어둔 SQLDate메서드로 java날짜를 SQL날짜로 변경해 4번째 ?에 넣어줌
	pstmt.setBoolean(5, todo.isStatus());		// pstmt 준비완료 (모든 ?를 채움)
	
	pstmt.executeUpdate();	// 입력은 리턴값이 없음
	
} catch (SQLException e) {
	System.out.println("SQL todo입력 에러..");
} // insert 작업이므로 리턴값 없음

todoApp.dao/TodoDaoImpl.class delete메서드

// id로 검색해 삭제
String DELETE_TODO = "DELETE FROM todos WHERE id = ? ";
boolean rowdeleted = false;

try {
	Connection conn = JDBCUtils.getConnection();
	PreparedStatement pstmt = conn.prepareStatement(DELETE_TODO);
	pstmt.setLong(1, todoId);
	rowdeleted = pstmt.executeUpdate() > 0;	// 한 행이상 삭제되면 true
	
} catch (SQLException e) {
	System.out.println("SQL todo삭제 에러..");
}
System.out.println("삭제 완료");
return rowdeleted;

todoApp.dao/TodoDaoImpl.class update메서드

// 같은 id의 모든 데이터 업데이트
String UPDATE_TODO = "UPDATE todos set title=?, username=?, description=?, target_date=?, is_done=? WHERE id=?";
Boolean rowupdate = false;

try {
	Connection conn = JDBCUtils.getConnection();
	PreparedStatement pstmt = conn.prepareStatement(UPDATE_TODO);
	// 아래 속성들은 Todo클래스에서 가져와야함
	pstmt.setString(1, todo.getTitle());
	pstmt.setString(2, todo.getUsername());
	pstmt.setString(3, todo.getDescription());
	pstmt.setDate(4, JDBCUtils.getSQLDate(todo.getTargetDate()));
	pstmt.setBoolean(5, todo.isStatus());
	pstmt.setLong(6, todo.getId());
	
	rowupdate = pstmt.executeUpdate() > 0;
	
} catch (SQLException e) {
	System.out.println("SQL todo업데이트 에러..");
	return false;
}
System.out.println("업데이트 완료");
return rowupdate;

todoApp.dao/TodoDaoImpl.class selectTodo메서드

// 할일을 하나 검색했을 때. id로 검색함. 리턴값이 있음.
Todo todo = null;
String SELECT_TODO_BY_ID = "SELECT id, title, username, description, target_date, is_done FROM todos WHERE id = ?" ;

try {
	Connection conn = JDBCUtils.getConnection();	// DB연결함
	PreparedStatement pstmt = conn.prepareStatement(SELECT_TODO_BY_ID);
	pstmt.setLong(1, todoId);
	
	ResultSet rs = pstmt.executeQuery();	// 쿼리문 실행한 값을 ResultSet의 객체 rs에 저장 
	if(rs.next()) {	// 결과가 있으면 값을 저장. 없을때 저장하면 에러발생.
		long id = rs.getLong("id");	// 리턴값을 long타입의 id에 저장
		// 우변은 DB의 속성이름, 좌변은 리턴받은 우변의 데이터를 저장하는 변수의 이름 
		String title = rs.getString("title");
		String username = rs.getString("username");
		String description = rs.getString("description");
		LocalDate targetDate = rs.getDate("target_date").toLocalDate();
        // 그냥 rs.getDate("target_date")하면 java날짜와 SQL날짜형이 달라 에러나므로 로컬데이트(자바날짜)로 변환
		Boolean status = rs.getBoolean("is_done");
		todo = new Todo(id, title, username, description, targetDate, status);
	}
	
} catch (SQLException e) {
	System.out.println("SQL todo검색 에러..");
}
return todo;

todoApp.dao/TodoDaoImpl.class selectAllTodos메서드

// 모든 할일을 검색했을 때
List<Todo> todos = new ArrayList<>();	// 빈 ArrayList를 생성
Connection conn = JDBCUtils.getConnection();	// DB연결함
String SELECT_ALL_TODOS = "SELECT * FROM todos"; // todos테이블 전체검색

// try-catch문은 PreparedStatement객체를 만들때 생기는 예외를 처리하는 작업이므로 Connection의 위치는 상관없음.
// 원래는 Connection객체를 선언할때도 예외처리가 필요하지만 JDBCUtils클래스에서 getConnection메서드의 예외처리를 이미 해주었으므로 여기선 다시 안해줘도 됨
try {	
	PreparedStatement pstmt = conn.prepareStatement(SELECT_ALL_TODOS);	// 쿼리문에 ?가 없으므로 바로실행
	ResultSet rs = pstmt.executeQuery();	// 쿼리실행 후 결과저장 
	// 결과가 여러행일 경우 while()을 사용하여 처리함. 한 행일땐 if문 사용.
	while(rs.next()) {	// 결과가 있을 경우 값을 저장. 없는데 저장하면 에러발생
		long id = rs.getLong("id");
		String title = rs.getString("title");
		String username = rs.getString("username");
		String description = rs.getString("description");
		LocalDate targetDate = rs.getDate("target_date").toLocalDate();
        // 그냥 rs.getDate("target_date")하면 java날짜와 SQL날짜형이 달라 에러나므로 로컬데이트(자바날짜)로 변환
		Boolean status = rs.getBoolean("is_done");
		// 리스트에 담기 (todo객체로 입력)
		todos.add(new Todo(id, title, username, description, targetDate, status));
	}	// while문은 rs.next(한 행이 끝나면 다음행으로 넘어감)에 값이 있을 경우 반복해서 실행됨
} catch (SQLException e) {
	System.out.println("SQL todo ALL검색 에러..");
	return null;
}
return todos;

=> selectAllTodos메서드 잘모르겠으니 체크.

try-catch문은 PreparedStatement객체를 만들때 생기는 예외를 처리하는 작업이므로 Connection의 위치가 try-catch문 안이던 밖이건 관계없음.
원래는 Connection객체를 선언할때도 예외처리가 필요하지만 JDBCUtils클래스에서 getConnection메서드의 예외처리를 이미 해주었으므로 여기선 다시 안해줘도 된다.

CRUD 기능 테스트

test패키지 아래 test클래스를 만들어 main메서드에서 각 메서드의 기능이 DB에 작동되는지 테스트한다.

test/test.class

TodoDaoImpl dao = new TodoDaoImpl();

// 입력테스트용
Todo todo = new Todo(1L, "할일1", "hong", "처음 할일", LocalDate.parse("2022-01-20"), false);
Todo todo2 = new Todo(2L, "할일2", "son", "두번째 할일", LocalDate.parse("2022-01-21"), false);
Todo todo3 = new Todo(3L, "할일3", "kim", "세번째 할일", LocalDate.parse("2022-01-22"), true);
dao.insertTodo(todo);
dao.insertTodo(todo2);
dao.insertTodo(todo3);

// 검색테스트용
Todo t1 = dao.selectTodo(1);
System.out.println(t1.toString());	

// 삭제테스트용
Boolean t2 = dao.deleteTodo(3);	

// 업데이트 테스트용
Todo todo4 = new Todo(2L,"할일_수정", "park", "수정한 할일", LocalDate.parse("2022-01-31"), true);
dao.updateTodo(todo4);	

// 전체검색 테스트용
List<Todo> todos = dao.selectAllTodos();	
for(Todo todo5 : todos) {
	System.out.println(todo5.toString());
}
  • 입력 결과

  • 검색 결과

  • 전체검색 결과

  • 업데이트 결과

  • 삭제 결과

모든 메서드 정상동작 확인.

profile
천 리 길도 가나다라부터

0개의 댓글

관련 채용 정보