[Study #24] 게시판 화면 구동하기

    반응형

     

    01. 'board.jsp' 수정

    • text-decoration: none; //글자 밑줄 없애기
    • :hover //마우스 올렸을 때 설정
    • 겹치는 부분은 ','로 이어 줄 수 있음

    [ 코드 추가하기 ]

    .title a{
    	text-decoration: none;
    	color: black;
    }
    
    tr:hover, tr:hover a {
    	background-color: #E0E0E0;
    	color: black;
    }

     

    • 'board.jsp' 바로 접속하면 서버 오류 : 써블릿으로 설정했기 때문에 통과해서 jsp로 가야 함 (바로 갈 수 없음) 

    오류화면

     

    02. 'DBConnection.java' 생성하기

     

    01) jar 파일 추가하기

     

    02) class 생성하기

     

    03) DBConnection 코드 작성

    • 싱글턴은 외부에서 조작 못하게 설정
    import java.sql.Connection;
    import java.sql.DriverManager;
    
    public class DBConnection {
    
    	// 반환
    	private static DBConnection dbConn = null;
    
    	// 생성자
    	private DBConnection() {
    	}
    
    	// 싱글턴 인스턴스를 반환하는 메서드
    	// synchronized = 예약어
    	public synchronized static DBConnection getInstance() {
    		if (dbConn == null) {
    			dbConn = new DBConnection();
    			// 없으면 만들어서 리턴, 있다면 그냥 리턴
    		}
    		return dbConn;
    	}
    
    	// getConn
    	public Connection getConnection() {
    		Connection conn = null;
    		String url = "jdbc:mariadb://ip주소/위치";
    		String id = "아이디";
    		String pw = "비밀번호";
    
    		try {
    			Class.forName("org.mariadb.jdbc.Driver");
    			conn = DriverManager.getConnection(url, id, pw);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    		return conn;
    	}
    }

     

    03. 테이블 생성하기

     

    [ step 1 ] 사이트 접속

     

    AQueryTool

    AQueryTool은 웹 기반 ERD 툴 + SQL 자동 생성 프로그램입니다.

    aquerytool.com

     

    [ step 2 ] 테이블 생성

     

    [ step 3 ] 테이블에 원하는 내용 입력

     

    [ step 4 ] 만든 내용을 토대로 테이블 생성하기

     

    [ step 5 ] mariaDB에서 쿼리에 붙여넣고 실행하면 board 생성

     

    [ step 6 ] 다시 사이트로 가서 테스트 데이터 100개 생성하기

     

    [ step 7 ] 데이터가 들어왔는지 확인하기

    방법 1
    방법 2

     

    [ step 8 ] 'bcontent' 추가해주기

     

    - 방법 1) 테이블에서 직접 추가하기

     

    - 방법 2) 쿼리에서 명령문 "ALTER TABLE 'board' ADD COLUMN 'bcontent' TEXT NOT NULL AFTER 'btitle;" 실행하기

    ( 테이블 'board'에다 'btitle' 뒤에 'bcontent' 추가하기)

     

    [ step 9 ]  UPDATE board SET bcontent='내용; UPDATE board SET bwrite='열무'; 쿼리문에서 실행하기 

    (bcontent를 다 내용으로 채우기)

     

    [ step 10 ]  뷰 생성하기

    • view는 실제로 존재하지 않는 가상의 테이블로, 보는 용도로만 사용함
    • dao에서 보드판 내용을 활용하려고 만들어줌

    CREATE VIEW boardview as

    SELECT bno, btitle, bwrite, bdate, blike

    FROM board ORDER BY bno DESC LIMIT 10

    ( 'boardview' 이름을 가진 bno, btitle, bwrite, bdate, blike의 뒤에서 10개까지만 가져오는 뷰 만들기)

    쿼리 명령문

     

    'boardview' 완성 화면

     

    - 쿼리문 연습하기 ; 한 줄 삭제하기

     

     

    04. 'BoardDTO' 수정하기

    • private String에 'bcontent' 추가하고, get/set 생성해 주기
    public class BoardDTO {
    	private int bno, blike;
    	private String btitle, bwrite, bdate, bcontent;
    
    	public int getBno() {
    		return bno;
    	}
    
    	public void setBno(int bno) {
    		this.bno = bno;
    	}
    
    	public int getBlike() {
    		return blike;
    	}
    
    	public void setBlike(int blike) {
    		this.blike = blike;
    	}
    
    	public String getBtitle() {
    		return btitle;
    	}
    
    	public void setBtitle(String btitle) {
    		this.btitle = btitle;
    	}
    
    	public String getBwrite() {
    		return bwrite;
    	}
    
    	public void setBwrite(String bwrite) {
    		this.bwrite = bwrite;
    	}
    
    	public String getBdate() {
    		return bdate;
    	}
    
    	public void setBdate(String bdate) {
    		this.bdate = bdate;
    	}
    
    	public String getBcontent() {
    		return bcontent;
    	}
    
    	public void setBcontent(String bcontent) {
    		this.bcontent = bcontent;
    	}
    
    }

     

    05. 'BoardDAO.java' 생성하기

    • 게시판의 글 읽기, 쓰기, 지우기, 수정하기를 담당하는 DAO로 데이터 접속 객체
    • 나중에 Spring 할 때 MVC 패턴도 쓸 예정인데 지금 하는 것이 M 쪽 계열
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.poseidon.db.DBConnection;
    import com.poseidon.dto.BoardDTO;
    
    public class BoardDAO {
    	// 게시판 글 읽어오는 메서드
    
    	// 게시판 첫 화면 읽어온기
    	public List<BoardDTO> boardList() {
    		List<BoardDTO> list = new ArrayList<BoardDTO>();
    		String sql = "SELECT * FROM boardview";
    		// limit 순서가 제일 마지막에 와야 함
    		Connection conn = null;
    		Statement stmt = null;
    		ResultSet rs = null;
    
    		// DBConnection.getInstance() : 객체 뽑아오기
    		conn = DBConnection.getInstance().getConnection();
    		try {
    			stmt = conn.createStatement();
    			rs = stmt.executeQuery(sql);// 결과값 내보내줌
    			// execute : 실행만 해줌 ex.참/거짓으로 반환
    			// executeUpdate : 실행만 해줌 ex. 1, 2, 0 (영향 받은 행만 반환)
    			// executeQuery : select ex. 결과 반환
                
    			// 0 or 1개일 땐 if문 가능, 많을 땐 while문
    			// rs.next()에서 뽑아낼 결과가 있다면 참, 아니면 거짓
    			while (rs.next()) {
    				BoardDTO dto = new BoardDTO();
    				dto.setBno(rs.getInt("bno"));// rs에서 int타입의 bno가져온다는 뜻
    				dto.setBtitle(rs.getString("btitle"));
    				dto.setBwrite(rs.getString("bwrite"));
    				dto.setBdate(rs.getString("bdate"));
    				dto.setBlike(rs.getInt("blike"));
    				list.add(dto);
    			}
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				// rs가 있다면 닫아주기
    				if (rs != null) {
    					rs.close();
    				}
    				if (stmt != null) {
    					stmt.close();
    				}
    				if (conn != null) {
    					conn.close();
    				}
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    		return list;
    	}
    
    	public BoardDTO detail(int bno) {
    
    		BoardDTO dto = new BoardDTO();
    		Connection conn = null;
    		String sql = "SELECT * FROM board WHERE bno=" + bno;
    		Statement stmt = null;
    		ResultSet rs = null;
    
    		// DB연결
    		conn = DBConnection.getInstance().getConnection();
    		try {
    			stmt = conn.createStatement();
    			rs = stmt.executeQuery(sql);
    			if (rs.next()) {
    				dto.setBno(rs.getInt("bno"));
    				dto.setBtitle(rs.getString("btitle"));
    				dto.setBcontent(rs.getString("bcontent"));
    				dto.setBwrite(rs.getString("bwrite"));
    				dto.setBdate(rs.getString("bdate"));
    				dto.setBlike(rs.getInt("blike"));
    			}
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				if (rs != null) {
    					rs.close();
    				}
    				if (stmt != null) {
    					stmt.close();
    				}
    				if (conn != null) {
    					conn.close();
    				}
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    
    		return dto;
    	}
    
    }

     

    06. 'Detail.java' 수정하기

    import java.io.IOException;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.poseidon.dao.BoardDAO;
    import com.poseidon.dto.BoardDTO;
    
    @WebServlet("/detail")
    public class Detail extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    
    	public Detail() {
    		super();
    	}
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		System.out.println(request.getParameter("bno"));
    
    		// getParameter는 String 타입이라 캐스트 걸어줘야 함
    		int bno = Integer.parseInt(request.getParameter("bno"));
    
    		// DAO 만들기
    		BoardDAO dao = new BoardDAO();
    
    		// DAO 속 detail을 실행시켜서 DTO 받기
    		BoardDTO detail = dao.detail(bno);
    
    		// 디스패쳐로 보내기 (detail.jsp)
    		RequestDispatcher rd = request.getRequestDispatcher("detail.jsp");
    		request.setAttribute("detail", detail);
    		rd.forward(request, response);
    	}
    
    }

     

    07. 'detail.jsp' 생성하기

    • 톺아보기 = 상세히 보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>톺아보기</title>
    <link rel="stylesheet" type="text/css" href="./css/detail.css">
    </head>
    <body>
    	<jsp:include page="./menu.jsp" />
    	<h1>톺아보기</h1>
    	<div class="content">
    		<div class="title">${detail.btitle }</div>
    		<div class="write">
    			<div class="bwrite">작성자 : ${detail. bwrite }</div>
    			<div class="bdate">${detail. bdate }</div>
    			<div class="blike">
    				<img alt="좋아요" src="./like.png" style="width: 20px;">
    				${detail. blike }
    			</div>
    
    		</div>
    		<div class="bcontent">${detail. bcontent }
    			<img alt="좋아요" src="./KakaoTalk_20230628_115655614.png"
    				style="width: 400px;">
    
    		</div>
    	</div>
    
    </body>
    </html>

     

     

    08. 'Board.java' 생성하기

    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.poseidon.dao.BoardDAO;
    import com.poseidon.dto.BoardDTO;
    
    
    @WebServlet("/board")
    public class Board extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
       
        public Board() {
            super();
        }
    
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		
    		BoardDAO dao = new BoardDAO();
    		List<BoardDTO> list = dao.boardList();
    		
    		RequestDispatcher rd = request.getRequestDispatcher("board.jsp");
    		request.setAttribute("Sdata", "전달합니다.");// 값 지정하는 key, value
    		request.setAttribute("list", list);
    		rd.forward(request, response);
    		//rd한테 request와 response 그대로 전달
    	}
    
    }

     

     

    09. 'detail.css' 생성하기

    • min-height: 500px; 최저 높이를 500px로 설정 (500보다 크면 늘어나고 작으면 500으로 맞춰줌)
    • line-height: 30px; 높이가 30이면 써놓은 글자를 자동으로 중간 정렬하기
    @charset "UTF-8";
    
    @font-face {
    	font-family: 'SUITE-Regular';
    	src:
    		url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2304-2@1.0/SUITE-Regular.woff2')
    		format('woff2');
    	font-weight: 400;
    	font-style: normal;
    }
    
    @font-face {
    	font-family: 'TheJamsil5Bold';
    	src:
    		url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2302_01@1.0/TheJamsil5Bold.woff2')
    		format('woff2');
    	font-weight: 700;
    	font-style: normal;
    }
    
    /* 전체크기 설정 */
    .content {
    	margin: 0 auto;
    	width: 900px;
    	height: auto;
    	padding: 20px;
    }
    
    img{
    	width: 10px;
    }
    
    .title {
    	font-family: 'TheJamsil5Bold';
    	width: 100%;
    	height: 80px;
    	line-height: 80px;
    	font-size: x-large;
    	border-bottom: 2px solid #F44336;
    	background-color: white;
    	box-sizing: border-box;
    }
    
    .write {
    	font-family: 'SUITE-Regular';
    	width: 900px;
    	height: 40px;
    	border-bottom: double #F44336;	
    	font-size: medium;
    	font-weight: bold;
    	padding: 5px;
    	box-sizing: border-box;
    }
    
    .bwrite, .blike, .bdate {
    	float: left;
    	line-height: 30px;
    }
    
    .bwrite {
    	width: 80%;
    	
    }
    .bdate {
    	width: 15%;
    }
    
    .blike {
    	width: 5%;
    	text-align: left;
    }
    
    .bcontent {
    	font-family: 'SUITE-Regular';
    	width: 100%;
    	height: auto;
    	min-height: 300px;
    	padding: 10px 10px;
    	box-sizing: border-box;
    }

     

    10. 최종 화면

    게시판 화면
    작성글 화면

    반응형

    댓글