Just Do IT!

Java+MySQL 이용한 자바 콘솔 미니 프로젝트 회고 본문

프로젝트

Java+MySQL 이용한 자바 콘솔 미니 프로젝트 회고

MOON달 2024. 8. 5. 17:48
728x90

KOSTA에서 공부를 하면서, 너무 빠르게 진도를 나가다보니 복습의 중요성을 너무너무 잘 느끼게 되었다.

물론 수업이 부족하다는 뜻이 아니라, 배우는 양이 많다는 뜻!

그래서 쉬는 기간을 이용하여 간단하게 프로젝트를 만들어보면서 배웠던 걸 복습해보기로 했다.

 

java와 mySQL을 사용한 간단한 콘솔 프로젝트이다.

기획은 짬짬히 해서 한 2~3일 정도 하였고, 나름대로 노션에 기획안도 적어봤었다.

그리고 database를 만들기 위해 이전에 수업에서 했었던 SNS 프로그래밍도 참고해서 만들었다.

 

자세한 기획과 기능 구현한 것들은 깃허브 레파지토리에서 볼 수 있다.

https://github.com/seoyeon-jung/SLibrary-java

 

GitHub - seoyeon-jung/SLibrary-java: Java, MySQL을 이용한 console 프로그램입니다.

Java, MySQL을 이용한 console 프로그램입니다. Contribute to seoyeon-jung/SLibrary-java development by creating an account on GitHub.

github.com

 

 

 

 

엔티티 관계도

mysql workbench에서 sql문을 작성해서 db를 만들었고,

dbeaver에서 추가되는 걸 바로바로 확인했다. 사실 이건 다 학원에서 배운 그대로이다 ㅋㅋㅋ

erd도 생성해보고 싶었는데, 우선은 기능 구현을 해보고 싶어서 다음에 기회가 되면 해보는 걸로.

 

이미 book table에 20개의 책 정보를 넣었기 때문에 진짜 도서관처럼 되도록 했다.

yes24에서 베스트 책 중에 문제집을 제외하고 넣었는데 나름대로 여러 분야의 책이 담겨서 좋았다.

출판사를 넣는 걸 까먹었는데...그냥 그대로 진행했다 ㅋㅋㅋ

 

 

 

 

로그인 구현해보기

 

이번에 새롭게 배우지 않은 걸 시도해본 것이 바로 '로그인' 기능이었다.

사실 로그인이라고 하기는 좀 민망하긴 하지만...

 

DB에 email, password를 찾아서 일치하는 사용자의 name을 출력하면서 로그인을 성공했음을 출력하면 된다.

사실은 뭐 다른 로직이 있을까 고민해봤는데, 비밀번호를 암호화한 것도 아니고 그냥 sql과 java를 연동해보는 간단한 프로젝트이기 때문에 간단히 비교하는 것으로 끝났다.

 

회원가입이랑 비슷해서 고민은 좀 길었지만 금방 간단하게 구현했다.

콘솔에, 회원가입 혹은 로그인을 해야만 도서관 메인 메뉴로 넘어가도록 했기 때문에 로그인은 필수였다.

 

 

 

 

로그인 했음을 보여주기

 

아무래도 로그인을 한 뒤에, 로그인을 했음을 증명해야 다음이 가능했다.

그런데 뭐 어떤 식으로 인증을 해야 할지 몰랐는데 그냥 로그인한 사용자 객체를 null로 지정한 다음에 로그인하거나 회원가입한 경우에 해당 객체에 정보를 추가하는 것으로 했다.

 

// 현재 로그인한 사용자 객체 저장
private User loggedInUser = null;

 

이런식으로 추가해주었고,

로그인과 회원가입에 추가해주었다.

 

	// UserService.java
    
    // 회원 가입
	public void signUpUser() throws Exception {
		System.out.println("\n ========== 회원가입 ==========");
		String name = getInput("이름", true);
		String email = getInput("이메일", true);
		String password = getInput("비밀번호", true);

		// DB에 저장
		User newUser = new User(0, name, email, password, null, null, null);
		int result = userDAO.addUser(newUser);
		if (result > 0) {
			// 회원가입 성공 시 해당 유저를 로그인한 사용자로 지정
			loggedInUser = newUser;
			System.out.println("\n" + newUser.getName() + "님 안녕하세요!");
		} else {
			System.out.println("회원가입에 실패했습니다, 다시 시도해주세요.");
		}
	}

	// 로그인
	public void loginUser() throws Exception {
		System.out.println("\n ========== 로그인 ==========");
		String email = getInput("이메일", true);
		String password = getInput("비밀번호", true);

		// DB에 저장
		User user = userDAO.login(email, password);
		if (user != null) {
			// 로그인 성공 시 현재 로그인한 사용자 저장
			loggedInUser = user;
			System.out.println("\n" + user.getName() + "님 안녕하세요!");
		} else {
			System.out.println("로그인에 실패했습니다. 다시 시도해주세요.");
		}
	}

 

그리고 로그인한 유저를 반환한 다음에,

Book 관련 메소드를 구현할 때 사용해주었다.

	// 로그인한 유저 반환
	public User getLoggedInUser() {
		return loggedInUser;
	}

 

이런식으로!

 

그리고,

이걸 이용해서 로그인했음을 알게하고 해당 유저가 책을 대출하고, 반납하고, 그리고 유저 정보를 변경할 수 있도록 해주었다.

 

 

// BookService.java

	private UserService us;

	public BookService(UserService us) {
		this.us = us;
	}

 

이렇게 Book 관련해서도 로그인한 유저가 필수로 사용되므로,

인스턴스를 생성해서 사용해주었다.

 

간단하게 아래 코드를 참고해서 설명해보자면,

책을 대출할 때는 대출하는 사람이 누구인지, userId가 필요하다. 그걸 userService에 구현했던 getLoggedInUser()를 통해서 해당 유저가 누구인지 구하는 것이다. 

	// 책 대출하기
	public void borrowBook() throws Exception {
		if (us.getLoggedInUser() == null) {
			System.out.println("로그인 후에 책을 대출할 수 있습니다.");
			return;
		}

		System.out.println("\n ========== 책 대출하기 ==========");
		printBookList(); // 우선 대출 가능한 책 목록 출력

		int bookId = Integer.parseInt(getInput("책 ID", true));
		int userId = us.getLoggedInUser().getId();

		boolean success = bookDAO.borrowBook(bookId, userId);
		if (success) {
			System.out.println("책을 성공적으로 대출하였습니다.");
		} else {
			System.out.println("책을 대출할 수 없습니다. 다시 한번 시도해주세요.");
		}
	}

 

 

그러면, BookDAO에서

	// 책 대출하기
	public boolean borrowBook(int bookId, int userId) throws Exception {
		// 1. 책의 대출 상태 확인
		String checkSQL = "SELECT available FROM book WHERE id = ?";
		try (Connection conn = DBConnection.getConnection();
				PreparedStatement pstmt = conn.prepareStatement(checkSQL)) {
			pstmt.setInt(1, bookId);
			ResultSet rs = pstmt.executeQuery();

			if (rs.next() && rs.getBoolean("available")) {
				// 2. 책의 대출 상태 변경
				String updateBookSQL = "UPDATE book SET available = false WHERE id = ?";
				try (PreparedStatement pstmtUpdate = conn.prepareStatement(updateBookSQL)) {
					pstmtUpdate.setInt(1, bookId);
					int result = pstmtUpdate.executeUpdate();

					if (result > 0) {
						// 3. 대출 기록을 loan 테이블에 추가
						String insertLoanSQL = "INSERT INTO loan (member_id, book_id, loan_date, return_date) VALUES (?, ?, NOW(), DATE_ADD(NOW(), INTERVAL 14 DAY))";
						try (PreparedStatement pstmtInsertLoan = conn.prepareStatement(insertLoanSQL)) {
							pstmtInsertLoan.setInt(1, userId);
							pstmtInsertLoan.setInt(2, bookId);
							pstmtInsertLoan.executeUpdate();
						}
						return true;
					}
				}
			}
			return false;
		}
	}

 

이런식으로 sql문을 작성하고, book table에 대출되었음을 update하고,

loan table에 userId가 bookId를 대출했다는 row를 추가해주면 된다.

 

처음에는 이 관계를 생각하는게 힘들어서 database를 구현하는 게 꽤나 오래 걸렸는데, 그래도 오늘 안에 다 구현해서 다행이다.

 

 

 

 

 

 

 

 

 

 

 

 

최종 회고

 

원래의 계획은 토요일에 시작해 월요일에 끝내는 것이었는데, 어쩌다 보니 일요일-월요일 이틀 내에 구현했다.

토요일은 쉬었기 때문...아무튼! 그래도 저번주에 기획한 대로 기능을 구현할 수 있어서 좋았다.

 

이제는 jsp를 배우면서 웹 개발로 넘어갔지만, 그 전에 이 흐름을 잘 이해해보기 위해서 나름대로 기획도 배웠던 거랑 다르게 해보고 여러 기능을 추가해보았는데, 완성해서 다행이다. 완전히 다 이해했다고 자신있기 이야기하기에는 좀 민망하지만, 그래도 수업할 때 실습한 것 + 오늘 프로젝트 한것 합쳐서 흐름을 이해하긴 한 것 같다.

 

아무래도 프론트를 맡아서 진행했을 때는 결과가 바로바로 보이기도 하고, 콘솔을 잘 이용하지 않았었다. 콘솔을 이용하는 경우는...에러가 났을 때 참고하는 용도? 그랬는데 java만 배워서 지금은 터미널에서만 확인할 수 있기에 콘솔을 활용하는 기회가 되었다. 사실 일요일에는 sql문을 짜느라 시간을 다 보냈고, 오늘 거의 다 완성했는데 너무 재밌었다!

 

작은 프로젝트이지만 이전에 내가 진행했떤 모든 프로젝트와 전혀 다른 흐름이었고, database를 직접 만들어본 것도 처음이어서 너무너무 즐거운 경험이었고, 수업을 따라가기만 하다가 잠시 멈춰서 직접 프로젝트를 해보는 계기가 되었다.

내 체력이 받쳐준다면 매주 주말에 작게나마 프로젝트를 만들어보고 싶은데 그건 진짜 안될것 같고....

시간을 아예 빼서 복습 시간을 만들어야겠다. 맨날 해야지, 하고 잘 안되는 것 같다.

 

잠시 사담으로 흘러가긴 했지만,

이번 프로젝트 정말정말 재밌게 했다. 거의 몇 시간을 움직이지 않고 작성한듯 하다...ㅋㅋㅋㅋㅋㅋㅋ

 

다음에도 작은 프로젝트 회고글로 돌아와야지...!