Error(에러)와 Exception(예외의 차이) 

에러(Error)란 컴퓨터 하드웨어의 오동작 또는 고장으로 인해 응용프로그램에 이상이 생겼거나 JVM 실행에 문제가 생겼을 경우 발생하는것을 말합니다. 이 경우 개발자는 대처할 방법이 극히 제한적입니다. 하지만 예외(Exception)은 다릅니다. 예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말합니다. 예외가 발생하면 프로그램이 종료가 된다는것은 에러와 동일하지만 예외는 예외처리(Exception Handling)을 통해 프로그램을 종료 되지 않고 정상적으로 작동되게 만들어줄 수 있습니다. 자바에서 예외처리는 Try Catch문을 통해 해줄 수 있습니다.

 

 여러가지 예외들 

 예외 구문 이유 
ArithmeticException 정수를 0으로 나눌경우 발생 
ArrayIndexOutOfBoundsExcetion 배열의 범위를 벗어난 index를 접근할 시 발생
ClassCastExcetion 변환할 수 없는 타입으로 객체를 반환 시 발생 
NullPointException   존재하지 않는 레퍼런스를 참조할때 발생 
IllegalArgumentException 잘못된 인자를 전달 할 때 발생 
IOException 입출력 동작 실패 또는 인터럽트 시 발생 
OutOfMemoryException  메모리가 부족한 경우 발생  
NumberFormatException  문자열이 나타내는 숫자와 일치하지 않는 타입의 숫자로 변환시 발생 

 

 빈도수가 높은 예외 

NullPointException

자바 프로그램에서 가장 빈번하게 발생하는 에러입니다. 이 에러는 객체 참조가 없는 상태, 즉 null 값을 갖는 참조변수로 객체 접근 연사자인 토드(.)를 사용했을 때 발생합니다. 객체가 없는 상태에서 객체를 사용하려 했으니 예외가 발생하는 것입니다.

 

ArrayIndexOutOfBoundsExcetion

배열에서 인덱스 범위를 초과하여 사용할 경우 발생합니다. 예를 들어 길이가 3인 int[]arr = new int[3] 배열을 선언했다면 0 ~ 2까지의 index만 사용할 수 있습니다. 하지만 이 배열의 index가 -1 이나 3을 참조하는 순간 예외가 발생합니다.

 

NumberFormatException 

개발을 하다보면 문자열로 되어있는 데이터를 숫자타입으로 변경하는 경우가 자주발생하는데 숫자타입으로 변경할 수 없는 문자를 치환시키려고 하면 발생하는 에러입니다.

 

ClassCastExcetion

타입 변환은 상위 클래스와 하위클래스간에 발생하고 구현 클래스와 인터페이스간에도 발생합니다. 이런 관계가 아니면 클래스는 다른 클래스로 타입을 변환할 수 없습니다. 하지만 이 규칙을 무시하고 억지로 타입을 변환시킬경우 발생하는 에러입니다.

 

 예외 처리코드 (Try Catch) 

try{
    //에러가 발생할 수 있는 코드
    throw new Exception(); //강제 에러 출력 
}catch (Exception e){
    //에러시 수행
     e.printStackTrace(); //오류 출력(방법은 여러가지)
     throw e; //최상위 클래스가 아니라면 무조건 던져주자
}finally{
    //무조건 수행
} 

 

try블록에는 예외가 발생할 수 있는 코드가 위치합니다. try 블록의 코드가 예외없이 정상 실행되면 catch블록의 코드는 실행되지 않고 finally 블록의 코드를 실행합니다. 하지만 try 블록의 코드에서 예외가 발생하면 즉시 실행을 멈추고 catch 블록으로 이동하여 예외처리 코드를 실행합니다. 그리고 finally 블록의 코드를 실행합니다. (finally 블록은 생략 가능합니다.) 

try catch 문을 주로 쓰는 구간은 주로 데이터베이스에 데이터를 주고받을 경우 많이사용합니다. 데이터베이스를 거쳐올때는 변수가 많이 생기기 때문에 try catch문은 필수입니다. 그리고 finally에는 데이터베이스와의 연결을 끊어주는 코드를 주로 삽입하죠. 특정 예외가 발생하여 데이터베이스와의 연결이 끊어지지 않으면 여러가지 문제를 야기할수 있기 때문입니다.

 

예외는 반드시 Throw해주자.

최상단 클래스를 제외한 나머지 클래스에서의 예외처리는 반드시 Throw를 해주어야 합니다. 그렇지 않으면 예외처리를 해주었음에도 불구하고 Main에서는 Exception을 전달받지 못하여 개발자가 예외를 인지못하는 경우가 생깁니다.

 

 

출처:https://coding-factory.tistory.com/280

# a5 데이터베이스 삭제/생성/선택
 DROP DATABASE IF EXIT `a5`;
 
 CREATE DATABASE `a5`;
 
 USE `a5`;

# 부서(dept) 테이블 생성 및 홍보부서 기획부서 추가
DROP TABLE dept;

CREATE TABLE dept(
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,PRIMARY KEY(id),
  regDate DATETIME NOT NULL,
  `name` CHAR(100) NOT NULL
);


INSERT INTO dept
SET regDate = NOW(),
`name` = '홍보';

INSERT INTO dept
SET regDate = NOW(),
`name` = '기획';
# 사원(emp) 테이블 생성 및 홍길동사원(홍보부서), 홍길순사원(홍보부서), 임꺽정사원(기획부서) 추가

CREATE TABLE emp(
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,PRIMARY KEY(id),
  regDate DATETIME NOT NULL,
  `name` CHAR(100) NOT NULL,
  deptName CHAR(100) NOT NULL
);

INSERT INTO emp
SET regDate = NOW(),
`name` = '홍길동',
deptName = '홍보';

INSERT INTO emp
SET regDate = NOW(),
`name` = '홍길순',
deptName = '홍보';


INSERT INTO emp
SET regDate = NOW(),
`name` = '임꺽정',
deptName = '기획';

DELETE
FROM emp
WHERE id = 5;

SELECT *
FROM emp;
# 홍보를 마케팅으로 변경

UPDATE dept
SET `name` = '마케팅'
WHERE `name` = '홍보';



# 마케팅을 홍보로 변경
UPDATE dept
SET `name` = '홍보'
WHERE `name` = '마케팅';


# 홍보를 마케팅으로 변경

UPDATE dept
SET `name` = '마케팅'
WHERE `name` = '홍보';
# 구조를 변경하기로 결정(사원 테이블에서, 이제는 부서를 이름이 아닌 번호로 기억)

ALTER TABLE emp ADD COLUMN deptId INT(10) UNSIGNED NOT NULL;

UPDATE emp
SET deptId = 1
WHERE deptName = '홍보';

UPDATE emp
SET deptId = 2
WHERE deptName = '기획';

# 사장님께 드릴 인명록을 생성

SELECT *
FROM emp;

# 사장님께서 부서번호가 아니라 부서명을 알고 싶어하신다.
# 그래서 dept 테이블 조회법을 알려드리고 혼이 났다.

# 사장님께 드릴 인명록을 생성(v2, 부서명 포함, ON 없이)
# 이상한 데이터가 생성되어서 혼남

# 사장님께 드릴 인명록을 생성(v3, 부서명 포함, 올바른 조인 룰(ON) 적용)
# 보고용으로 좀 더 편하게 보여지도록 고쳐야 한다고 지적받음

# 사장님께 드릴 인명록을 생성(v4, 사장님께서 보시기에 편한 칼럼명(AS))
SELECT emp.id AS `사원번호`,
emp.name AS `사원명`,
DATE(emp.regDate) AS `입사일`,
dept.name AS `부서명`
FROM emp
INNER JOIN dept
ON emp.deptId = dept.id
ORDER BY `부서명`, `사원번호`;



SHOW TABLES;

DROP TABLE dept;
DROP TABLE emp;

# 부서(홍보, 기획)
CREATE TABLE dept(
id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
regDate DATETIME NOT NULL,
`name` CHAR(100) NOT NULL UNIQUE

);


INSERT INTO dept
SET regDate = NOW(),
`name` = '홍보';



INSERT INTO dept
SET regDate = NOW(),
`name` = '기획';


# 사원(홍길동/홍보/5000만원, 홍길순/홍보/6000만원, 임꺽정/기획/4000만원)

CREATE TABLE emp (
    id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    regDate DATETIME NOT NULL,
    `name` CHAR(100) NOT NULL,
    deptId INT UNSIGNED NOT NULL,
    salary INT UNSIGNED NOT NULL
);

INSERT INTO emp
SET regDate = NOW(),
`name` = '홍길동',
deptId = 1,
salary = 5000;

INSERT INTO emp
SET regDate = NOW(),
`name` = '홍길순',
deptId = 1,
salary = 6000;

INSERT INTO emp
SET regDate = NOW(),
`name` = '임꺽정',
deptId = 2,
salary = 4000;

SELECT *
FROM emp;

DELETE 
FROM emp
WHERE id = 4;

# 사원 수 출력
SELECT COUNT(*)
FROM emp;

# 가장 큰 사원 번호 출력

SELECT MAX(id)
FROM emp;
# 가장 고액 연봉

SELECT MAX(salary)
FROM emp;

# 가장 저액 연봉

SELECT MIN(salary)
FROM emp;

# 회사에서 1년 고정 지출(인건비)

SELECT SUM(salary)
FROM emp;

# 부서별, 1년 고정 지출(인건비)

SELECT deptId, SUM(salary)
FROM emp
GROUP BY deptId;


# 부서별, 최고연봉

SELECT deptId, MAX(salary)
FROM emp
GROUP BY deptId
LIMIT 1;


# 부서별, 최저연봉
SELECT deptId, MIN(salary)
FROM emp
GROUP BY deptId;



# 부서별, 평균연봉

SELECT deptId, AVG(salary)
FROM emp
GROUP BY deptId;
# 부서별, 부서명, 사원리스트, 평균연봉, 최고연봉, 최소연봉, 사원수 
## V1(조인 안한 버전)
SELECT E.deptId AS 부서번호,
GROUP_CONCAT(E.name) AS 사원리스트,
TRUNCATE(AVG(E.salary), 0) AS 평균연봉,
MAX(E.salary) AS 최고연봉,
MIN(E.salary) AS 최소연봉,
COUNT(*) A`jam``jam``jam`S 사원수
FROM emp AS E
GROUP BY E.deptId;

## V2(조인해서 부서명까지 나오는 버전)
SELECT D.name AS 부서,
GROUP_CONCAT(E.name) AS 사원리스트,
TRUNCATE(AVG(E.salary), 0) AS 평균연봉,
MAX(E.salary) AS 최고연봉,
MIN(E.salary) AS 최소연봉,
COUNT(*) AS 사원수
FROM emp AS E
INNER JOIN dept AS D
ON E.deptId = D.id
GROUP BY E.deptId;

## V3(V2에서 평균연봉이 5000이상인 부서로 추리기)

SELECT D.name AS 부서,
GROUP_CONCAT(E.name) AS 사원리스트,
TRUNCATE(AVG(E.salary), 0) AS 평균연봉,
MAX(E.salary) AS 최고연봉,
MIN(E.salary) AS 최소연봉,
COUNT(*) AS 사원수
FROM emp AS E
INNER JOIN dept AS D
ON E.deptId = D.id
GROUP BY E.deptId
HAVING `평균연봉` >= 5000;
## V4(V3에서 HAVING 없이 서브쿼리로 수행)
### HINT, UNION을 이용한 서브쿼리
# SELECT *
# FROM (
#     select 1 AS id
#     union
#     select 2
#     UNION
#     select 3
# ) AS A
SELECT *
FROM (
    SELECT D.name AS `부서명`,
    GROUP_CONCAT(E.`name`) AS `사원리스트`,
    TRUNCATE(AVG(E.salary), 0) AS `평균연봉`,
    MAX(E.salary) AS `최고연봉`,
    MIN(E.salary) AS `최소연봉`,
    COUNT(*) AS `사원수`
    FROM emp AS E
    INNER JOIN dept AS D
    ON E.deptId = D.id
    WHERE 1
    GROUP BY E.deptId
) AS D
WHERE D.`평균연봉` >= 5000;

#################

#상황 : 커뮤니티 사이트 DB를 구축해야 합니다.
#조건 : member(회원), article(게시물) 테이블을 구현해주세요.
#조건 : 비회원은 글을 쓸 수 없습니다.
#조건 : 게시물 상세페이지에서는 제목, 내용, 작성날짜, 작성자가 보여야 합니다.
#조건 : 특정 게시물을 어떤 회원이 작성했는지 알 수 있어야 합니다.
#조건 : 회원이 자신의 이름을 바꾸면, 그 회원이 예전에 쓴 글에서도 작성자가 자동으로 변경되어야 합니다.
#조건 : 회원 아이디와 비번의 칼럼명은, loginId 와 loginPw 로 해주세요.
#조건 : loginId에는 unique 인덱스를 걸어주세요.
#조건 : 회원 2명이 가입을 햇습니다.
#조건 : 1번 회원은 글을 2개(글 1번, 3번), 2번 회원은 글을 1개(2번) 썻습니다.


# 회원 테이블 생성, loginId, loginPw, `name`
## 조건 : loginId 칼럼에 UNIQUE INDEX 없이
CREATE TABLE `member` (
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(id),
    regDate DATETIME NOT NULL,
    loginId CHAR(50) NOT NULL,
    loginPw VARCHAR(100) NOT NULL,
    `name` CHAR(100) NOT NULL
);

# 회원 2명 생성
## 조건 : (loginId = 'user1', loginPw = 'user1', `name` = '홍길동')
## 조건 : (loginId = 'user2', loginPw = 'user2', `name` = '홍길순')
INSERT INTO `member`
SET regDate = NOW(),
loginId = 'user1',
loginPw = 'user1',
`name` = '홍길동';

INSERT INTO `member`
SET regDate = NOW(),
loginId = 'user2',
loginPw = 'user2',
`name` = '홍길순';

# 회원 2배 증가 쿼리만들고 회원이 백만명 넘을 때 까지 반복 실행
## 힌트1 : INSERT INTO `tableName` (col1, col2, col3, col4)
## 힌트2 : SELECT NOW(), UUID(), 'pw', '아무개'

INSERT INTO `member` (regDate, loginId, loginPw, `name`)
SELECT NOW(), UUID(), 'pw', '아무개'
FROM `member`;

# 회원수 확인
SELECT COUNT(*)
FROM `member`;

# 검색속도 확인
## 힌트 : SQL_NO_CACHE
SELECT SQL_NO_CACHE *
FROM `member`
WHERE loginId = 'user1';

# 유니크 인덱스를 loginID 칼럼에 걸기
## 설명 : mysql이 loginId의 고속검색을 위한 부가데이터를 자동으로 관리(생성/수정/삭제) 한다.
## 설명 : 이게 있고 없고가, 특정 상황에서 어마어마한 성능차이를 가져온다.
## 설명 : 생성된 인덱스의 이름은 기본적으로 칼럼명과 같다.
ALTER TABLE `member` ADD UNIQUE INDEX (`loginId`); 

# 검색속도 확인, loginId 가 'user1' 인 회원 검색
SELECT SQL_NO_CACHE *
FROM `member`
WHERE loginId = 'user1';

# 인덱스 삭제, `loginId` 이라는 이름의 인덱스 삭제
ALTER TABLE `member` DROP INDEX `loginId`;

# 회원 테이블 삭제
DROP TABLE `member`;

# 회원 테이블을 생성하는데, loginId에 uniqueIndex 까지 걸어주세요.
CREATE TABLE `member` (
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(id),
    regDate DATETIME NOT NULL,
    loginId CHAR(50) UNIQUE NOT NULL,
    loginPw VARCHAR(100) NOT NULL,
    `name` CHAR(100) NOT NULL
);

# 회원 2명 생성
## 조건 : (loginId = 'user1', loginPw = 'user1', `name` = '홍길동')
## 조건 : (loginId = 'user2', loginPw = 'user2', `name` = '홍길순')
INSERT INTO `member`
SET regDate = NOW(),
loginId = 'user1',
loginPw = 'user1',
`name` = '홍길동';

INSERT INTO `member`
SET regDate = NOW(),
loginId = 'user2',
loginPw = 'user2',
`name` = '홍길순';

# 회원수 확인
SELECT COUNT(*) FROM `member`;

# 인덱스 쓰는지 확인
## 힌트 : EXPLAIN SELECT SQL_NO_CACHE * ~
EXPLAIN SELECT SQL_NO_CACHE *
FROM `member`
WHERE loginId = 'user1';

# 게시물 테이블 생성(title, body, writerName, memberId)
DROP TABLE `article`;

CREATE TABLE `article` (
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(id),
    regDate DATETIME NOT NULL,
    title CHAR(200) NOT NULL,
    `body` TEXT NOT NULL,
    `writerName` CHAR(100) NOT NULL,
    memberId INT(10) UNSIGNED NOT NULL
);

# 1번 회원이 글 1 작성(title = '글 1 제목', `body` = '글 1 내용')
INSERT INTO article
SET regDate = NOW(),
title = '글 1 제목',
`body` = '글 1 내용',
writerName = '홍길동',
memberId = 1;

# 2번 회원이 글 2 작성(title = '글 2 제목', `body` = '글 2 내용')
INSERT INTO article
SET regDate = NOW(),
title = '글 2 제목',
`body` = '글 2 내용',
writerName = '홍길순',
memberId = 2;

# 1번 회원이 글 3 작성(title = '글 3 제목', `body` = '글 3 내용')
INSERT INTO article
SET regDate = NOW(),
title = '글 3 제목',
`body` = '글 3 내용',
writerName = '홍길동',
memberId = 1;

# 전체글 조회
SELECT *
FROM article;

# 1번회원의 이름변경 홍길동 => 홍길동2
UPDATE `member`
SET `name` = '홍길동2'
WHERE id = 1;

# 전체글 조회, 여전히 게시물 테이블에는 이전 이름이 남아 있음
SELECT *
FROM article;

# 게시물 테이블에서 writerName 삭제
ALTER TABLE article DROP COLUMN writerName;

# INNER JOIN 을 통해서 두 테이블을 조회한 결과를 합침, ON 없이
SELECT * FROM article
INNER JOIN `member`;

# INNER JOIN 을 통해서 두 테이블을 조회한 결과를 합침, 올바른 조인 조건

## 힌트 : 이걸로 조인조건을 걸 칼럼 조사
## SELECT article.id, article.memberId, member.id AS "회원테이블_번호"
## FROM article
## INNER JOIN `member`;

# 조인 완성, ON 까지 추가
SELECT A.*, M.name AS writerName
FROM article AS A
INNER JOIN `member` AS M
ON A.memberId = M.id;

 

<h1>요구 : CSS 선택자로 검색되는 엘리먼트 개수를 주석에 적어주세요.</h1>

<!--
.menu-1>ul>li*2>a[href=#]{1차 메뉴 아이템 $}+ul>li*2>a[href=#]{2차 메뉴 아이템 $}
-->
<nav class="menu-1">
  <ul>
    <li>
      <a href="#">1차 메뉴 아이템 1</a>
      <ul>
        <li><a href="#">2차 메뉴 아이템 1</a></li>
        <li><a href="#">2차 메뉴 아이템 2</a></li>
      </ul>
    </li>
    <li>
      <a href="#">1차 메뉴 아이템 2</a>
      <ul>
        <li><a href="#">2차 메뉴 아이템 1</a></li>
        <li><a href="#">2차 메뉴 아이템 2</a></li>
      </ul>
    </li>
  </ul>
</nav>

 

 

 

 

 

문제 선택자를 찾아 갯수를 써주세요

html { /* 개 */ }
body { /* 개 */ }
html body { /* 개 */ }
html > body { /* 개 */ }
html, body { /* 개 */ }
ul { /* 개 */ }
body > ul { /* 개 */ }
body ul { /* 개 */ }
body > nav > ul { /* 개 */ }
body > nav ul { /* 개 */ }
body > nav.menu-1 ul { /* 개 */ }
body > nav.menu-1 ul ul { /* 개 */ }
body > nav.menu-1 ul ul ul { /* 개 */ }
body > nav.menu-1 li { /* 개 */ }
body > nav.menu-1 li li { /* 개 */ }
body > nav.menu-1 > ul { /* 개 */ }
body > nav.menu-1 > ul li { /* 개 */ }
body > nav.menu-1 > ul > li { /* 개 */ }
body > nav.menu-1 > ul > li a { /* 개 */ }
body > nav.menu-1 > ul > li > a { /* 개 */ }
body > nav.menu-1 li > a { /* 개 */ }
body > nav.menu-1 li:hover > a { /* 개 */ }
body > nav.menu-1 li > ul { /* 개 */ }
body > nav.menu-1 li:hover > ul { /* 개 */ }

 

 

 

 

정답

 

html { /* 1개 */ }
body { /* 1개 */ }
html body { /* 1개 */ }
html > body { /* 1개 */ }
html, body { /* 2개 */ }
ul { /* 3개 */ }
body > ul { /* 0개 */ }
body ul { /* 3개 */ }
body > nav > ul { /* 1개 */ }
body > nav ul { /* 3개 */ }
body > nav.menu-1 ul { /* 3개 */ }
body > nav.menu-1 ul ul { /* 2개 */ }
body > nav.menu-1 ul ul ul { /* 0개 */ }
body > nav.menu-1 li { /* 6개 */ }
body > nav.menu-1 li li { /* 4개 */ }
body > nav.menu-1 > ul { /* 1개 */ }
body > nav.menu-1 > ul li { /* 6개 */ }
body > nav.menu-1 > ul > li { /* 2개 */ }
body > nav.menu-1 > ul > li a { /* 6개 */ }
body > nav.menu-1 > ul > li > a { /* 2개 */ }
body > nav.menu-1 li > a { /* 6개 */ }
body > nav.menu-1 li:hover > a { /* 0개 */ }
body > nav.menu-1 li > ul { /* 2개 */ }
body > nav.menu-1 li:hover > ul { /* 0개 */ }


<nav class="menu-1">
  <ul>
    <li>
      <a href="#">동물</a>

      <ul>
        <li><a href="#">포유류</a></li>
        <li><a href="#">조류</a></li>
      </ul>
    </li>

    <li>
      <a href="#">식물</a>

      <ul>
        <li><a href="#">과일</a></li>
        <li><a href="#">야채</a></li>
      </ul>
    </li>

    <li>
      <a href="#">광물</a>

      <ul>
        <li><a href="#">금속</a></li>
        <li><a href="#">비금속</a></li>
      </ul>
    </li>
  </ul>
</nav>




/css



.menu-1 > ul ul {
  display:none;
}

.menu-1 ul > li:hover > ul {
  display:block;
}

<!-- nav>section>div*4>a[href=#]{메뉴 아이템 $} -->

<!-- 메뉴 박스(메뉴를 감싸는 부모) -->
<div class="menu-box">
  <!-- 메뉴 -->
  <div>
    <!-- 메뉴 아이템 -->
    <div>
      <!-- 메뉴 아이템 텍스트 -->
      <div>메뉴 아이템 1</div>
    </div>
    <div>
      <!-- 메뉴 아이템 텍스트 -->
      <div>메뉴 아이템 2</div>
    </div>
    <div>
      <!-- 메뉴 아이템 텍스트 -->
      <div>메뉴 아이템 3</div>
    </div>
    <div>
      <!-- 메뉴 아이템 텍스트 -->
      <div>메뉴 아이템 4</div>
    </div>
  </div>
</div>





/css/

/* 노말라이즈 */
a {
  color:inherit;
  text-decoration:none;
}

/* 커스텀 */

/* 메뉴박스 */
.menu-box {
  text-align:center;
}

/* 메뉴 */
.menu-box > div {
  /* 메뉴에는 배경색이 있다. */
  background-color:#dfdfdf;
  /* 메뉴는 너비가 최대한 줄어든다. */
  display:inline-block;
  border-radius:5px;
  padding:0 10px;
}

/* 메뉴 아이템 */
.menu-box > div > div {
  /* 메뉴 아이템은 너비가 최대한 줄어들고 한줄에 여러개 나온다. */
  display:inline-block;
}

/* 메뉴 아이템 텍스트 */
.menu-box > div > div > div {
  padding:10px;
  /* 커서를 포인터로 바꿈 */
  cursor:pointer;
}

/* 마우스가 올려진 메뉴 아이템의 자식인 텍스트 */
.menu-box > div > div:hover > div {
  background-color:black;
  color:white;
}

 

/html/

<nav>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</nav>





/css/



body {
  background-color:black;
}

nav {
  text-align:center;
}

nav > div {
  width:20px;
  height:20px;
  /* rgba(255,255,255,0.5) 반투명한 하얀색 */
  background-color:rgba(255,255,255,0.5);
  display:inline-block;
  border-radius:50%;
  /* 마우스를 올렸을 때 커서를 포인터로 바꾼다. */
  cursor:pointer;
}

nav > div:first-child, nav > div:hover {
  background-color:rgba(255,255,255,1);
}

 

/html/ /css/ img:first-child { display:block; margin:0 auto; /* margin-left:auto; margin-right:auto; */ } body { text-align:center; } body > img:nth-child(1) { margin-bottom:14px; } body > img:nth-child(3) { margin:0 14px; }

/html/

<div>
    <section><img src="http://bnx.oa.gg/img/20160921PM33800_8489.jpg" alt=""></section>
    <section><img src="http://bnx.oa.gg/img/20160913PM122312_9304.jpg" alt=""></section>
    <section><img src="http://bnx.oa.gg/img/20160913PM122323_2917.jpg" alt=""></section>
</div>
<div>
    <section><img src="http://bnx.oa.gg/img/20160913PM122333_5909.jpg" alt=""></section>
    <section><img src="http://bnx.oa.gg/img/20160913PM122345_286.jpg" alt=""></section>
    <section><img src="http://bnx.oa.gg/img/20160913PM122357_7873.jpg" alt=""></section>
</div>



/css/

div {
    text-align:center;
}
div > section {
    display:inline-block;
    padding:30px;
}
div > section > img {
    width:200px;
}

연습용 데이터 베이스 생성

####데이터 초기화
DROP DATABASE employees;


USE `cgh`;

SHOW TABLES;



###############################
#TABLE 생성

CREATE TABLE DEPT (
    DEPTNO DECIMAL(2),
    DNAME VARCHAR(14),
    LOC VARCHAR(13),
    CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO) 
);
CREATE TABLE EMP (
    EMPNO DECIMAL(4),
    ENAME VARCHAR(10),
    JOB VARCHAR(9),
    MGR DECIMAL(4),
    HIREDATE DATE,
    SAL DECIMAL(7,2),
    COMM DECIMAL(7,2),
    DEPTNO DECIMAL(2),
    CONSTRAINT PK_EMP PRIMARY KEY (EMPNO),
    CONSTRAINT FK_DEPTNO FOREIGN KEY (DEPTNO) REFERENCES DEPT(DEPTNO)
);
CREATE TABLE SALGRADE ( 
    GRADE TINYINT,
    LOSAL SMALLINT,
    HISAL SMALLINT 
);
INSERT INTO DEPT VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS');
INSERT INTO DEPT VALUES (30,'SALES','CHICAGO');
INSERT INTO DEPT VALUES (40,'OPERATIONS','BOSTON');
INSERT INTO EMP VALUES (7369,'SMITH','CLERK',7902,STR_TO_DATE('17-12-1980','%d-%m-%Y'),800,NULL,20);
INSERT INTO EMP VALUES (7499,'ALLEN','SALESMAN',7698,STR_TO_DATE('20-2-1981','%d-%m-%Y'),1600,300,30);
INSERT INTO EMP VALUES (7521,'WARD','SALESMAN',7698,STR_TO_DATE('22-2-1981','%d-%m-%Y'),1250,500,30);
INSERT INTO EMP VALUES (7566,'JONES','MANAGER',7839,STR_TO_DATE('2-4-1981','%d-%m-%Y'),2975,NULL,20);
INSERT INTO EMP VALUES (7654,'MARTIN','SALESMAN',7698,STR_TO_DATE('28-9-1981','%d-%m-%Y'),1250,1400,30);
INSERT INTO EMP VALUES (7698,'BLAKE','MANAGER',7839,STR_TO_DATE('1-5-1981','%d-%m-%Y'),2850,NULL,30);
INSERT INTO EMP VALUES (7782,'CLARK','MANAGER',7839,STR_TO_DATE('9-6-1981','%d-%m-%Y'),2450,NULL,10);
INSERT INTO EMP VALUES (7788,'SCOTT','ANALYST',7566,STR_TO_DATE('13-7-1987','%d-%m-%Y')-85,3000,NULL,20);
INSERT INTO EMP VALUES (7839,'KING','PRESIDENT',NULL,STR_TO_DATE('17-11-1981','%d-%m-%Y'),5000,NULL,10);
INSERT INTO EMP VALUES (7844,'TURNER','SALESMAN',7698,STR_TO_DATE('8-9-1981','%d-%m-%Y'),1500,0,30);
INSERT INTO EMP VALUES (7876,'ADAMS','CLERK',7788,STR_TO_DATE('13-7-1987', '%d-%m-%Y'),1100,NULL,20);
INSERT INTO EMP VALUES (7900,'JAMES','CLERK',7698,STR_TO_DATE('3-12-1981','%d-%m-%Y'),950,NULL,30);
INSERT INTO EMP VALUES (7902,'FORD','ANALYST',7566,STR_TO_DATE('3-12-1981','%d-%m-%Y'),3000,NULL,20);
INSERT INTO EMP VALUES (7934,'MILLER','CLERK',7782,STR_TO_DATE('23-1-1982','%d-%m-%Y'),1300,NULL,10);
INSERT INTO SALGRADE VALUES (1,700,1200);
INSERT INTO SALGRADE VALUES (2,1201,1400);
INSERT INTO SALGRADE VALUES (3,1401,2000);
INSERT INTO SALGRADE VALUES (4,2001,3000);
INSERT INTO SALGRADE VALUES (5,3001,9999);
COMMIT;
##########################################################################################

셀렉트문들과 각종 연습문제

 

SELECT *
FROM emp;


SELECT empno,ename,job,mgr,hiredate,sal,comm,deptno
FROM emp;

SELECT ename,hiredate
FROM emp;

SELECT deptno, ename
FROM emp;



SELECT DISTINCT(job)
FROM emp;

SELECT COUNT(empno)
FROM emp;


SELECT *
FROM emp
WHERE deptno = 10;

SELECT *
FROM emp
WHERE sal >= 2500;

SELECT *
FROM emp
WHERE ename = 'king';

SELECT empno,ename
FROM emp
WHERE ename LIKE 's%';

SELECT empno,ename
FROM emp
WHERE ename LIKE '%T%';

SELECT empno,ename,comm
FROM emp
WHERE comm IN(300,500,1400);

SELECT empno,ename,sal
FROM emp
WHERE sal BETWEEN 1200
AND 3500;

SELECT ename,empno,job,deptno
FROM emp
WHERE deptno = 30 AND job = 'manager';

SELECT empno,ename,deptno
FROM emp
WHERE NOT deptno = 30;

SELECT empno,ename,comm
FROM emp
WHERE comm NOT IN (300,500,1400);

SELECT empno,ename
FROM emp
WHERE ename NOT LIKE '%S%';

SELECT empno,ename,sal
FROM emp
WHERE sal NOT BETWEEN 1200 AND 3700;

SELECT ename,job
FROM emp
WHERE mgr IS NULL;

SELECT deptno,AVG(sal)
FROM emp;

SELECT deptno,AVG(sal)
FROM emp
GROUP BY deptno;

SELECT deptno,COUNT(*),COUNT(comm)
FROM emp
GROUP BY deptno;

SELECT deptno,MAX(sal),MIN(sal)
FROM emp
GROUP BY deptno;

SELECT deptno,AVG(sal)
FROM emp
GROUP BY deptno
HAVING AVG(sal) >= 2000;

SELECT deptno,AVG(sal)
FROM emp
WHERE sal >= 1000
GROUP BY deptno
HAVING AVG(sal) >= 2000;

SELECT empno,ename,sal
FROM emp
ORDER BY sal DESC,ename ASC;

SELECT emp.ename,dept.dname
FROM emp,dept;

SELECT ename,dname
FROM emp,dept
WHERE emp.deptno = dept.deptno;

SELECT e.ename,d.dname
FROM emp AS e,dept AS d
WHERE e.deptno = d.deptno;

SELECT e.ename , m.ename
FROM emp AS e
INNER JOIN emp m
ON e.mgr = m.empno;

SELECT e.ename,e.sal,s.grade
FROM emp AS e,salgrade AS s
WHERE e.sal >= s.losal
AND  e.sal <= s.hisal;

SELECT e.ename,e.sal,s.grade
FROM emp AS e,salgrade AS s
WHERE e.sal BETWEEN s.losal
AND s.hisal;


SELECT e.ename,d.dname,s.grade
FROM emp AS e, dept AS d,salgrade AS s
WHERE e.deptno = d.deptno
AND e.sal BETWEEN s.losal
AND s.hisal;

SELECT e.ename,m.ename
FROM emp AS e, emp AS m
WHERE e.mgr = m.empno;


SELECT e.ename,m.ename
FROM emp AS e
LEFT JOIN emp AS m
ON e.mgr = m.empno;

SELECT e.ename,d.dname
FROM dept AS d
LEFT JOIN emp AS e
ON d.deptno = e.deptno;

SELECT ename,e.deptno,dname
FROM emp AS e, dept AS d
WHERE e.deptno = d.deptno;

SELECT ename,job,e.deptno,loc
FROM emp AS e , dept AS d
WHERE e.deptno = d.deptno
AND d.deptno = 30;


SELECT ename,job,e.deptno,loc
FROM emp AS e
INNER JOIN dept AS d
ON e.deptno = d.deptno
WHERE d.deptno = 30;

SELECT ename,comm,dname,loc
FROM emp,dept
WHERE emp.deptno = dept.deptno
AND emp.comm IS NOT NULL AND emp.comm <>0;

SELECT ename,comm,dname,loc
FROM emp,dept
WHERE emp.deptno = dept.deptno
AND emp.comm IS NOT NULL 
AND emp.comm <> 0;

SELECT e.ename,e.job,d.deptno,d.dname
FROM emp AS e,dept AS d
WHERE e.deptno = d.deptno
AND d.loc = 'dallas';

SELECT e.ename,d.dname
FROM emp AS e , dept AS d
WHERE e.deptno = d.deptno
AND e.ename LIKE '%A%';


SELECT e.ename,e.job,e.sal,s.grade
FROM emp AS e,salgrade AS s
WHERE e.sal BETWEEN s.losal
AND s.hisal;

SELECT c.ename,c.deptno
FROM emp AS e, emp AS c
WHERE e.empno <> c.empno
AND e.deptno = c.deptno
AND e.ename = 'allen'
ORDER BY c.ename;

SELECT c.ename,c.deptno
FROM emp AS e
INNER JOIN emp c ON e.deptno = c.deptno
WHERE e.empno <> c.empno
AND e.ename = 'allen'
ORDER BY c.ename;

SELECT dname
FROM dept
WHERE deptno = (SELECT deptno FROM emp WHERE ename = 'jones');

SELECT e.ename,d.dname
FROM emp AS e, dept AS d
WHERE e.deptno = d.deptno
AND d.deptno = 10;

SELECT e.ename,d.dname
FROM emp AS e,
(SELECT deptno , dname
 FROM dept
 WHERE deptno = 10
 )AS d
 WHERE e.deptno = d.deptno;
 
 SELECT empno,ename,sal
 FROM emp
 WHERE sal >( SELECT AVG(sal) FROM emp)
 ORDER BY sal DESC;
 
 SELECT empno,ename
 FROM emp
 WHERE sal = (SELECT MAX(sal)
 FROM emp
 WHERE deptno = 10);
 
 
 
 
SELECT e.ename, d.dname, e.sal
FROM emp AS e, dept AS d
WHERE e.deptno = d.deptno
AND e.sal BETWEEN 3000 AND 5000;

SELECT e.ename, d.dname, e.sal
FROM emp AS e, dept AS d
WHERE e.deptno = d.deptno
AND e.job = 'manager';

SELECT e.ename, e.hiredate
FROM emp AS e , dept AS d
WHERE e.deptno = d.deptno AND d.dname = 'accounting';

SELECT e.ename,e.hiredate, e.comm
FROM emp AS e , dept AS d
WHERE e.deptno = d.deptno
AND e.comm IS NOT NULL
AND e.comm != 0;

SELECT e.ename , e.sal
FROM emp AS e , dept AS d
WHERE e.deptno = d.deptno
AND d.loc = 'NEW YORK';



SELECT e.ename , e.sal , d.loc
FROM emp AS e, dept AS d
WHERE e.deptno = d.deptno
AND e.sal <= 1200
ORDER BY e.sal ASC;

SELECT friend.ename AS "스미스 동료"
FROM emp `work` , emp friend
WHERE work.deptno = friend.deptno
AND work.ename = 'SMITH' 
AND friend.ename = 'SMITH'; 

SELECT work.ename, work.job
FROM emp `work`, emp manager
WHERE work.mgr = manager.empno
AND manager.ename = 'KING';


SELECT e.ename , d.dname, e.sal
FROM emp AS e
INNER JOIN dept AS d
ON e.deptno = d.deptno
AND e.sal BETWEEN 3000 AND 5000;

SELECT e.ename , d.dname, e.sal
FROM emp AS e
INNER JOIN dept AS d
ON e.deptno = d.deptno
AND e.job = 'manager';

SELECT e.ename, e.hiredate
FROM emp AS e
INNER JOIN dept AS d
ON e.deptno = d.deptno
WHERE d.dname = 'ACCOUNTING';

SELECT * FROM dept;
SELECT * FROM emp;
SHOW TABLES;

SELECT e.ename , e.hiredate , e.comm
FROM emp AS e
INNER JOIN dept AS d
ON e.deptno = d.deptno
WHERE e.comm IS NOT NULL
AND e.comm <> 0;

SELECT e.ename , e.sal
FROM emp AS e
INNER JOIN dept AS d
ON e.deptno = d.deptno
WHERE d.loc = 'new york'
ORDER BY e.sal ASC;

SELECT e.ename, e.sal , d.loc
FROM emp AS e
INNER JOIN dept AS d
ON e.deptno = d.deptno
WHERE e.sal <= 1200
ORDER BY e.sal ASC;


SELECT friend.ename AS "스미스 동료"
FROM emp WORK
INNER JOIN emp friend
ON work.deptno = friend.deptno
WHERE work.ename = 'smith' AND friend.ename <> 'smith';

SELECT *
FROM emp;

SELECT SUM(DISTINCT(sal)) , SUM(DISTINCT(comm)),SUM(sal),SUM(sal)
FROM emp;

SELECT COUNT(*)
FROM emp
WHERE deptno = 30;

SELECT COUNT(*)
FROM emp
WHERE comm IS NOT NULL;

SELECT ROUND(AVG(sal),1)
FROM emp;

SELECT SUM(sal),AVG(sal),ROUND(AVG(sal)),MAX(sal),MIN(sal)
FROM emp;

SELECT deptno , ROUND(AVG(sal))
FROM emp
GROUP BY deptno;

SELECT deptno , job , ROUND(AVG(sal)) desc_sal
FROM emp
GROUP BY deptno , job
ORDER BY deptno DESC,desc_sal DESC;

SELECT ROUND(AVG(sal))
FROM emp
GROUP BY deptno;

SELECT COUNT(*)
FROM emp;

SELECT *
FROM emp;

SELECT *
FROM dept;

1. 문제) 부서번호가 10번인 부서의 사람 중 사원번호, 이름, 월급을

출력하라

SELECT empno, ename, sal 
FROM emp 
WHERE deptno=10;

​

2. 문제) 사원번호가 7369인 사람 중 이름, 입사일, 부서번호를 출력하라.

SELECT ename, hiredate, deptno 
FROM emp 
WHERE empno = 7369;

​

3. 문제) 이름이 ALLEN인 사람의 모든 정보를 출력하라.

​

SELECT * 
FROM emp 
WHERE ename = 'allen';

​

4. 문제) 입사일이 83/01/12인 사원의 이름, 부서번호, 월급을 출력하라.

SELECT ename,deptno,sal 
FROM emp 
WHERE hiredate ='1983-01-12';

​

5. 문제) 직업이 MANAGER가 아닌 사람의 모든 정보를 출력하라.

SELECT * 
FROM emp 
WHERE job <> 'manager';

​

6. 문제) 입사일이 81/04/02 이후에 입사한 사원의 정보를 출력하라.

SELECT * 
FROM emp 
WHERE hiredate > '1981-04-02';

​

​

7. 문제) 급여가 $800 이상인 사람의 이름, 급여, 부서번호를 출력하라.

SELECT ename, sal, deptno 
FROM emp 
WHERE sal >800;

​

8. 문제) 부서번호가 20번 이상인 사원의 모든 정보를 출력하라.

SELECT * 
FROM emp 
WHERE deptno>=20;

​

9. 문제) 이름이 K로 시작하는 사람보다 높은 이름을 가진 사람의 모든

정보를 출력하라.

SELECT * 
FROM emp 
WHERE ename >= 'l';

​

10. 문제) 입사일이 81/12/09 보다 먼저 입사한 사람들의 모든 정보를

출력하라.

SELECT * 
FROM emp 
WHERE hiredate <'1981-12-09';

​

11. 문제) 입사번호가 7698보다 작거나 같은 사람들의 입사번호와 이름을

출력하라.

SELECT empno, ename 
FROM emp 
WHERE empno<7698;

​

12. 문제) 입사일이 81/04/02 보다 늦고 82/12/09 보다 빠른 사원의 이름,

월급, 부서번호를 출력하라.

​

SELECT ename, sal, deptno 
FROM emp 
WHERE hiredate < '1982-12-09' 
AND hiredate > '1981-12-09';

​

13. 문제) 급여가 $1,600보다 크고 $3,000보다 작은 사람의 이름, 직업,

급여를 출력하라.

​

SELECT ename, job, sal 
FROM emp 
WHERE sal 
BETWEEN 1600 AND 3000;

​

14. 문제) 사원번호가 7654와 7782 사이 이외의 사원의 모든 정보를

출력하라.

SELECT * 
FROM emp 
WHERE empno BETWEEN 7654 AND 7782;

​

15. 문제) 이름이 B와 J 사이의 모든 사원의 정보를 출력하라.

​

SELECT * 
FROM emp 
WHERE ename BETWEEN 'b' AND 'j';

​

16. 문제) 입사일이 81년 이외에 입사한 사람의 모든 정보를 출력하라.

SELECT * 
FROM emp 
WHERE YEAR(hiredate) <> '1981';

​

17. 문제) 직업이 MANAGER와 SALESMAN인 사람의 모든 정보를 출력하라.

SELECT * 
FROM emp 
WHERE job ='manager' OR job ='salesman';

​

18. 문제) 부서번호와 20, 30번을 제외한 모든 사람의 이름, 사원번호, 부서번호를 출력하라.

​

SELECT ename, empno, deptno 
FROM emp 
WHERE deptno <> 20 AND deptno <> 30;

​

​

19. 문제) 이름이 S로 시작하는 사원의 사원번호, 이름, 입사일, 부서번호

를 출력하라.

SELECT ename, hiredate, empno, deptno 
FROM emp 
WHERE ename LIKE 's%';

​

20. 문제) 입사일이 81년도인 사람의 모든 정보를 출력하라

SELECT * 
FROM emp 
WHERE YEAR(hiredate) = '1981';

​

21. 문제) 이름 중 S자가 들어가 있는 사람만 모든 정보를 출력하라.

SELECT * 
FROM emp 
WHERE ename LIKE '%s%';

​

22. 문제) 이름이 S로 시작하고 마지막 글자가 T인 사람의 모든 정보를

출력하라(단, 이름은 전체 5자리이다)

SELECT * 
FROM emp 
WHERE ename 
LIKE 's%' 
AND ename LIKE '%t';

​

23. 문제) 첫 번째 문자는 관계없고, 두 번째 문자가 A인 사람의 정보를

출력하라.

SELECT * 
FROM emp 
WHERE ename LIKE '_a%';

​

24. 문제) 커미션이 NULL인 사람의 정보를 출력하라.

SELECT * 
FROM emp 
WHERE comm IS NULL;

​

25. 문제) 커미션이 NULL이 아닌 사람의 모든 정보를 출력하라.

SELECT * 
FROM emp 
WHERE comm IS NOT NULL;

​

26. 문제) 부서가 30번 부서이고 급여가 $1,500 이상인 사람의 이름,

부서 ,월급을 출력하라.

SELECT ename, deptno, sal 
FROM emp 
WHERE deptno =30 AND sal>= 1500;

​

27. 문제) 이름의 첫 글자가 K로 시작하거나 부서번호가 30인 사람의

사원번호, 이름, 부서번호를 출력하라.

SELECT empno,ename, deptno 
FROM emp 
WHERE ename LIKE 'k%'OR deptno =30;

​

28. 문제) 급여가 $1,500 이상이고 부서번호가 30번인 사원 중 직업이

MANAGER인 사람의 정보를 출력하라

SELECT * 
FROM emp 
WHERE sal>=1500 
AND deptno=30 AND job='manager';

​

29. 문제) 부서번호가 30인 사람 중 사원번호 SORT하라.

SELECT * 
FROM emp 
WHERE deptno=30 ORDER BY empno;

​

30. 문제) 급여가 많은 순으로 SORT하라.

SELECT * 
FROM emp 
ORDER BY sal DESC;

​

31. 문제) 부서번호로 ASCENDING SORT한 후 급여가 많은 사람 순으로

출력하라.

SELECT *
FROM emp 
ORDER BY deptno ASC, sal DESC;

​

32. 문제) 부서번호가 DESCENDING SORT하고, 이름 순으로 ASCENDING SORT,

급여 순으로 DESCENDING SORT 하라.

SELECT *
FROM emp 
ORDER BY deptno DESC, ename ASC, sal DESC;


SHOW TABLES;

SELECT *
FROM dept;

SELECT *
FROM emp;

SELECT *
FROM salgrade;

 

 

작업 11, 반복문을 활용한 게시물 리스트 구현
작업 12, 게시물 상세페이지 구현
작업 13, servlet jsp 매핑
작업 14, 리팩토링, DBUtil 객체화x, 메인페이지 추가
작업 15, SecSql 도입(SQL 인젝션)
작업 16, 게시물 삭제 기능 구현, 리스트 구조 변경

 

TODO

 

페이징 처리 하는 방법
article/list?page(숫자) 했을 때 나오는 페이지

-select * from article order by id desc limit 0 , 10 -> 최신글 10개

-select * from article order by id desc limit 10 , 10 -> 최신글 10개 건너뛰고 10개

-select * from article order by id desc limit 20 , 10 -> 최신글 20개 건너뛰고 10개

https://beaniejoy.tistory.com/25

INSERT INTO article
SET regDate = NOW(),
title = CONCAT('제목 ',RAND()),
body = CONCAT('내용 ',RAND());

랜덤 글 작성

 

//페이지 번호와 한 페이지에 보여줄 게시글 수를 미리 상수로 지정합니다.

//java
//Copy code
//final int ARTICLE_PER_PAGE = 10; // 한 페이지당 보여줄 게시글 수
//final int PAGE_PER_BLOCK = 5; // 한 블록당 보여줄 페이지 수
//요청받은 페이지 번호를 파라미터에서 받아옵니다.
//java
//Copy code
//int pageNum = Integer.parseInt(request.getParameter("page"));
//데이터베이스에서 해당 페이지에 해당하는 게시글을 가져오기 위해 SQL 쿼리문을 작성합니다.
//java
//Copy code
//String sql = "SELECT * FROM article ORDER BY id DESC LIMIT ?, ?";
//int startArticleIndex = (pageNum - 1) * ARTICLE_PER_PAGE;
//try(Connection conn = DriverManager.getConnection(url, user, password);
//    PreparedStatement pstmt = conn.prepareStatement(sql)) {
//    pstmt.setInt(1, startArticleIndex);
//    pstmt.setInt(2, ARTICLE_PER_PAGE);
//    try(ResultSet rs = pstmt.executeQuery()) {
//        // 게시글 데이터를 가져온 후, JSP에 전달하여 출력
//    }
//}
//게시글 총 개수와 페이지 총 개수를 계산합니다.
//java
//Copy code
//String sql = "SELECT COUNT(*) FROM article";
//try(Connection conn = DriverManager.getConnection(url, user, password);
//    PreparedStatement pstmt = conn.prepareStatement(sql);
//    ResultSet rs = pstmt.executeQuery()) {
//    rs.next();
//    int totalArticleCount = rs.getInt(1);
//    int totalPageCount = (int) Math.ceil((double) totalArticleCount / ARTICLE_PER_PAGE);
//    int currentPageBlock = (int) Math.ceil((double) pageNum / PAGE_PER_BLOCK);
//    int startPageNum = (currentPageBlock - 1) * PAGE_PER_BLOCK + 1;
//    int endPageNum = currentPageBlock * PAGE_PER_BLOCK;
//    if(endPageNum > totalPageCount) {
//        endPageNum = totalPageCount;
//    }
//}
//JSP에서 페이지 번호에 대한 링크를 출력합니다.
//html
//Copy code
//<ul class="pagination">
//<% if(currentPageBlock > 1) { %>
//    <li><a href="list?page=<%= startPageNum - 1 %>">이전</a></li>
//<% } %>
//<% for(int i = startPageNum; i <= endPageNum; i++) { %>
//    <li <% if(pageNum == i) { %>class="active"<% } %>>
//        <a href="list?page=<%= i %>"><%= i %></a>
//    </li>
//<% } %>
//<% if(currentPageBlock < Math.ceil((double) totalPageCount / PAGE_PER_BLOCK)) { %>
//    <li><a href="list?page=<%= endPageNum + 1 %>">다음</a></li>
//<% } %>
//</ul>
//위와 같은 코드를 사용하여 JSP에서 페이지네이션을 구현할 수 있습니다. 페이지 번호에 대한 링크를 클릭하면 해당 페이지에 대한 게시글을 가져와서 출력합니다

챗 gpt는 이런 답을 주는데 더 쉬운 방법이 있을 것 같다

+ Recent posts