[ Java ] 코드 리뷰 :: DB를 가변배열에 읽어오기
✅ 구현해본 버전
- 기본 배열을 가변배열화 해서 데이터 개수만큼 배열을 늘려나가기
- ArrayList를 사용하기
#️⃣ DB를 담을 Member 클래스 정의
import java.util.ArrayList;
public class Member {
private int id;
private String name;
private int age;
public Member() {
super();
}
public Member(int id, String name, int age) { //getter, setter만 했다가 생성자도 추가해봄
this.id = id;
this.name=name;
this.age=age;
}
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
#️⃣ 1) 기본배열을 가변배열화 하기
1차.
public class Program0810 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
System.out.println("[ 회원 검색 프로그램 ]");
System.out.println("검색할 이름 : ");
String searchWord = "";
// 검색어 입력
Scanner scan = new Scanner(System.in);
searchWord = scan.next();
System.out.println();
// 검색어를 이용해서 데이터를 가져오기 (변수를 쿼리문에 끼워넣기)
String url = "url";
String sql = "SELECT ID,NAME,AGE FROM MEMBER WHERE NAME LIKE '%" + searchWord + "%'";
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection(url, "ID", "PW");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
// 멤버클래스에 저장하기
int index = 0;
Member[] arr = new Member[1]; //최소 개수를 만들어두고 늘려나갈 예정
while(rs.next()) {
System.out.println("길이1:" +arr.length);
// 인덱스가 다 차면 새로운 배열 만들어서 옮겨주기
if(index==arr.length-1) {
Member[] tmp = new Member[arr.length+1];
// 1)새 배열로 내용 복사하기
for (int i=0; i<arr.length; i++) {
tmp[i]= arr[i];
}
// 2)객체 연결하기
arr=tmp;
System.out.println("길이2:" +arr.length);
} //if ends
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
arr[index] = new Member(id, name, age);
// arr[index].setId(id);
// arr[index].setName(name);
// arr[index].setAge(age);
index++;
} // while ends
int size =index;
// 출력하기
System.out.printf("%s\t%-10s\t%-10s\n", "ID", "이름", "나이");
for (int i = 0; i < size; i++) {
System.out.printf("%-2d\t", arr[i].getId());
System.out.printf("%-10s\t", arr[i].getName());
System.out.printf("%-10d\n", arr[i].getAge());
}
rs.close();
st.close();
con.close();
}
}
👉 원래 while(rs.next())조건 안에서 먼저 데이터를 받고, 그 후에 index가 다 차면 if문을 통해서 배열을 늘리려고 생각을 했었다. 그렇게 되면 (인덱스가 다 찼음 && 다음줄이 있는지 체크) 이 조건이 동시에 들어가야 하는데, 이때 rs.next()로 다음줄을 읽어와버리게 되므로 한줄씩 날아가게 된다. 그래서 hasNext()같은 놈이 있는지 찾아보고 한참을 고민해봤는데... 중복 조건을 쓸 필요가 없다는 생각이 퍼뜩 들어서 if문을 위로 올림.
👉 그 결과, 이미 다음값이 있는지 체크하고 while문이 시작되므로 진행에 문제는 없었다!
다만 1줄이라도 데이터가 있는 경우 처음부터 인덱스 0 == 길이-1 이 일치하므로, 멀쩡한 배열을 한번 더 생성해서 복사한다는 단점이 생긴다. 그래서 데이터 개수보다 인덱스가 하나 더 많다.
2차.
public static void main(String[] args) throws ClassNotFoundException, SQLException {
System.out.println("[ 회원 검색 프로그램 ]");
System.out.println("검색할 이름 : ");
String searchWord = "";
// 사용자 이름의 검색어를 입력하는 코드
Scanner scan = new Scanner(System.in);
searchWord = scan.next();
System.out.println();
// 검색어를 이용해서 데이터를 가져오기 (변수를 쿼리문에 끼워넣기)
String url = "url"; // 약속된 사용문장
String sql = "SELECT ID,NAME,AGE FROM MEMBER WHERE NAME LIKE '%" + searchWord + "%'";
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection(url, "id", "pw");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
// 1. 멤버클래스에 저장하기
int index = 0; // 기존배열의 인덱스
int size = 0; // 새 배열의 인덱스이자 최종 길이
Member[] arr = new Member[index];
// 데이터가 있을 시 배열 늘리기
for (int i = 0; rs.next(); i++) {
Member[] tmp = new Member[++size];
// 1)새 배열로 내용 복사하기
for (int j = 0; j < arr.length; j++) {
tmp[j] = arr[j];
}
// 2)객체 연결하기
arr = tmp;
//3) 배열에 데이터 넣기
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
arr[i] = new Member(id, name, age);
} // for ends
// 2. 출력하기
System.out.println("size"+ size);
System.out.printf("%s\t%-10s\t%-10s\n", "ID", "이름", "나이");
if (size == 0)
System.out.println("데이터가 없습니다");
else {
for (int i = 0; i < size; i++) {
System.out.printf("%-2d\t", arr[i].getId());
System.out.printf("%-10s\t", arr[i].getName());
System.out.printf("%-10d\n", arr[i].getAge());
}
}
rs.close();
st.close();
con.close();
}
👉 인덱스가 하나 더 늘어나는 문제점을 보완하기 위해 다시 짠 코드.
코드공유하면서 얘기를 나누다가 while과 조건(if)를 묶으면 결국 for문이라서 다시 정리했다.
for(int i=0; rs.next(); i++) {} 이걸 왜 생각못해서 굳이 if문으로 인덱스와 길이를 비교하려 했을까.... 덕분에 코드가 한결 간결해짐!
#️⃣ 2) ArrayList 활용하기
public class Program0811 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
System.out.println("[ 회원 검색 프로그램 ]");
System.out.println("검색할 이름 : ");
String searchWord = "";
// 사용자 이름의 검색어를 입력하는 코드
Scanner scan = new Scanner(System.in);
searchWord = scan.next();
System.out.println();
// 검색어를 이용해서 데이터를 가져오기 (변수를 쿼리문에 끼워넣기)
String url = "url";
String sql = "SELECT ID,NAME,AGE FROM MEMBER WHERE NAME LIKE '%" + searchWord + "%'";
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection(url, "ID", "PW");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
// 멤버클래스에 저장하기
ArrayList<Member> arrList = new ArrayList<Member>();
int index = 0;
while(rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
arrList.add(new Member(id,name,age));
// list[index].setId(id);
// list[index].setName(name);
// list[index].setAge(age);
index++;
}
int size =index;
// 출력하기
System.out.printf("%s\t%-10s\t%-10s\n", "ID", "이름", "나이");
for (int i = 0; i < size; i++) {
System.out.printf("%-2d\t", arrList.get(i).getId());
System.out.printf("%-10s\t", arrList.get(i).getName());
System.out.printf("%-10d\n", arrList.get(i).getAge());
}
rs.close();
st.close();
con.close();
}
}
👉 ArrayList를 사용하면 데이터를 읽어오는 족족 배열이 늘어나므로 배열 길이를 직접 늘리려는 수고를 하지 않아도 된다. 제네릭도 잠시 잊고있다가 Member[]과 다르게 ArrayList는 타입을 써줄 공간이 없구나 참 하면서 다시 리마인드 됨. 굿굿
👉 ArrayList에 값을 더할때는 add(), 값을 읽어올때는 get()을 사용한다!!! 그놈의 push, pop좀 잠시 잊어봐
👉list.add(1)로 값을 넣으므로, 아무생각없이 list.add(Member(id,name,age))로 넣었다가 오류가 뜨기에, new가 빠졌다는걸그제서야 알아챘다. new 객체를 바로 때려넣으면 되는구나 싶어서 좀 속시원했음!