1. 성적 저장 기능
2. 전체 학생 성적 조회 기능
3. 개별 학생 성적 조회 기능
4. 성적 수정 기능
5. 성적 정보 삭제 기능
package com.jdbc.basic.score.domain;
import lombok.*;
@Setter @Getter
@NoArgsConstructor // 기본 생성자
@AllArgsConstructor // 모든 필드 초기화 생성자
@ToString
@Builder // 객체 생성시 생성자 역할을 대신
// 데이터베이스 score 테이블의 행데이터를 저장할 객체
public class Score {
private int stuNum;
private String stuName;
private int kor;
private int eng;
private int math;
private int total;
private double average;
// 총점, 평균을 계산하는 메서드
public void calc(){
this.total = kor + eng + math;
this.average = Math.round((total / 3.0) * 100) / 100;
}
}
package com.jdbc.basic.score.repository;
import com.jdbc.basic.score.domain.Score;
import java.util.Map;
public interface ScoreRepository {
// 성적 정보 저장
boolean save(Score score);
// 성적 정보 삭제
boolean remove(int stuNum);
// 성적 정보 수정
boolean modify(Score score);
// 전체 성적 조회
Map<Integer, Score> findAll();
// 개별 성적 조회
Score findOne(int stuNum);
}
package com.jdbc.basic.score.controller;
import com.jdbc.basic.score.domain.Score;
import java.util.HashMap;
import java.util.Map;
// 데이터들을 전처리 후처리하고 저장 관리하는 클래스
public class ScoreController {
// 성적 정보가 저장될 맵
private static final Map<Integer, Score> scoreMap;
static {
scoreMap = new HashMap<>();
}
// 학생 성적정보 입력 기능
public void insertStudent(Score score){
// 메모리에 저장
scoreMap.put(score.getStuNum(), score);
// DB에 저장 명령
}
}
package com.jdbc.basic.score.repository;
import com.jdbc.basic.Connect;
import com.jdbc.basic.score.domain.Score;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
// Oracle DBMS에 성적 정보를 CRUD하는 클래스
public class ScoreOracleRepo implements ScoreRepository {
@Override
public boolean save(Score score) {
String sql = "INSERT INTO score " +
"VALUES (seq_score.nextval, ?,?,?,?,?,?)";
try (Connection conn = Connect.makeConnection()) {
// 트랜잭션 처리
conn.setAutoCommit(false); // 자동커밋 설정 끄기
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, score.getStuName());
pstmt.setInt(2, score.getKor());
pstmt.setInt(3, score.getEng());
pstmt.setInt(4, score.getMath());
pstmt.setInt(5, score.getTotal());
pstmt.setDouble(6, score.getAverage());
int result = pstmt.executeUpdate();
if (result != 0) {
conn.commit(); // 커밋 완료
return true;
} else {
conn.rollback(); // 롤백
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public boolean remove(int stuNum) {
String sql = "DELETE FROM score WHERE stu_num=?";
try (Connection conn = Connect.makeConnection()) {
// 트랜잭션 처리
conn.setAutoCommit(false); // 자동커밋 설정 끄기
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, stuNum);
int result = pstmt.executeUpdate();
if (result != 0) {
conn.commit(); // 커밋 완료
return true;
} else {
conn.rollback(); // 롤백
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public boolean modify(Score score) {
String sql = "UPDATE score " +
" SET kor =?, eng = ?, math = ?, total = ?, average = ? " +
" WHERE stu_num = ?";
try (Connection conn = Connect.makeConnection()) {
// 트랜잭션 처리
conn.setAutoCommit(false); // 자동커밋 설정 끄기
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, score.getKor());
pstmt.setInt(2, score.getEng());
pstmt.setInt(3, score.getMath());
pstmt.setInt(4, score.getTotal());
pstmt.setDouble(5, score.getAverage());
int result = pstmt.executeUpdate();
if (result != 0) {
conn.commit(); // 커밋 완료
return true;
} else {
conn.rollback(); // 롤백
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public Map<Integer, Score> findAll() {
Map<Integer, Score> scoreMap = new HashMap<>();
String sql = "SELECT * FROM score ORDER BY stu_num";
try (Connection conn = Connect.makeConnection()) {
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
Score s = new Score(
rs.getInt("stu_num")
, rs.getString("stu_name")
, rs.getInt("kor")
, rs.getInt("eng")
, rs.getInt("math")
, rs.getInt("total")
, rs.getDouble("average")
);
scoreMap.put(s.getStuNum(), s);
}
return scoreMap;
} catch (Exception e) {
e.printStackTrace();
return Collections.emptyMap();
}
}
@Override
public Score findOne(int stuNum) {
String sql = "SELECT * FROM score WHERE stu_num = ?";
try (Connection conn = Connect.makeConnection()) {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, stuNum);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
Score s = new Score(
rs.getInt("stu_num")
, rs.getString("stu_name")
, rs.getInt("kor")
, rs.getInt("eng")
, rs.getInt("math")
, rs.getInt("total")
, rs.getDouble("average")
);
return s;
}
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
@Test
@DisplayName("성적 정보를 수정해야 한다.")
void findModify(){
// given [객체에서 수정 진행]
Score score = repository.findOne(3);
score.setKor(80);
score.setEng(80);
score.setMath(80);
score.setTotal(80);
score.calc();
//when - 테스트할 상황
boolean result = repository.modify(score);
//then - 테스트 후 예상되는 결과
Score newScore = repository.findOne(3);
assertEquals(80, newScore.getAverage());
}
==== 최종 코드 ↓ =====
package com.jdbc.basic.score.domain;
import lombok.*;
@Setter @Getter
@NoArgsConstructor // 기본 생성자
@AllArgsConstructor // 모든 필드 초기화 생성자
@ToString
@Builder // 객체 생성시 생성자 역할을 대신
// 데이터베이스 score 테이블의 행데이터를 저장할 객체
public class Score {
private int stuNum;
private String stuName;
private int kor;
private int eng;
private int math;
private int total;
private double average;
// 총점, 평균을 계산하는 메서드
public void calc(){
this.total = kor + eng + math;
this.average = Math.round((total / 3.0) * 100) / 100;
}
}
package com.jdbc.basic.score.repository;
import com.jdbc.basic.score.domain.Score;
import java.util.Map;
public interface ScoreRepository {
// 성적 정보 저장
boolean save(Score score);
// 성적 정보 삭제
boolean remove(int stuNum);
// 성적 정보 수정
boolean modify(Score score);
// 전체 성적 조회
Map<Integer, Score> findAll();
// 개별 성적 조회
Score findOne(int stuNum);
// 반 전체 평균 조회
double getClassAverage();
}
package com.jdbc.basic.score.repository;
import com.jdbc.basic.Connect;
import com.jdbc.basic.score.domain.Score;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
// Oracle DBMS에 성적 정보를 CRUD하는 클래스
public class ScoreOracleRepo implements ScoreRepository {
@Override
public boolean save(Score score) {
String sql = "INSERT INTO score " +
"VALUES (seq_score.nextval, ?,?,?,?,?,?)";
try (Connection conn = Connect.makeConnection()) {
// 트랜잭션 처리
conn.setAutoCommit(false); // 자동커밋 설정 끄기
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, score.getStuName());
pstmt.setInt(2, score.getKor());
pstmt.setInt(3, score.getEng());
pstmt.setInt(4, score.getMath());
pstmt.setInt(5, score.getTotal());
pstmt.setDouble(6, score.getAverage());
int result = pstmt.executeUpdate();
if (result != 0) {
conn.commit(); // 커밋 완료
return true;
} else {
conn.rollback(); // 롤백
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public boolean remove(int stuNum) {
String sql = "DELETE FROM score WHERE stu_num=?";
try (Connection conn = Connect.makeConnection()) {
// 트랜잭션 처리
conn.setAutoCommit(false); // 자동커밋 설정 끄기
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, stuNum);
int result = pstmt.executeUpdate();
if (result != 0) {
conn.commit(); // 커밋 완료
return true;
} else {
conn.rollback(); // 롤백
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public boolean modify(Score score) {
String sql = "UPDATE score " +
" SET kor =?, eng = ?, math = ?, total = ?, average = ? " +
" WHERE stu_num = ?";
try (Connection conn = Connect.makeConnection()) {
// 트랜잭션 처리
conn.setAutoCommit(false); // 자동커밋 설정 끄기
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, score.getKor());
pstmt.setInt(2, score.getEng());
pstmt.setInt(3, score.getMath());
pstmt.setInt(4, score.getTotal());
pstmt.setDouble(5, score.getAverage());
pstmt.setDouble(6, score.getStuNum());
int result = pstmt.executeUpdate();
if (result != 0) {
conn.commit(); // 커밋 완료
return true;
} else {
conn.rollback(); // 롤백
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public Map<Integer, Score> findAll() {
Map<Integer, Score> scoreMap = new HashMap<>();
String sql = "SELECT * FROM score ORDER BY stu_num";
try (Connection conn = Connect.makeConnection()) {
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
Score s = new Score(
rs.getInt("stu_num")
, rs.getString("stu_name")
, rs.getInt("kor")
, rs.getInt("eng")
, rs.getInt("math")
, rs.getInt("total")
, rs.getDouble("average")
);
scoreMap.put(s.getStuNum(), s);
}
return scoreMap;
} catch (Exception e) {
e.printStackTrace();
return Collections.emptyMap();
}
}
@Override
public Score findOne(int stuNum) {
String sql = "SELECT * FROM score WHERE stu_num = ?";
try (Connection conn = Connect.makeConnection()) {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, stuNum);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
Score s = new Score(
rs.getInt("stu_num")
, rs.getString("stu_name")
, rs.getInt("kor")
, rs.getInt("eng")
, rs.getInt("math")
, rs.getInt("total")
, rs.getDouble("average")
);
return s;
}
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
public double getClassAverage() {
StringBuilder sql = new StringBuilder();
sql.append("SELECT AVG(average) AS avg_cls\n")
.append("FROM score");
try (Connection conn = Connect.makeConnection()){
PreparedStatement pstmt = conn.prepareStatement(sql.toString());
ResultSet rs = pstmt.executeQuery();
if(rs.next()) {
return rs.getDouble("avg_cls");
}
} catch (SQLException e) {
e.printStackTrace();
}
return 0.0;
}
}
package com.jdbc.basic.score.controller;
import com.jdbc.basic.score.domain.Score;
import com.jdbc.basic.score.repository.ScoreOracleRepo;
import com.jdbc.basic.score.repository.ScoreRepository;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// 데이터들을 전처리 후처리하고 저장 관리하는 클래스
public class ScoreController {
// 성적 정보가 저장될 맵
private static Map<Integer, Score> scoreMap;
// ScoreRepository에 의존성 관계를 가진다.
private final ScoreRepository repository; // 의존성 관계를 가진 경우 인터페이스로 필드 생성.
// 누구라도 대체할수 있도록 구현체와 연결하면 x
public ScoreController() {
this.repository = new ScoreOracleRepo();
}
static {
scoreMap = new HashMap<>();
}
// 학생 성적정보 입력 기능
public void insertStudent(Score score) {
// 메모리에 저장
scoreMap.put(score.getStuNum(), score);
// DB에 저장 명령
repository.save(score);
}
// 성적 전체 조회
public List<Score> findAllStudents() {
Map<Integer, Score> students = repository.findAll();
scoreMap = students;
List<Score> scoreList = new ArrayList<>();
for (Integer stuNum : scoreMap.keySet()) {
scoreList.add(scoreMap.get(stuNum));
}
return scoreList;
}
// 반 평균을 구하는 메서드
public double calsClassAverage() {
// case 1: 앱 내부에서 구한다. (비추)
/*double avgSum = 0.0;
for (Integer stuNum : scoreMap.keySet()) {
avgSum += scoreMap.get(stuNum).getAverage();
}
return avgSum / scoreMap.size();*/
// case 2: DB에서 전체평균을 구해서 가져온다.
return repository.getClassAverage();
}
// 성적 개별 조회
public Score findOneStudent(int stuNum) {
return repository.findOne(stuNum);
}
// 성적 수정
public boolean updateStudent(int stuNum, int kor, int eng, int math) {
// 1.DB에서 해당 학생을 조회한다.
Score target = findOneStudent(stuNum);
if (target != null) {
//2. 수정 진행
target.setKor(kor);
target.setEng(eng);
target.setMath(math);
//3. DB에 수정 반영
return repository.modify(target);
}
return false;
}
// 성적정보 삭제
public boolean deleteStudent(int stuNum){
return repository.remove(stuNum);
}
// 학번으로 조회했을 때 학생 존재 유무를 리턴
public boolean hasScore(int stuNum){
return repository.findOne(stuNum) != null;
}
}
package com.jdbc.basic.score.view;
public class Run {
public static void main(String[] args) {
new ScoreMenu().mainMenu();
}
}
package com.jdbc.basic.score.view;
import com.jdbc.basic.score.controller.ScoreController;
import com.jdbc.basic.score.domain.Score;
import java.util.List;
import java.util.Scanner;
// 화면 출력창
public class ScoreMenu {
private final ScoreController controller;
Scanner sc;
public ScoreMenu() {
controller = new ScoreController();
sc = new Scanner(System.in);
}
public void mainMenu() {
while (true) {
System.out.println("\n ====== 성적 관리 프로그램 ======= ");
System.out.println("# 1. 성적 정보 입력");
System.out.println("# 2. 성적 전체 조회");
System.out.println("# 3. 성적 개별 조회");
System.out.println("# 4. 성적 정보 수정");
System.out.println("# 5. 성적 정보 삭제");
System.out.println("# 9. 끝내기");
int menu = inputN("\n메뉴입력 : ");
switch (menu) {
case 1:
insertMenu();
break;
case 2:
findAllMenu();
break;
case 3:
findOneMenu();
break;
case 4:
modifyMenu();
break;
case 5:
removeMenu();
break;
case 9:
System.out.println("프로그램을 종료합니다.");
System.exit(0);
return;
default:
System.out.println("\n# 메뉴를 다시 입력하세요.");
}
}
}
// 5번 메뉴
private void removeMenu() {
System.out.println("\n# 삭제할 학생의 학번을 입력하세요!");
int stuNum = inputN(">>> ");
if (controller.hasScore(stuNum)) {
boolean flag = controller.deleteStudent(stuNum);
if (flag) {
System.out.println("# 삭제가 완료되었습니다.");
} else {
System.out.println("# 삭제에 실패했습니다.");
}
} else {
System.out.println("\n# 해당 학번은 존재하지 않습니다.");
}
}
// 4번 메뉴
private void modifyMenu() {
System.out.println("\n# 수정할 학생의 학번을 입력하세요!");
int stuNum = inputN(">>> ");
if (controller.hasScore(stuNum)) {
System.out.println("# 수정할 점수들을 입력하세요.");
int kor = inputN(" - 국어: ");
int eng = inputN(" - 영어: ");
int math = inputN(" - 수학: ");
boolean flag = controller.updateStudent(stuNum,kor,eng,math);
if (flag) {
System.out.println("# 수정이 완료되었습니다.");
} else {
System.out.println("#수정이 실패했습니다.");
}
} else {
System.out.println("\n# 해당 학번은 존재하지 않습니다.");
}
}
// 3번 메뉴
private void findOneMenu() {
System.out.println("\n# 조회할 학생의 학번을 입력하세요!");
int stuNum = inputN(">>> ");
Score student = controller.findOneStudent(stuNum);
if(student != null) {
System.out.println("\n## 조회 결과");
System.out.println("- 학번: " + student.getStuNum());
System.out.println("- 이름: " + student.getStuName());
System.out.println("- 국어: " + student.getKor());
System.out.println("- 영어: " + student.getEng());
System.out.println("- 수학: " + student.getMath());
System.out.println("- 총점: " + student.getTotal());
System.out.println("- 평균: " + student.getAverage());
} else {
System.out.println("\n# 해당 학번은 존재하지 않습니다.");
}
}
// 2번 메뉴
private void findAllMenu() {
List<Score> students = controller.findAllStudents();
System.out.printf("\n=============== 모든 성적 정보 (반 평균 : %.2f점) ================\n",
controller.calsClassAverage());
System.out.printf("%5s%5s%5s%5s%5s%5s%5s\n"
, "학번", "이름", "국어", "영어", "수학", "총점", "평균");
System.out.println("----------------------------------------------");
for (Score s : students) {
System.out.printf("%5d %5s%5d %5d %5d %4d %.2f\n"
, s.getStuNum(), s.getStuName(), s.getKor()
, s.getEng(), s.getMath(), s.getTotal()
, s.getAverage());
}
}
// 1번 메뉴
private void insertMenu() {
System.out.println("\n 성적 정보 입력을 시작합니다.");
System.out.println(" - 이름 :");
String name = sc.next();
int kor = inputN(" - 국어:");
int eng = inputN(" - 영어:");
int math = inputN(" - 수학:");
Score score = new Score();
score.setStuName(name);
score.setKor(kor);
score.setEng(eng);
score.setMath(math);
score.calc();
controller.insertStudent(score);
System.out.printf("\n %s 님의 성정 정보가 저장되었습니다.\n", name);
}
// 숫자입력 메서드
private int inputN(String msg) {
int n;
while (true) {
try {
System.out.println(msg);
n = sc.nextInt();
break;
} catch (Exception e) {
sc.nextLine();
System.out.println("# 정수로만 입력하세요");
}
}
return n;
}
}
'데이터베이스' 카테고리의 다른 글
데이터베이스_ DB CRUD(실습_Spring 사용x)_ 22.06.29(day08) (0) | 2022.06.29 |
---|---|
데이터베이스_JUnit을 통한 테스트 DB 연결(인텔리제이 - 오라클)_ 22.06.29(day08) (0) | 2022.06.29 |
데이터베이스_Spring 없이 자바로만 DB 연결(인텔리제이 - 오라클)_ 22.06.29(day08) (0) | 2022.06.29 |
데이터베이스_JAVA(인텔리제이)와 데이터베이스(오라클) 연결(Gradle) 설정_ 22.06.29(day08) (0) | 2022.06.29 |
데이터베이스_SQL기본(뷰, 그룹함수)_ 22.06.29(day08) (0) | 2022.06.29 |