ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JDBC 활용하기 - JDBC로 읽고 쓰기
    데이터베이스/데이터베이스 기본 2021. 2. 12. 03:05

    2021/02/03 - [데이터베이스/데이터베이스 기본] - JDBC 활용하기 - JDBC 접속하기

     

    JDBC 활용하기 - JDBC 접속하기

    2021/02/03 - [데이터베이스/데이터베이스 기본] - JDBC 활용하기 - 드라이버 다운 및 설정 JDBC 활용하기 - 드라이버 다운 및 설정 2021/02/03 - [데이터베이스/데이터베이스 기본] - JDBC란? (Java Database Con..

    sgcomputer.tistory.com

    JDBC는 자바 프로그램이 데이터 베이스를 쉽게 이용할 수 있도록 만든 자바 API로서

     

    이전에 JDBC를 이용해 데이터베이스에 접속하는 과정까지 진행해본 바 있다.

     

    위 글처럼 데이터 베이스를 설정하고 JDBC설정까지 마쳤다면 정상적으로 접속이 될 것이다.

     

    이번 글에서는 JDBC를 이용한 데이터 읽고 쓰기를 해볼 것이다.

     

    시작하기 전에 대략 어떤 내용을 구현할지 쓰자면 아래와 같다.

     

     

    위와 같이 아이디, 이름, 나이를 입력해 제출하면 데이터가 데이터베이스에 저장된다.

     

     

    그리고나서 위와 같이 현재 데이터 베이스에 저장된 모든 회원 리스트를 가져오는

     

    내용을 실습할 예정이다.

     

    이전에 진행할 실습 내용들을 통해 JDBC, 데이터베이스 세팅이 완료됐다는 전제하에 진행한다.

    필요한 내용들

    해당 기능을 구현해야하는 서블릿, JSP 파일들을 다음과 같다.

     

    1. 개인 정보를 입력하고 제출해야하는 form JSP파일

    2. 입력된 정보를 받아서 처리할 컨트롤러 서블릿

    3. 입력된 정보를 데이터 베이스에 저장할 수 있도록 객체화를 시켜주는 DTO 클래스

    4. DTO를 통해 객체화된 정보를 직접 데이터 베이스에 저장하고 읽어오는 DAO 클래스

    5. DAO를 통해 저장된 정보를 읽어와서 화면에 출력할 회원 LIST를 보여줄 JSP파일

     

    파일을 생성하면 위와 같은 구조가 만들어진다.

    데이터 베이스 생성하기

    2021/01/29 - [데이터베이스/Oracle] - Oracle 오라클 기본 - 테이블 생성, 입력 및 조회, 삭제

     

    Oracle 오라클 기본 - 테이블 생성, 입력 및 조회, 삭제

    오라클이든 mysql이든 기본은 테이블을 중심으로 데이터를 관리한다. 본인이 활용하고자 하는 데이터에 맞는 테이블을 생성하는 것이 기본 중의 기본이다. 테이블의 생성 테이블 생성은 크게 어

    sgcomputer.tistory.com

    생성된 오라클 데이터 베이스가 있다는 전제하에 아래와 같이 테이블을 생성한다.

     

     

    그러면 아래와 같은 컬럼(column)을 가진 테이블이 생성된다.

     

    jdbc form JSP 생성하기

     

    가장 처음으로 사용자가 데이터를 입력할 수 있는 form jsp를 생성해주자.

     

    별다른 새로운 것은 없고 위와 같이 생성하면 아래와 같은 결과물을 볼 수 있다.

     

    데이터를 보낼 경로는 아직만들지 않은 /jdbcController로 보낸다.

     

     

    JDBC 컨트롤러 생성하기

    @WebServlet("/JdbcController")
    public class JdbcController extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {
    		RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/views/jdbcform.jsp");
    		rd.forward(request, response);
    	}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {
    		
    		String id = request.getParameter("id");
    		String name = request.getParameter("name");
    		int age = Integer.parseInt(request.getParameter("age"));
    		
    		DTO dto = new DTO();
    		dto.setId(id);;
    		dto.setName(name);;
    		dto.setAge(age);
    		
    		DAO dao = new DAO();
    		
    		try {
    			dao.add(dto);
    			
    		} catch (ClassNotFoundException | SQLException e) {
    			
    			e.printStackTrace();
    		}
    		
    		try {
    			request.setAttribute("list", dao.read());
    			
    		} catch (ClassNotFoundException | SQLException e) {
    			
    			e.printStackTrace();
    		}
    		
    		RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/views/list.jsp");
    		rd.forward(request, response);
    		
    	}
    
    }

     

    이번에는 위 코드와 같은 컨트롤러를 만들어야 한다.

     

    해당 컨트롤러는 이전에 만든 form jsp에서 보낸 데이터를 처리하는 역할을 한다.

     

    해당 컨트롤러는 doGet메서드와 doPost메서드로 나뉜다.

     

     

     

    doGet메서드는 해당 url로 접속하면 form.jsp 파일의 내용을 보여주는 역할을 한다.

     

    이는 form.jsp가 WEB-INF 폴더 안에 들어있기 때문에 직접 jsp파일로 접근할 수 없기 때문에 이렇게 처리해야한다. 

     

     

     

    그리고 doPost는 form을 통해 전달된 자료를 처리하는 역할을 한다.

     

    doPost메서드는 전달받은 데이터를 DTO를 통해서 객체화한다.

     

    그리고 객체화된 데이터를 DAO를 통해 데이터 베이스에 입력한다.

     

    데이터에 입력이 완료되면 DAO 통해 데이터 베이스에 입력된 자료를 읽어온다.

     

    그리고 이 데이터를 list.jsp로 전달해서 데이터를 보여주는 역할을 한다.

    DTO 생성하기

     

    컨트롤러를 만들었다면 다음은 DTO를 만들어야 한다.

     

    DTO란 Data Transfer Object의 약자로 컨트롤러를 통해 전달받은 데이터를 객체화해주는 역할을 한다.

     

    즉 DTO가 객체가 되고 사용자가 입력한 값을 DTO 객체에 저장하게 된다.

     

     

    간단하게 그림으로 나타내면 위와 같다.

     

    전달받은 값은 DTO 객체에 저장되고 이렇게 저장된 객체를 데이터베이스에 저장하게 되는 것이다.

    DAO 생성하기

    public class DAO {
    	
    	public void add(DTO dto) throws ClassNotFoundException, SQLException {
    		
    		String url = "jdbc:oracle:thin:@localhost:1521/xe";
    		String sql = "";
    		
    		Class.forName("oracle.jdbc.driver.OracleDriver");
    		Connection con = DriverManager.getConnection(url, "servlet", "1234");
    
    		sql = "INSERT INTO JDBC (ID, NAME, AGE) VALUES (?, ?, ?)";
    		
    		PreparedStatement st = con.prepareStatement(sql);
    			
    		st.setString(1, dto.getId());
    		st.setString(2, dto.getName());
    		st.setInt(3, dto.getAge());
    			
    		st.executeUpdate();
    			
    		st.close();
    		con.close();
    		
    	}
    	
    	public List<DTO> read() throws ClassNotFoundException, SQLException {
    		
    		String url = "jdbc:oracle:thin:@localhost:1521/xe";
    		String sql = "";
    		
    		Class.forName("oracle.jdbc.driver.OracleDriver");
    		Connection con = DriverManager.getConnection(url, "servlet", "1234");
    		
    		sql = "SELECT * FROM JDBC";
    		
    		PreparedStatement st = con.prepareStatement(sql);
    		
    		ResultSet rs = st.executeQuery();
    		
    		List<DTO> list = new ArrayList<DTO>();
    		
    		while(rs.next()) {
    			String id = rs.getString("id");
    			String name = rs.getString("name");
    			int age = rs.getInt("age");
    			
    			DTO dto = new DTO( id, name, age );
    			
    			list.add(dto);
    		}
    		
    		rs.close();
    		st.close();
    		con.close();
    		
    		return list;
    	}

     

    DAO란 Data Access Object의 약자로서 객체화된 자료를 직접 데이터 베이스에 저장하는 역할을 한다.

     

    즉 DB에 접속해서 직접 CRUD를 진행하는 역할을 한다.

     

    해당 DAO는 쓰기와 읽기 두 개로 메서드가 나눠져있는데 설명하면 다음과 같다.

     

    우선 쓰기 부분을 설명하면 다음과 같다.

     

     

    우선 앞서 말했듯 DAO는 데이터 베이스에 접속하고 데이터를 저장하는 역할을 한다.

     

    그래서 매번 메서드를 실행할 때 데이터 데이터 베이스에 접속하는 과정을 거쳐야 한다.

     

    가장 먼저 할 것은 데이터 베이스를 접속하고 접속 객체를 얻어오는 것이다.

     

    그리고 나선 해당 연결 객체를 통해 쿼리 문을 설정하고 해당 쿼리문에 맞게 데이터를 지정한다.

     

    그리고 저장하는 것을 통해 이 과정이 끝난다.

     

    더 간단히 설명하면 다음과 같다.

     

    1. Class.forName(), DriverManager.getConnection() 메서드를 통해 연결 객체 얻어냄

    2. 해당 연결 객체를 통해 sql 구문 실행을 도와줄 preStatement 객체를 만든다.

    3. preStatement 객체에 DTO를 통해 전달받은 값들을 하나씩 입력해준다.

    4. executeUpdate() 메서드를 통해 최종적으로 sql 구문을 실행해준다.

     

    이때 중요한건 preStatement 객체다.

     

    preStatement 객체란 데이터 베이스에서 실행되는 sql 구문을 세팅해주는 역할을 한다.

     

    위에서 데이터 베이스에서 실행될 sql 문자열에 물음표(?)가 있는 것을 볼 수 있다.

     

    해당 문자열을 preStatement 메서드 안에 넣고 이를 preStatement객체에 저장하고

     

    setString, setInt 등의 메서드를 쓰면 물음표에 있는 부분에 값을 저장할 수 있다.

     

    위에서 보면 st.setString, st.setInt를 확인해보면 그 내용을 알 수 있다.

     

    그렇게 최종적으로 세팅되면 실행되는 sql 구문은 아래처럼 변화한다.

     

     

    위와 같이 preStatement를 객체를 이용하면 sql문을 세팅할 수 있고 이를 통해 데이터 저장이 가능하다.

     

     

    다음은 데이터 베이스에 저장된 값을 불러오는 읽기 부분인 read 메서드에 대해 살펴보자.

     

    read 메서드도 jdbc를 이용하기 때문에 쓰기와 똑같이 처음에는 똑같이 연결 객체를 얻어야 한다.

     

    그리고 이번에는 모든 회원의 리스트를 가져와야 하기 때문에 위와 같은 sql문을 작성한다.

     

    그다음 바로 excuteQuery() 메서드를 통해 sql문을 실행하고 그 값으르 ResultSet 객체에 저장한다.

     

    ResultSet이란 sql을 입력하고 실행하여 생성된 반환값의 집합을 나타내는 데이터 테이블이다.

     

    그림으로 설명하면 아래와 같다.

     

     

    만약 위와 같은 데이터를 가진 테이블이 있다면 아래와 같은 ResultSet이 만들어진다.

     

     

    이때 중요한 것이 바로 빨간 화살표인 커서의 존재다.

     

    커서란 ResultSet 객체가 특정 row를 지정해서 데이터를 얻어올 수 있도록 하는 존재다.

     

    해당 커서를 조작하면 데이터 베이스 내에서 특정 row(행)을 지정해서 해당 row의 값을 불러올 수 있다.

     

    위 코드에서처럼 ResultSet 객체를 만들면 커서가 생기고 사용자 요청에 맞는 데이터로 커서를 옮겨

     

    데이터를 가져온다.

     

    우선 위와 같이 ResultSet 객체를 생성해줬다면 다음은 데이터 베이스의 결과값을 저장할 List를 만들자.

     

    ResultSet 객체에서 이야기한 것처럼 커서는 특정 row의 값을 가져올 수 있다.

     

    그리고 우리는 이렇게 전달된 row값을 전달된 값을 하나의 DTO 객체에 저장하고

     

    이 DTO 객체를 List에 저장해 한 번에 돌려주는 것이다.

     

    그림으로 이야기하면 다음과 같다.

     

     

    만약 위와 같은 데이터가 있다고 가정해보자.

     

    해당 데이터들은 row값을 기준으로 데이터들이 하나의 그룹으로 반환된다.

     

    위 데이터는 아래와 같이 3개의 데이터 그룹으로 반환될 것이다.

     

     

    그리고 이러한 반환된 데이터는 저장할 때와 마찬가지로 DTO 객체를 이용해

     

    각 row 데이터 별로 DTO 데이터에 저장한다.

     

     

    그리고 이렇게 만들어진 DTO 객체를 저장할 List를 만든다.

     

    그렇게 DTO 객체를 저장할 List를 만들었다면 이제 값을 추출할 차례다.

     

    해당 메서드에서 값을 추출하는 메서드는 next()다.

     

    앞서 서술했듯 ResultSet은 반환값에 대한 데이터 테이블과 커서를 가진다.

     

    next() 메서드는 커서가 있는 위치에서 다음 행으로 이동시키는 것을 말한다.

     

    그림으로 나타내면 다음과 같다.

     

     

    ResultSet 객체를 생성하면 위와 같이 커서와 반환값에 대한 테이블이 생성된다.

     

    여기서 next() 메서드를 쓰면 다음과 같이 상태가 변한다.

     

     

    next() 메서드를 쓰면 현재 커서가 위치한 row(행)에서 다음 row로 이동하여 데이터를 나타내게 된다.

     

    그리고 만약 더이상 row가 존재하지 않으면 next()는 false를 반환한다.

     

    next()의 성질을 이용해 while에 넣으면 ResultSet 객체로 반환된 데이터 테이블의 처음부터 끝을 훑는다.

     

    그리고 이 과정에서 각 row(행)별로 데이터를 받아와서 이를 DTO 객체에 저장하는 것이다.

     

    위에서 rs.getString("컬럼명"), rs.Int("컬럼명") 메서드를 통해 각 데이터 값을 추출할 수 있다.

     

    이렇게 while문을 통해 모든 값을 DTO 객체에 저장하고 이 DTO를 저장한 List를 최종적으로 반환한다.

    list.jsp 생성하기

    앞서 컨트롤러를 통해 DAO의 add를 통해 데이터를 저장하고 DAO의 read를 통해 데이터를 쓰고 읽는 것을 배웠다.

     

    그리고 이렇게 쓰여진 데이터를 읽어오는 과정에서 반환된 list를 보여줄 jsp 파일이 필요하다.

     

     

    그때는 간단하게 전달받은 list를 JSTL을 이용해 나타내주면 된다.

Designed by Tistory.