Learn & Record
JAVA, MariaDB (JDBC UPDATE, DELETE, 디자인패턴, 싱글턴 패턴, 어댑터 패턴, 빌더패턴, MVC패턴, MVC패턴+DB연결) 본문
JAVA, MariaDB (JDBC UPDATE, DELETE, 디자인패턴, 싱글턴 패턴, 어댑터 패턴, 빌더패턴, MVC패턴, MVC패턴+DB연결)
Walker_ 2024. 2. 16. 13:471. JDBC UPDATE 구현
[ DBUpdate 파일 ]
package ch_01.day2402141516;
import java.sql.SQLException;
import java.util.Scanner;
public class DBUpdate extends DBSelect{
protected User modifyUser(){
User user = new User();
Scanner scanner = new Scanner(System.in);
Boolean validate = false;
String validateTemp;
do {
System.out.println("정보 수정 할 회원의 아이디를 입력하세요: ");
user.userID = scanner.nextLine();
System.out.println("회원의 이름을 입력하세요 : ");
user.name = scanner.nextLine();
System.out.println("회원의 나이를 입력하세요 : ");
user.age = Integer.parseInt(scanner.nextLine());
System.out.println("회원의 직업을 입력하세요 : ");
user.job = scanner.nextLine();
System.out.println("수정 된 회원 : " + user.userID + " / " + user.name + " / "
+ user.age + " / " + user.job +"이 맞습니까? (y/n)");
validateTemp = scanner.nextLine();
validate = !validateTemp.equals("y");
}while (validate);
scanner.close();
return user;
}
public void updateUser() throws SQLException {
User user = modifyUser();
String updateSQL = "UPDATE uUser SET name = ?, age = ?, job = ? WHERE userID = ? ";
preparedStatement = conn.prepareStatement(updateSQL); // 쿼리 실행 준비
// ? 자리에 순서대로 데이터 입력
preparedStatement.setString(1, user.name);
preparedStatement.setInt(2, user.age);
preparedStatement.setString(3, user.job);
preparedStatement.setString(4, user.userID);
int cnt = preparedStatement.executeUpdate(); // 영향을 받은 데이터 갯수 반환
// pstmt.excuteQuery() : select
// pstmt.excuteUpdate() : insert, update, delete ..
if(cnt ==1 ){
System.out.println("영향 받은 데이터 : :"+cnt);
System.out.println("데이터 수정에 성공했습니다.");
} else {
System.out.println("데이터 수정에 실패했습니다.");
}
}
}
- 기능 구현 코드 [ My_06_UpdateUser] 파일
package ch_01.day240214_16;
import java.sql.SQLException;
public class My_06_UpdateUser {
public static void main(String[] args) throws SQLException {
DBUpdate myDB = new DBUpdate();
myDB.connectDB(); // DB 클래스에 선언된 메서드
myDB.getAllUser(); // DBSelect 클래스에 선언된 메서드
myDB.updateUser();
myDB.getAllUser(); // DBSelect 클래스에 선언된 메서드
myDB.closeDB(); // DB 클래스에 선언된 메서드
}
}
2. JDBC DELETE 구현
package ch_01.day240214_16;
import java.sql.SQLException;
import java.util.Scanner;
public class DBDelete extends DBSelect{
public void deleteUser() throws SQLException{
Scanner scanner = new Scanner(System.in);
System.out.println("삭제 할 유저의 아이디를 입력하세요 : ");
String userID = scanner.nextLine();
String deleteSQL = "DELETE FROM tUser WHERE userID='" + userID + "' ";
preparedStatement = conn.prepareStatement(deleteSQL); // 쿼리 실행 준비
int cnt = preparedStatement.executeUpdate(); // 영향을 받은 데이터 갯수 반환
// pstmt.excuteQuerey() : select
// pstmt.escuteUpdate() : insert, update, delete ..
if (cnt == 1) {
System.out.println("영향 받은 데이터 : : " + cnt);
System.out.println("데이터 삭제에 성공했습니다.");
} else {
System.out.println("데이터 삭제에 실패했습니다.");
}
scanner.close();
}
}
package ch_01.day240214_16;
import java.sql.SQLException;
public class My_08_DeleteUser {
public static void main(String[] args) throws SQLException {
DBDelete myDB = new DBDelete();
myDB.connectDB(); // 데이터베이스 연결
myDB.getAllUser(); // 모든 유저 보여줌
myDB.deleteUser(); // 삭제 처리
myDB.getAllUser(); // 모든 유저 보여줌 > 삭제 확인 용도
myDB.closeDB(); // 데이터베이스 연결 닫기
}
}
3. 디자인 패턴 Design Pattern
- 지금까지 수많은 소프트웨어 개발자들이 오랜 세월에 걸쳐 쌓아 온 프로그램 설계 노하루를 집대성한 것
- 디자인 패턴의 개념은 1995년 Gof(Gang of Four)라고 불리는 저자 네 명 (에릭 감마, 리처드 헬름, 랄프 존슨, 존 블라)이
- 쓴 "Gof의 디자인 패턴"에서 처음 소개된 이후 많은 프로그래머들의 연구 대상이 되었음
- 객체 지향 프로그램을 어떻게 구현해야 더 유연하고 재활용성이 높은 프로그램을 만들 수 있는지를 정리한 내용
- 구조화 되지 않은 프로그램은 프로그램의 구성 요소가 강하게 결합하기 때문에 프로그램의 유지보수와 확장이 어려움
- 간단히 말해서 프로그램 특성에 따른 설계 유형을 이론화한 내용.
- 따라서 디자인 패턴은 자바는 물론 C++이나 C# 같은 객체 지향 언어에도 작용하여 구현할 수 있음
4. 싱글턴 패턴 Singleton pattern
- 객체 지향 프로그램에서 인스턴스를 단 하나만 생성하는 디자인 패턴
5. 어댑터 패턴 Adapter Pattern
- 어댑터를 번역하면 변환기 converter라고 할 수 있음
- 변환기의 역할을 서로 다른 두 인터페이스 사이에 통신이 가능하게 하는 것
- ODBC, JDBC가 어댑터 패턴을 이용해 다양한 데이터베이스 시스템을 단일한 인터페이스로 조작가능
- * 자바의 경우 DB 종류에 구분없이, JDBC로 동일하게 사용가능
[ AdpaterNo.java ]
package ch_01.day240214_16.adapter;
class WorkMan {void runWork() {System.out.println("work");}
}
class StudyStudent {void runStudy() {System.out.println("study");}
}
public class AdapterNo {
public static void main(String[] args) {
WorkMan workMan = new WorkMan();
StudyStudent studyStudent = new StudyStudent();
// 유사한 기능이라하더라도 새로운 클래스가 생성이 되면 메서드의 사용법을 공부해야 함
workMan.runWork();
studyStudent.runStudy();
}
}
[ Adapter.java ]
package ch_01.day240214_16.adapter;
import javax.swing.text.Style;
interface AdapterService {
void runService();
}
class AdapterServiceA implements AdapterService {
WorkMan workMan = new WorkMan();
@Override
public void runService() { workMan.runWork();}
}
class AdapterServiceB implements AdapterService{
StudyStudent studyStudent = new StudyStudent();
@Override
public void runService() { studyStudent.runStudy();}
}
public class Adapter {
public static void main(String[] args) {
AdapterService asa1 = new AdapterServiceA();
AdapterService asb1 = new AdapterServiceB();
asa1.runService();
asb1.runService();
}
}
6. 빌더패턴
- 객체 생성을 하는데, 해당 클래스의 멤버 변수는 8개
- name, age, address, grade, tel, email, reserve, hobby
- 이름 항상 있지만, 나머지는 변동됨. 생성자를 몇 개 만들어야 할까
package ch_01.day240214_16.patternb;
public class Account {
private int accID;
private int balance;
private String cusName;
// 모든 필드를 사용하는 생성자가 필요
public Account(int accID, int balance, String cusName) {
this.accID = accID;
this.balance = balance;
this.cusName = cusName;
}
@Override
public String toString() {
return "Acount{" +
"accID=" + accID +
", balance=" + balance +
", cusName='" + cusName + '\'' +
'}';
}
public static class Builder {
// 외부 클래스와 동일한 필드를 가짐
private int accID;
private int balance;
private String cusName;
Builder() {
}
public Builder accID(int accID) {
this.accID = accID;
return this;
}
public Builder balance(int balance) {
this.balance = balance;
return this;
}
public Builder cusName(String cusName) {
this.cusName = cusName;
return this;
}
public Account Builder() {
return new Account(this.accID, this.balance, this.cusName);
}
}
}
- 빌더 패턴으로 유연하게 생성자를 활용 가능
package ch_01.day240214_16.patternb;
public class Test {
public static void main(String[] args) {
// 계좌번호를 초기값으로 객체 생성
Account account1 = new Account.Builder().accID(222).Builder();
System.out.println(account1);
// 계좌번호, 잔액을 초기값으로 객체 생성
Account account2 = new Account.Builder().accID(222).balance(10000).Builder();
System.out.println(account2);
// 계좌번호, 잔액, 예금주를 초기값으로 객체 생성
Account account3 = new Account.Builder().accID(222).balance(10000).cusName("홍길동").Builder();
System.out.println(account3);
// 잔액, 예금주를 초기값으로 객체 생성
Account account4 = new Account.Builder().balance(10000).cusName("홍길동").Builder();
System.out.println(account4);
// 예금주를 초기값으로 객체 생성
Account account5 = new Account.Builder().cusName("홍길동").Builder();
System.out.println(account5);
}
}
7. MVC 패턴 Model View Controller
- 디자인 패턴의 일종으로 전체 프로그램의 구조와 관련된 디자인 패턴
- 애플리케이션 내부 데이터와 사용자에게 표시하는 정보와 분리
- 사용성과 확장성이 용이하다는 장점이 있고, 복잡해질수록 모델과 뷰의 관계가 복잡해지는 단점
- 모델 : 데이터인 데이터베이스, 상수, 변수를 뜻함.데이터 혹은 데이터를 처리하는 영역을 의미
- 뷰 : 모델을 기반으로 사용자가 볼 수 있는 화면을 뜻함. 사용자 인터페이스 요소
- 컨트롤러 : 요청을 처리하는 존재로 뷰와 모델 사이의 중간 통신 역할. 모델에서 필요한 데이터를 처리하고, 결과 뷰 전송
[DTO (Data Trinsfer Object)]
package ch_01.day240216.mvc;
/* DTO(Data Transfer Object), VO(Value Object)
로직을 갖고 있지 않는 순수한 데이터 객체이며 속성과 그 속성에 접근하기 위한 getter, setter 메소드만 가진 클래스
*/
public class Account {
private int id; // 계좌
private String name; // 이름
private long balance; // 잔액
public Account(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getBalance() {
return balance;
}
public void setBalance(long balance) {
this.balance = balance;
}
public Account(int id, String name, long balance) {
this.id = id;
this.name = name;
this.balance = balance;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", balance=" + balance +
'}';
}
}
[ Controller ]
package ch_01.day240216.mvc;
import java.util.ArrayList;
import java.util.Scanner;
// Controller
public class AccountManager {
private ArrayList<Account> list;
private Scanner stdIn;
public AccountManager() {
list = new ArrayList<>();
stdIn = new Scanner(System.in);
}
public void makeAccount() { // 계좌 개설
Account account = new Account();
System.out.print("계좌 번호: ");
account.setId(stdIn.nextInt());
System.out.print("이름: ");
account.setName(stdIn.next());
System.out.print("입금액: ");
account.setBalance(stdIn.nextLong());
list.add(account);
System.out.println("계좌가 개설되었습니다.");
System.out.println(list.toString() + "\t");
}
public void deposit() { // 입금
System.out.print("계좌번호: ");
int id = stdIn.nextInt();
System.out.print("입금액: ");
long money = stdIn.nextLong();
// 해당 계좌 찾기
for (Account account : list) {
if (account.getId() == id) { // 동일한 계좌가 있다면
account.setBalance(money + account.getBalance());
System.out.println("입금완료 되었습니다.");
return;
}
}
System.out.println("해당 계좌번호가 존재하지 않습니다.");
}
public void withdraw() { // 출금
System.out.print("계좌번호: ");
int id = stdIn.nextInt();
System.out.print("출금액: ");
long money = stdIn.nextLong();
// 해당 계좌 찾기
for (Account account : list) {
if (account.getId() == id) { // 동일한 계좌가 있다면
if (account.getBalance() < money) {
System.out.println("잔액이 부족합니다.");
} else {
account.setBalance(account.getBalance() - money);
System.out.println("출금완료 되었습니다.");
}
return;
}
}
System.out.println("해당 계좌번호가 존재하지 않습니다.");
}
public void inquire() { // 잔액 조회
System.out.print("계좌번호: ");
int id = stdIn.nextInt();
// 해당 계좌 찾기
for (Account account : list) {
if (account.getId() == id) { // 동일한 계좌가 있다면
System.out.println(account.getId() + "\t" + account.getName() + "\t" + account.getBalance());
return;
}
}
System.out.println("해당 계좌번호가 존재하지 않습니다.");
}
public void display() { // 출력
for (Account account : list) {
System.out.println(account.getId() + "\t" + account.getName() + "\t" + account.getBalance());
}
}
}
[ View ]
package ch_01.day240216.mvc;
import java.util.Scanner;
public class AccountView {
public static void printMenu() {
System.out.println("===========MENU===========");
System.out.println("1. 계좌개설");
System.out.println("2. 입금");
System.out.println("3. 출금");
System.out.println("4. 잔액조회");
System.out.println("5. 전체출력");
System.out.println("6. 프로그램종료");
System.out.println();
}
public static void main(String[] args) {
AccountManager manager = new AccountManager();
Scanner stdIn = new Scanner(System.in);
while (true) {
printMenu();
System.out.println("선택 : ");
int choice = stdIn.nextInt();
switch (choice){
case 1:
manager.makeAccount();
break;
case 2:
manager.deposit();
break;
case 3:
manager.withdraw();
break;
case 4:
System.out.println("계좌번호\t성명\t잔액");
manager.inquire();
break;
case 5:
System.out.println("계좌번호\t성명\t금액");
manager.display();
break;
case 6:
System.out.println("종료합니다.");
stdIn.close();
return;
default:
System.out.println("잘못누르셨습니다.\n다시선택해주세요.");
break;
}
}
}
}
8. MVC 패턴 + DB 연결
- [ 디비 관련 코드 추가 ] > [ 데이터베이스에 account 테이블 추가 ]
# AccountManager.java
.
.
.
public AccountManager() {
getConnection();
list = new ArrayList<>();
stdIn = new Scanner(System.in);
}
// 디비 관련 시작
private void getConnection() { // 디비 연결 생성자에서 실행
try {
String url = "jdbc:mariadb://localhost:3306/sample";
String user = "root";
String password = "5046";
try {
Class.forName("org.mariadb.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
this.connection = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
}
.
.
.
[ makeAccount() list 주석 처리 > addAcount 추가 ]
public void makeAccount() { // 계좌 개설
Account account = new Account();
System.out.print("계좌 번호: ");
account.setId(stdIn.nextInt());
System.out.print("이름: ");
account.setName(stdIn.next());
System.out.print("입금액: ");
account.setBalance(stdIn.nextLong());
// list.add(account);
System.out.println("계좌가 개설되었습니다.");
System.out.println(list.toString() + "\t");
}
if(addAccount(account)) {
System.out.println("계좌가 개설되었습니다.");
System.out.println(list.toString() + "\t");
} else {
System.out.println("계좌 생성에 실패했습니다.");
}
}
[ isAccount, addAccount 메서드 추가 ]
private boolean isAccount(int id) { // 동일한 계좌가 있는지
int res = 0;
try {
String sql = "SELECT COUNT(*) AS cnt FROM account WHERE id = '" + id + "'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
resultSet.next();
res = resultSet.getInt("cnt");
} catch (Exception e) {
e.printStackTrace();
}
return res != 0 ? true : false;
}
private boolean addAccount(Account account) {
/* 계좌 생성 */
Statement statement = null;
if (isAccount(account.getId())) { // 계좌 생성 전에 동일한 계좌 번호가 존재하는지 확인
System.out.println(account.getId() + "계좌가 존재합니다.");
return false;
}
boolean res = false;
int cnt = 0;
try {
String sql = String.format("INSERT INTO account VALUES (%d, '%d', %d)",
account.getId(), account.getName(), account.getBalance());
statement = connection.createStatement();
cnt = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (statement != null) {
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
res = (cnt == 0) ? false : true;
return res;
}