오류 및 문제점
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. 플레이 리스트 삭제
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;
}
public String deletePlaylist(String title, String singer, int userno) {
int cnt = playlistDao.deletePlaylist(title, singer, userno);
return cnt > 0 ? "플레이 리스트에서 삭제되었습니다." : "플레이 리스트에서 삭제 실패하였습니다.";
}
2. 로그인
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;
}
public int signin(String userid, String userpw) {
return userDao.signin(userid, userpw);
}
3. 회원가입
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;
}
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. 탈퇴
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;
}
public String quitUser(int userno) {
int result = userDao.quitUser(userno);
return result > 0 ? "회원 탈퇴하였습니다." : "회원 탈퇴에 실패하였습니다.";
}
5. 연도별 차트
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;
}
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;
}
}
}