CSS
width : 100%
width : 50%
width : 25%
<link rel="stylesheet" href="css/responsive.css">
<style>
.box{
width : 100px;
height : 100px;
border : 1px solid red;
}
</style>
<div class="box color color-sm color-md"></div>
/* 화면의 폭과 상관없이 적용할 css */
.color{
background-color:yellow;
}
/* 화면의 폭이 최소 576px 이상일 때 적용할 css*/
@media(min-width:576px){
.color-sm{
background-color:yellowgreen;
}
}
@media(min-width:768px){
.color-md{
background-color:blue;
}
}
⭐ 선택자의 구체성이 동일한 경우 나중에 작성한 css가 적용
JSP & JAVA
SELECT *
FROM
(SELECT result1.*, ROWNUM AS num 2. 행번호 부여
FROM
(SELECT num, writer, title 1. 정렬
FROM board
ORDER BY num DESC) result1)
WHERE rnum BETWEEN 1 AND 5 3. 원하는 행만 SELECT
➜ startRowNum & endRowNum 을 구하는 일반식만 작성하면 해결
startRowNum : 공차수열 일반화
endRowNum : 등비수열 일반화
public class BoardDto {
private int num;
private String writer;
private String title;
private String content;
private int viewCount;
private String createdAt;
// 페이징 처리를 위한 필드
private int startRowNum;
private int endRowNum;
// setter, getter
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getViewCount() {
return viewCount;
}
public void setViewCount(int viewCount) {
this.viewCount = viewCount;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public int getStartRowNum() {
return startRowNum;
}
public void setStartRowNum(int startRowNum) {
this.startRowNum = startRowNum;
}
public int getEndRowNum() {
return endRowNum;
}
public void setEndRowNum(int endRowNum) {
this.endRowNum = endRowNum;
}
}
public List<BoardDto> selectPage(BoardDto dto){
List<BoardDto> list=new ArrayList<>();
//필요한 객체를 담을 지역변수를 미리 만든다
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = new DbcpBean().getConn();
String sql = """
SELECT *
FROM
(SELECT result1.*, ROWNUM AS rnum
FROM
(SELECT num, writer, title, viewCount, createdAt
FROM board
ORDER BY num DESC) result1)
WHERE rnum BETWEEN ? AND ?
""";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, dto.getStartRowNum());
pstmt.setInt(2, dto.getEndRowNum());
rs = pstmt.executeQuery();
while (rs.next()) {
BoardDto dto2=new BoardDto();
dto2.setNum(rs.getInt("num"));
dto2.setWriter(rs.getString("writer"));
dto2.setTitle(rs.getString("title"));
dto2.setViewCount(rs.getInt("viewCount"));
dto2.setCreatedAt(rs.getString("createdAt"));
list.add(dto2);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e) {
}
}
return list;
}
<%
// 기본 페이지 번호는 1 로 설정하고
int pageNum = 1;
// 페이지 번호를 읽어와서
String strPageNum = request.getParameter("pageNum");
// 전달되는 페이지 번호가 있다면
if(strPageNum != null){
// 해당 페이지 번호를 숫자로 변경해서 사용한다
pageNum = Integer.parseInt(strPageNum);
}
// 한 페이지에 몇개 씩 표시할 것인지
final int PAGE_ROW_COUNT = 5;
// 보여줄 페이지의 시작 ROWNUM
int startRowNum = 1+(pageNum-1)*PAGE_ROW_COUNT; // 공차 수열
// 보여줄 페이지의 끝 ROWNUM
int endRowNum= pageNum*PAGE_ROW_COUNT; // 등비 수열
// dto 에 select 할 row 의 정보를 담고
BoardDto dto = new BoardDto();
dto.setStartRowNum(startRowNum);
dto.setEndRowNum(endRowNum);
// 해당 row 만 select 한다
List<BoardDto> list = BoardDao.getInstance().selectPage(dto);
// 글 목록 얻어오기
// List<BoardDto> list = BoardDao.getInstance().selectAll();
%>
<style>
ul a {
text-decoration:none;
}
/* ul 요소이면서 클래스 속성의 값이 pagination 인 요소에 적용할 css */
ul.my-pagination{
list-style-type:none; /*ul 의 disc 없애기*/
padding-left:0; /*왼쪽 padding 제거*/
display:flex; /*자식 요소(li)를 flex 레이아웃으로 배치하기 위해 (가로배치)*/
gap:10px; /*자식 요소 끼리 공간 부여하기*/
justify-content:center; /*가로로 배치된 상태에서 가운데 정렬*/
}
.active{
font-weight:bold;
color:red;
text-decoration:underline;
}
</style>
<jsp:include page="/WEB-INF/include/navbar.jsp">
<jsp:param value="board" name="thisPage"/>
</jsp:include>
<div class="container pt-1">
<a class="btn btn-outline-primary btn-sm" href="new-form.jsp">
새 글 작성 <i class="bi bi-pencil-square"></i>
</a>
<h1>게시글 목록 입니다</h1>
<table class="table table-bordered">
<thead>
<tr>
<th>글번호</th>
<th>작성자</th>
<th>제목</th>
<th>조회수</th>
<th>작성일</th>
</tr>
</thead>
<tbody>
<%for(BoardDto tmp : list) {%>
<tr>
<td><%=tmp.getNum()%></td>
<td><%=tmp.getWriter()%></td>
<td>
<a href="view.jsp?num=<%=tmp.getNum()%>"><%=tmp.getTitle()%></a>
</td>
<td><%=tmp.getViewCount()%></td>
<td><%=tmp.getCreatedAt()%></td>
</tr>
<%} %>
</tbody>
</table>
<ul class="my-pagination">
<%for(int i=1; i<=5; i++){%>
<li>
<a class="<%=i==pageNum ? "active":"" %>" href="list.jsp?pageNum=<%=i%>"><%=i %></a>
</li>
<%} %>
</ul>
</div>
public int getCount() {
int count = 0;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = new DbcpBean().getConn();
// 글의 전체 갯수를 ROWNUM 중에서 가장 큰 값
String sql = """
SELECT MAX(ROWNUM) AS count
FROM board
""";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
if (rs.next()) {
count = rs.getInt("count");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e) {
}
}
return count;
}
⚠️ 정수를 정수로 나누면 소수점이 버려진 정수가 나온다
// 하단 페이지에를 몇개 씩 표시할 것인지
final int PAGE_DISPLAY_COUNT = 5;
//하단 시작 페이지 번호
int startPageNum = 1 + ((pageNum-1)/PAGE_DISPLAY_COUNT)*PAGE_DISPLAY_COUNT;
//하단 끝 페이지 번호
int endPageNum = startPageNum+PAGE_DISPLAY_COUNT-1;
//전체 글의 갯수
int totalRow = BoardDao.getInstance().getCount();
//전체 페이지의 갯수 구하기
int totalPageCount = (int)Math.ceil(totalRow/(double)PAGE_ROW_COUNT);
//끝 페이지 번호가 이미 전체 페이지 갯수보다 크게 계산되었다면 잘못된 값이다.
if(endPageNum > totalPageCount){
endPageNum=totalPageCount; //보정해 준다.
}
<ul class="pagination">
<%for(int i=startPageNum; i<=endPageNum; i++){%>
<li>
<a class="<%=i==pageNum ? "active":"" %>" href="list.jsp?pageNum=<%=i%>"><%=i %></a>
</li>
<%} %>
</ul>

화살표 표시
> : ›
< : ‹
>> : »
<< : «
> & < 로 페이지 이동<ul class="pagination">
<!-- startPagNum 이 1이 아닐 때 이전 page 가 존재하기 때문에 -->
<%if(startPageNum != 1) {%>
<li>
<a href="list.jsp?pageNum=<%=startPageNum-1%>">‹</a>
</li>
<%} %>
<%for(int i=startPageNum; i<=endPageNum; i++){%>
<li>
<a class="<%=i==pageNum ? "active":"" %>" href="list.jsp?pageNum=<%=i%>"><%=i %></a>
</li>
<%} %>
<!-- endPageNum 이 totalPageNum 보다 작을 때 다음 page 가 있다 -->
<%if(endPageNum < totalPageCount) {%>
<li>
<a href="list.jsp?pageNum=<%=endPageNum+1%>">›</a>
</li>
<%} %>
</ul>
<%if(startPageNum != 1) {%>
- prev 링크를 조건부로 출력
<%for(int i=startPageNum; i<=endPageNum; i++){%>
- page 번호를 반복문 돌면서 출력
<%if(endPageNum < totalPageCount) {%>
- next 링크를 조건부로 출력
<ul class="pagination">
<!-- startPagNum 이 1이 아닐 때 이전 page 가 존재하기 때문에 -->
<%if(startPageNum != 1) {%>
<li class="page-item">
<a class="page-link" href="list.jsp?pageNum=<%=startPageNum-1%>">‹</a>
</li>
<%} %>
<%for(int i=startPageNum; i<=endPageNum; i++){%>
<li class="page-item">
<a class="page-link <%=i==pageNum ? "active":"" %>" href="list.jsp?pageNum=<%=i%>"><%=i %></a>
</li>
<%} %>
<-- endPageNum 이 totalPageNum 보다 작을 때 다음 page 가 있다 -->
<%if(endPageNum < totalPageCount) {%>
<li class="page-item">
<a class="page-link" href="list.jsp?pageNum=<%=endPageNum+1%>">›</a>
</li>
<%} %>
</ul>
public boolean addViewCount(int num) {
Connection conn = null;
PreparedStatement pstmt = null;
int rowCount = 0;
try {
conn = new DbcpBean().getConn();
String sql = """
UPDATE board
SET viewCount = viewCount+1
WHERE num = ?
""";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, num);
rowCount = pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e) {
}
}
if (rowCount > 0) {
return true;
} else {
return false;
}
}
<%
// 만일 본인 글 자세히 보기가 아니면 조회수를 1 증가 시킨다
if(!dto.getWriter().equals(userName)){
BoardDao.getInstance().addViewCount(num);
}
%>
// 프로필 이미지 출력을 위한 필드
private String profileImage;
public String getProfileImage() {
return profileImage;
}
public void setProfileImage(String profileImage) {
this.profileImage = profileImage;
}
getByNum 메소드 수정public BoardDto getByNum(int num) {
BoardDto dto = null;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = new DbcpBean().getConn();
String sql = """
SELECT writer, title, content, viewCount,
TO_CHAR(b.createdAt, 'YY"년" MM"월" DD"일" HH24:MI') AS createdAt,
profileImage
FROM board b
INNER JOIN users u ON b.writer = u.userName
WHERE b.num = ?
""";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, num);
rs = pstmt.executeQuery();
if (rs.next()) {
dto = new BoardDto();
dto.setNum(num);
dto.setWriter(rs.getString("writer"));
dto.setTitle(rs.getString("title"));
dto.setContent(rs.getString("content"));
dto.setViewCount(rs.getInt("viewcount"));
dto.setCreatedAt(rs.getString("createdAt"));
dto.setProfileImage(rs.getString("profileImage"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (Exception e) {
}
}
return dto;
}
<tr>
<th>작성자</th>
<td>
<%if(dto.getProfileImage() == null) {%>
<i style="font-size:100px;" class="bi bi-person-circle"></i>
<%} else{%>
<img src="${pageContext.request.contextPath }/upload/<%=dto.getProfileImage() %>"
style="width:100px;height:100px;border-radius:50%;"/>
<%} %>
<%=dto.getWriter()%>
</td>
</tr>
새로운 폴더에 GitHub 저장소 clone하기
<기본 설정>
1. 다운 받은 apache 폴더를 다른COM 폴더에 복사하기
2. 다른COM > other_webwork 로 workspace
3. Servers 탭을 선택 후 빈 공간에 NEW > Server 선택
4. Apache > Tomcat 10.1 > Next 선택
5. Broswe 버튼을 눌러 압축 해제한 apache tomcat 폴더를 찾아 선택 후 finish
6. server.xml 파일에서 source 탭을 선택 후 64라인에 port 번호를 8888 로 설정한 후 저장
7. content.xml 에 </Context> 안에 해당 코드 넣기
<Resource name="jdbc/myoracle" auth="Container"
type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@127.0.0.1:1521:xe"
username="scott" password="TIGER" maxTotal="20" maxIdle="10"
maxWaitMillis="-1"/>
8. Servers 탭에서 run 을 클릭해 server 실행
<저장소 clone>
1. clone할 저장소 위치 복사
2. clone할 폴더 위치에 Git Bash 실행
3. git clone 저장소_위치
4. 해당 폴더에서 clone 결과 확인
5. eclipes git mode 에서 add
6. Add an existing local Git repository 을 선택해 clone 된 Local 저장소를 찾아 등록
7. 찾은 저장소를 check 후에 add click
8. git mode 에서 Working Tree 에서 import할 프로젝트를 선택해서 import Projects 클릭
9. import 할 프로젝트 확인 후 finish
10. Java EE mode 로 전향 후 import 된 프로젝트를 확인
11. 해당 Project 에서 Properties 를 click
12. Project Facets > Convert to faceted form 에서
Dynamic Web Module 을 선택해 Runtime 에 Tomcat을 check 하고 Apply and Close
(JAVA 가 21 version인지 확인 필수)