[프로젝트] 서양수박 - day02

_bean_·2023년 3월 21일
0
post-thumbnail

오류 및 문제점

1. 에러 메시지 출력

  • 문제점: SQL 에러 발생 시 콘솔에 에러 메시지가 출력된다.
  • 해결 방안: Java 내에서 에러가 발생하는 구간의 코드를 작성한다.

if (pService.isExistList(title, singer, userNo)) {
	PlaylistView.print("이미 플레이 리스트에 존재하는 노래입니다.");
} else {
	// 로직 작성
}

2. 이메일, 생일, 성별 형식

  • 문제점: 이메일, 생일, 성별 형식을 맞춰 데이터를 삽입해야 한다.
  • 해결 방안: 정규 표현식을 이용해 데이터 삽입 전 형식에 적합한지 확인한다.
System.out.println("생일 입력 (예: 2023/01/01)");
System.out.print(">> ");
String tmpday = sc.next();
String birthPtn = "[0-9]{4}/[0-9]{2}/[0-9]{2}";
boolean birthResult = Pattern.matches(birthPtn, tmpday);
Date birthday = null;
if (birthResult) {
	birthday = DateUtil.convertToDate(tmpday);
}

String mailPtn = "[a-zA-Z0-9]+@\\w+";
boolean mailResult = Pattern.matches(mailPtn, email);

3 . 많은 확인 조건

  • 문제점: 회원가입, 회원 정보 수정에서 아이디, 이메일이 UNIQUE이기 때문에 Java에서 조건을 하나씩 확인하기 번거롭다.
  • 해결 방안: 프로시저를 생성해 SQL 내에서 조건에 따른 메시지를 반환할 수 있도록 한다.
create or replace procedure p_signup(seq_user in number,
                          userid in userlist.user_id%type,
                          userpw in userlist.user_pw%type,
                          username in userlist.user_name%type,
                          userday in userlist.user_day%type,
                          useremail in userlist.user_email%type,
                          usergender in userlist.user_gender%type,
                          message out varchar2)
is
    exist char(1):='0';
begin
    select
    case when exists(select * from userlist where user_id=userid) then '1'
         when exists(select * from userlist where user_email=useremail) then '2'
    end
    into exist
    from dual;
    
    if(exist = '1')
        then message:='이미 존재하는 아이디입니다.';
    elsif(exist = '2')
        then message:='이미 존재하는 이메일입니다.';
    else
        insert into userlist
        values (seq_user, userid, userpw, username, userday, useremail, usergender);
        message:='회원가입이 완료되었습니다.';
    end if;
end;
/

4. 노래 검색 null 출력

  • 문제점: 정확한 노래 검색 시 존재하지 않는 노래를 입력하면 null이 출력된다.
  • 해결 방안: MUSIC 객체가 null이면 출력하지 않도록 출력 조건을 추가한다.

// 변경 전
public static void print(MusicVO music) {
	System.out.println(music);	
	System.out.println();	
}

// 변경 후
public static void print(MusicVO music) {
	if (music != null) {
		System.out.println(music);
	}
	System.out.println();
}

5. 로그인 static 사용

  • 문제점: Map을 이용해 로그인 정보를 유지하니 코드가 복잡해진다.
  • 해결 방안: 클래스 상단에서 로그인 정보를 static으로 선언해 어느 메소드에서든 접근 가능하도록 한다.
// 변경 전
private static Map<Integer, String> signInAndOut(Scanner sc, UserlistService uService) {}

// 변경 후
static int userNo = 0;
static String userId = null;

private static void signInAndOut(Scanner sc) {}

6. 서비스 static 사용

  • 문제점: 메소드 이동 시 필요한 서비스를 넘겨줘야 한다.
  • 해결 방안: 클래스 상단에서 서비스를 static으로 선언해 어느 메소드에서든 접근 가능하도록 한다.
// 변경 전
private static void myPlaylist(Scanner sc, PlaylistService pService, MusicService mService) {}

// 변경 후
static MusicService mService = new MusicService();
static UserlistService uService = new UserlistService();
static PlaylistService pService = new PlaylistService();

private static void myPlaylist(Scanner sc) {}

7. 전체 노래 조회 추가

  • 문제점: 어떤 노래가 존재하는지 전체 리스트를 볼 수 없다.
  • 해결 방안: 전체 노래 조회 기능을 추가한다.

8. 콘솔 출력 형태

  • 문제점: 노래 정보 출력 시 출력 형태가 일관적이지 않다.
  • 해결 방안: 여러 코드를 도전 후 가장 괜찮은 결과를 선택한다.


진행 상황

1. 플레이 리스트 삭제

// PlaylistDAO.java
public int deletePlaylist(String title, String singer, int userno) {
	String sql = """
			delete from playlist
			where music_no=(select music_no
			    from music
			    where music_name=? and singer=?)
			and user_no=?
							""";
	conn = OracleUtil.getConnection();
	try {
		pst = conn.prepareStatement(sql);
		pst.setString(1, title);
		pst.setString(2, singer);
		pst.setInt(3, userno);
		resultCount = pst.executeUpdate();
	} catch (SQLException e) {
		resultCount = -1;
		e.printStackTrace();
	} finally {
		OracleUtil.dbDisconnect(null, pst, conn);
	}
	return resultCount;
}

// PlaylistService.java
public String deletePlaylist(String title, String singer, int userno) {
	int cnt = playlistDao.deletePlaylist(title, singer, userno);
	return cnt > 0 ? "플레이 리스트에서 삭제되었습니다." : "플레이 리스트에서 삭제 실패하였습니다.";
}

2. 로그인

// UserlistDAO.java
public int signin(String userid, String userpw) {
	String sql = """
			select user_no
			from userlist
			where user_id=? and user_pw=?
			""";
            
	int user = 0;
	conn = OracleUtil.getConnection();
	try {
		pst = conn.prepareStatement(sql);
		pst.setString(1, userid);
		pst.setString(2, userpw);
		rs = pst.executeQuery();

		while (rs.next()) {
			user = rs.getInt("user_no");
		}
	} catch (SQLException e) {
		e.printStackTrace();
	} finally {
		OracleUtil.dbDisconnect(rs, pst, conn);
	}

	return user;
}

// UserlistService.java
public int signin(String userid, String userpw) {
	return userDao.signin(userid, userpw);
}

3. 회원가입

// UserlistDAO.java
public String signup(String user_id, String user_pw, String user_name, Date user_day, String user_email,
			char user_gender) {
	String sql = "{call p_signup(seq_user.nextval, ?, ?, ?, ?, ?, ?, ?)}";
	String message = null;

	conn = OracleUtil.getConnection();
	try {
		cst = conn.prepareCall(sql);
		cst.setString(1, user_id);
		cst.setString(2, user_pw);
		cst.setString(3, user_name);
		cst.setDate(4, user_day);
		cst.setString(5, user_email);
		cst.setString(6, Character.toString(user_gender));
		cst.registerOutParameter(7, Types.VARCHAR);
		cst.execute();

		message = cst.getString(7);
	} catch (SQLException e) {
		e.printStackTrace();
	} finally {
		OracleUtil.dbDisconnect(null, cst, conn);
	}
	return message;
}

// UserlistService.java
public String signup(String user_id, String user_pw, String user_name, Date user_day, String user_email,
		char user_gender) {
	return userDao.signup(user_id, user_pw, user_name, user_day, user_email, user_gender);
}

4. 탈퇴

// UserlistDAO.java
public int quitUser(int userno) {
	String sql = "delete from userlist where user_no=?";

	try {
		conn = OracleUtil.getConnection();
		pst = conn.prepareStatement(sql);
		pst.setInt(1, userno);
		resultCount = pst.executeUpdate();

	} catch (SQLException e) {
		resultCount = -1;
		e.printStackTrace();
	} finally {
		OracleUtil.dbDisconnect(null, st, conn);
	}

	return resultCount;
}

// UserlistService.java
public String quitUser(int userno) {
	int result = userDao.quitUser(userno);
	return result > 0 ? "회원 탈퇴하였습니다." : "회원 탈퇴에 실패하였습니다.";
}

5. 연도별 차트

// MusicDAO.java
public List<Map<MusicVO, Integer>> selectYearChart(int ranking, int year) {
	String sql = """
			select rownum, music_name, singer, release_date, sorted.개수
			from music, (select music_no, count(*) 개수
			    from music join playlist using(music_no)
			    where to_char(release_date, 'yyyy')=?
			    group by music_no, music_name
			    order by 개수 desc, music_name asc) sorted
			where sorted.music_no=music.music_no
			and rownum <= ?
				""";
	List<Map<MusicVO, Integer>> musiclist = new ArrayList<>();
	conn = OracleUtil.getConnection();
	try {
		pst = conn.prepareStatement(sql);
		pst.setInt(1, year);
		pst.setInt(2, ranking);
		rs = pst.executeQuery();

		while (rs.next()) {
			Map<MusicVO, Integer> music = makeChart(rs);
			musiclist.add(music);
		}
	} catch (SQLException e) {
		e.printStackTrace();
	} finally {
		OracleUtil.dbDisconnect(rs, pst, conn);
	}

	return musiclist;
}

// MusicService.java
public List<Map<MusicVO, Integer>> selectYearChart(int ranking, int year) {
	return musicDao.selectYearChart(ranking, year);
}

6. 전체적인 로직

while (true) {
	String select;
	if (userNo == 0) {
		System.out.println("<< 서양 수박♪♬ >>");
		System.out.println("1. 인기 차트 | 2. 노래 검색 | 3. 로그인&회원가입 | exit. 프로그램 종료");
		System.out.println("=============================================================");
		System.out.print(">> ");
		select = sc.next();

		if (select.equals("exit")) {
			System.out.println("프로그램을 종료합니다.");
			break;
		}

		switch (select) {
		case "1": {
			showChart(sc);
			break;
		}
		case "2": {
			searchMusic(sc);
			break;
		}
		case "3": {
			signInAndOut(sc);
			break;
		}
		default:
			System.out.println("올바른 번호를 선택하세요");
			break;
		}
	} else {
		System.out.println("<< " + userId + "님의 서양 수박♪♬ >>");
		System.out.println("1. 인기 차트 | 2. 노래 검색 | 3. 플레이리스트 | 4. 마이페이지 | exit. 프로그램 종료");
		System.out.println("========================================================================");
		System.out.print(">> ");
		select = sc.next();

		if (select.equals("exit")) {
			System.out.println("프로그램을 종료합니다.");
			break;
		}

		switch (select) {
		case "1": {
			showChart(sc);
			break;
		}
		case "2": {
			searchMusic(sc);
			break;
		}
		case "3": {
			myPlaylist(sc);
			break;
		}
		case "4": {
			mypage(sc);
			break;
		}
		default:
			System.out.println("올바른 번호를 선택하세요");
			break;
		}
	}
}
profile
어쩌다 풀스택 :3

0개의 댓글