Statement
Connection 클래스의 createStatement() 메소드를 호출하여 얻어지며 생성 된 Statement 인스턴스로
SQL 질의문을 String 에 담아 인자로 전달하여 executeQuery() 메소드를 호출하여 SQL 질의 수행
이전 포스팅과 동일하게 커넥션 생성과 자원반납은 JDBCTemplate 클래스에 작성하여 메소드 호출하여 수행한다.
(JDBCTemplate 클래스 코드는 아래 확인 가능)
Statement 는 쿼리문을 저장하고 실행하는 기능을 하는 용도의 인터페이스로
사용법을 알아보자.
Connection con = getConnection();
/* 쿼리문을 저장하고 실행하는 기능을 하는 용도의 인터페이스 */
Statement stmt = null;
/* select 결과 집합을 받아올 용도의 인터페이스 */
ResultSet rset = null;
try {
/* Connection 인스턴스를 통해 Statement 인스턴스 생성 */
stmt = con.createStatement();
rset = stmt.executeQuery("SELECT EMP_ID, EMP_NAME FROM EMPLOYEE");
while (rset.next()) {
System.out.println(rset.getString("EMP_ID")
+ ", " + rset.getString("EMP_NAME"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(stmt);
close(con);
}
}
1. Connection 인스턴스를 통해 Statement 인스턴스 생성
stmt = con.createStatement();
2. ResultSet 에 executeQuery() 메소드를 호출하여 SQL 질의 수행
rset = stmt.executeQuery(/*쿼리문*/ "SELECT EMP_ID, EMP_NAME FROM EMPLOYEE");
이 때, 쿼리문을 직접 executeQuery("쿼리") 로 작성 할 수도 있지만, 쿼리문을 String 래퍼런스 변수에 담아
변수인 query를 전달하는 방법도 있다. 더 가독성이 좋아질 수 있음.
String query = "SELECT EMP_ID, EMP_NAME FROM EMPLOYEE";
rset = stmt.executeQuery(query);
그리고, 이 쿼리문을 XML 파일에 작성하여 불러오는 방식도 있는데 이는 다음 포스팅에 이어 작성하기로 한다.
3. 결과 값이 여러 행일 경우 while문, 한 개의 행일 때 if문으로 rset.next() 메소드로 true일 때
rset.getString("컬럼명")으로 결과 값을 추출할 수 있다.
while (rset.next()) {
System.out.println(rset.getString("EMP_ID")
+ ", " + rset.getString("EMP_NAME"));
}
ResultSet
select 결과 집합을 받아올 용도의 인터페이스이다.
SELECT 문을 사용한 질의 성공 시 ResultSet 을 반환한다.
SQL 질의문에 의해 생성 된 테이블을 담고 있으며 커서로 특정 행에 대한 참조 조작을 수행한다.
String id = rset.getString ("ID");
String pwd = rset .getString ("PWD"); //혹은 2 라고 작성해도 됨. 두번째 컬럼이라는 뜻
Statment 생성과 SQL 질의 작성 순서를 다시 한번 확인해본다.
1. Connection 생성
2. Statement 생성
3. excuteQuery() 로 쿼리문을 실행하고 결과를 ResultSet으로 반환받음
4. ResultSet에 담긴 결과 값을 컬럼 이름을 이용해 꺼내오기
5. finally 사용한 자원 반납
/* 1. Connection 생성 */
Connection con = getConnection();
Statement stmt = null;
ResultSet rset = null;
try {
/* 2. Statement 생성 */
stmt = con.createStatement();
String empid = "207";
String query = "SELECT EMP_ID, EMP_NAME FROM EMPLOYEE WHERE EMP_ID = '" + empid + "'";
/* 3. excuteQuery() 로 쿼리문을 실행하고 결과를 ResultSet으로 반환받음 */
rset = stmt.executeQuery(query);
/* 4. ResultSet에 담긴 결과 값을 컬럼 이름을 이용해 꺼내오기 */
if (rset.next()) {
/* next() : ResultSet의 커서 위치를 하나 내리면서
* 행이 존재하면 true, 존재하지 않으면 false을 반환 */
System.out.println(rset.getString("EMP_ID") + ", " + rset.getString("EMP_NAME"));
} else {
System.out.println("조회하는 사원이 없습니다.");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
/* 5. 사용한 자원 반납 */
close(rset);
close(stmt);
close(con);
}
next() : ResultSet의 커서 위치를 하나 내리면서 행이 존재하면 true, 존재하지 않으면 false을 반환
결과값이 여러 행일 때 각 행의 정보를 ArrayList로 담는 방법
Connection con = getConnection();
Statement stmt = null;
ResultSet rset = null;
/* 한 행의 정보를 담을 DTO*/
EmployeeDTO row = null;
/* 여러 DTO를 하나의 인스턴스로 묶기 위한 List*/
List<EmployeeDTO> empList = null;
String query = "SELECT * FROM EMPLOYEE";
try {
stmt = con.createStatement();
rset = stmt.executeQuery(query);
empList = new ArrayList<>();
while(rset.next()) {
row = new EmployeeDTO();
row.setEmpId(rset.getString("EMP_ID"));
row.setEmpName(rset.getString("EMP_NAME"));
row.setEmpNo(rset.getString("EMP_NO"));
row.setEmail(rset.getString("EMAIL"));
row.setPhone(rset.getString("PHONE"));
row.setDeptCode(rset.getString("DEPT_CODE"));
row.setJobCode(rset.getString("JOB_CODE"));
row.setSalLevel(rset.getString("SAL_LEVEL"));
row.setSalary(rset.getInt("SALARY"));
row.setBonus(rset.getDouble("BONUS"));
row.setManagerId(rset.getString("MANAGER_ID"));
row.setHireDate(rset.getDate("HIRE_DATE"));
row.setEntDate(rset.getDate("ENT_DATE"));
row.setEntYn(rset.getString("ENT_YN"));
empList.add(row);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(stmt);
close(con);
}
for(EmployeeDTO emp : empList) {
System.out.println(emp);
}
}
JDBCTemplate 코드
1. .ProPerties 파일에서 driver연결 정보 읽어오기
2. Class.forName() 메소드로 커넥션 생성
3. getConnection() 메소드로 인스턴스 생성
4. 자원 반납을 finally에 작성하면 메인 클래스에서 호출과 동시에 연결이 끊기기 때문에
메인클래스에서 모든 db연동이 끝난 뒤 close()로 호출할 수 있도록 따로 메소드를 작성한다.
public class JDBCTemplate {
public static Connection getConnection() {
/* Connection 레퍼런스 변수 생성 */
Connection con = null;
Properties prop = new Properties();
try {
/* .ProPerties 파일에서 driver, url 정보 읽어오기 */
prop.load(new FileReader("config/connection-info.properties"));
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
/* DriverManager : JDBC드라이버를 통해 커넥션을 만드는 역할 forName()를 통해 생성 */
Class.forName(driver);
/* getConnection() 메소드로 인스턴스 생성 */
con = DriverManager.getConnection(url, prop);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} // 여기에 finally로 close() 하면 메소드 호출과 동시에 close()되버림.
// 따로 메소드 작성하여 닫아줘야 할 때 메소드 호출할 수 있도록 함
return con;
}
/* close(con) 메소드 생성 */
public static void close(Connection con) {
try {
if (con != null && !con.isClosed()) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/* close(stmt) 메소드 생성 */
public static void close(Statement stmt) {
try {
if (stmt != null && !stmt.isClosed()) {
stmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/* close(rset) 메소드 생성 */
public static void close(ResultSet rset) {
try {
if (rset != null && !rset.isClosed()) {
rset.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
'백엔드 과정 > jdbc' 카테고리의 다른 글
[JDBC] 연습문제1. DB테이블에서 같은 성을 가진 사원 정보 조회하기 (0) | 2022.02.03 |
---|---|
[JDBC] PreparedStatement (0) | 2022.02.03 |
[JDBC] Connection 생성하기 (0) | 2022.02.03 |
[JDBC] DriverManager 란? (0) | 2022.02.03 |
[JDBC] 개발환경 구축 (0) | 2022.02.03 |