preparedStatement - 미리 준비되어진 Statement
java.sql. Statement 와 동일한 기능을 제공한다.
차이점이 있다면 PreparedStatement 는 SQL 쿼리의 틀을 미리 생성해 놓고 값을 나중에 지정한다는 것
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCEx08 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String url = "jdbc:mysql://localhost:3306/sample";
String user = "root";
String password = "123456";
Connection conn = null;
PreparedStatement pstmt = null;
try {
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
// ? 는 따옴표 안붙음
String sql = "insert into dept2 values (?, ?, ?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "10");
pstmt.setString(2, "개발");
pstmt.setString(3, "서울");
int result = pstmt.executeUpdate();
System.out.println("실행 완료" + result);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} finally {
if(pstmt != null) try {pstmt.close();} catch(SQLException e) {}
if(conn != null) try {conn.close();} catch(SQLException e) {}
}
}
}
update 구문 만들기
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCEx09 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String url = "jdbc:mysql://localhost:3306/sample";
String user = "root";
String password = "123456";
Connection conn = null;
PreparedStatement pstmt = null;
try {
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
// 컬럼명은 ?로 할 수 없다. / 순서는 앞에부터
String sql = "update dept2 set loc = ? where deptno = ?";
pstmt = conn.prepareStatement(sql);
// 순서대로 값 변경해준다.
pstmt.setString(1, "부산");
pstmt.setString(2, "10");
int result = pstmt.executeUpdate();
System.out.println("실행 완료" + result);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} finally {
if(pstmt != null) try {pstmt.close();} catch(SQLException e) {}
if(conn != null) try {conn.close();} catch(SQLException e) {}
}
}
}
delete
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCEx10 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String url = "jdbc:mysql://localhost:3306/sample";
String user = "root";
String password = "123456";
Connection conn = null;
PreparedStatement pstmt = null;
try {
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
// 컬럼명은 ?로 할 수 없다. / 순서는 앞에부터
String sql = "delete from dept2 where deptno = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "10");
int result = pstmt.executeUpdate();
System.out.println("실행 완료" + result);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} finally {
if(pstmt != null) try {pstmt.close();} catch(SQLException e) {}
if(conn != null) try {conn.close();} catch(SQLException e) {}
}
}
}
select
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCEx11 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String url = "jdbc:mysql://localhost:3306/sample";
String user = "root";
String password = "123456";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
// 컬럼명은 ?로 할 수 없다. / 순서는 앞에부터
String sql = "Select empno, ename, sal, job from emp where deptno = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "20");
rs = pstmt.executeQuery();
while(rs.next()) {
System.out.printf("%s %s %s %s%n", rs.getString("empno"), rs.getString("ename"), rs.getString("sal"), rs.getString("job"));
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} finally {
if(rs != null) try {rs.close();} catch(SQLException e) {}
if(pstmt != null) try {pstmt.close();} catch(SQLException e) {}
if(conn != null) try {conn.close();} catch(SQLException e) {}
}
}
}
s로 시작하는 사원이름 출력
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCEx11 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String url = "jdbc:mysql://localhost:3306/sample";
String user = "root";
String password = "123456";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
// 컬럼명은 ?로 할 수 없다. / 순서는 앞에부터
String sql = "Select empno, ename, sal, job from emp where ename like ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "s%");
rs = pstmt.executeQuery();
while(rs.next()) {
System.out.printf("%s %s %s %s%n", rs.getString("empno"), rs.getString("ename"), rs.getString("sal"), rs.getString("job"));
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} finally {
if(rs != null) try {rs.close();} catch(SQLException e) {}
if(pstmt != null) try {pstmt.close();} catch(SQLException e) {}
if(conn != null) try {conn.close();} catch(SQLException e) {}
}
}
}
sample X
database 명 : project
user / password : project / 1234
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCEx12 {
public static void main(String[] args) {
// TODO Auto-generated method stub
BufferedReader br = null;
String url = "jdbc:mysql://localhost:3306/project";
String user = "project";
String password = "1234";
Connection conn = null;
PreparedStatement pstmt = null;
int i=0;
try {
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
br = new BufferedReader(new FileReader("./zipcode_seoul_utf8_type2.csv"));
String str = "";
while ((str = br.readLine()) != null) {
String[] arrZipcode = str.split(",");
String sql = "insert into zipcode values(?, ?, ?, ?, ?, ?, ?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, arrZipcode[0]);
pstmt.setString(2, arrZipcode[1]);
pstmt.setString(3, arrZipcode[2]);
pstmt.setString(4, arrZipcode[3]);
pstmt.setString(5, arrZipcode[4]);
pstmt.setString(6, arrZipcode[5]);
pstmt.setString(7, arrZipcode[6]);
int result = pstmt.executeUpdate();
System.out.println("실행 결과 : " + i++ );
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} finally {
if(pstmt != null) try {pstmt.close();} catch(SQLException e) {}
if(conn != null) try {conn.close();} catch(SQLException e) {}
}
}
}
실행
동이름 : 대치
[우편번호] 시도 구군 동 리 번지
동이름 : exit
프로그램 종료 ...
게시판 만들때 사용함.
select 문을 통해서 데이터를 가져오는 경우, ResultSet 객체에 데이터를 저장해야 한다.
absolute(값) : cursor을 특정위치로 바로 이동하여 값 읽을 수 있음.
next() : Cursor를 다음 Row(행)로 이동
beforeFirst() : 1행 이전으로 올라가기 (커서의 초기화상태)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCEx13 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String url = "jdbc:mysql://localhost:3306/sample";
String user = "root";
String password = "123456";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
String sql = "select * from emp";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
rs.absolute(1);
System.out.printf("%s %s %s %s %n", rs.getString("empno"), rs.getString("ename"), rs.getString("sal"),
rs.getString("job"));
System.out.println("행번호 : " + rs.getRow());
rs.absolute(10);
System.out.printf("%s %s %s %s %n", rs.getString("empno"), rs.getString("ename"), rs.getString("sal"),
rs.getString("job"));
System.out.println("행번호 : " + rs.getRow());
// select count(*) from emp;
rs.next();
System.out.println("행번호 : " + rs.getRow());
// 1행 이전으로 올라가기 (커서의 초기화상태)
rs.beforeFirst();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} finally {
if (rs != null)
try {
rs.close();
} catch (SQLException e) {
}
if (pstmt != null)
try {
pstmt.close();
} catch (SQLException e) {
}
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
}
}
}
}
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseMetaEx01 {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/sample";
String user = "root";
String password = "123456";
Connection conn = null;
try {
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
DatabaseMetaData dmd = conn.getMetaData();
// getDatabaseProductName() : 데이터베이스 제품 이름
System.out.println(dmd.getDatabaseProductName());
// getDatabaseProductVersion() : 데이터베이스 제품 버전
System.out.println(dmd.getDatabaseProductVersion());
// getDriverName() : 드라이버 이름
System.out.println(dmd.getDriverName());
// getDriverVersion() : 드라이버 버전
System.out.println(dmd.getDriverVersion());
System.out.println(dmd.getJDBCMajorVersion() + ":" + dmd.getJDBCMinorVersion());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} finally {
if(conn != null) try {conn.close();} catch(SQLException e) {}
}
}
}
ResultSetMetaData : 메타데이터는 저장된 데이터 자체가 아니라, 해당 데이터에 대한 정보를 갖는 데이터를 의미.
ex) 데이터베이스의 소유권 또는 데이터의 크기에 관련된 정보 등이 있다면, 이러한 것을 메타데이터라고 함.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
public class ResultSetMetaEx01 {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/sample";
String user = "root";
String password = "123456";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
Class.forName("org.mariadb.jdbc.Driver");
conn = DriverManager.getConnection(url, user, password);
String sql = "select * from emp";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
// select 문을 select 한(ResultSet의 총 필드 수) 반환 컬럼의 개수 8 출력
// System.out.println(rsmd.getColumnCount());
for(int i=1; i<=rsmd.getColumnCount(); i++) {
// 컬럼의 이름 출력
System.out.println(rsmd.getColumnName(i));
// 컬럼의 데이터 타입
System.out.println(rsmd.getColumnTypeName(i));
// 컬럼의 정도
System.out.println(rsmd.getPrecision(i));
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("[에러] : " + e.getMessage());
} finally {
if(rs != null) try {rs.close();} catch(SQLException e) {}
if(pstmt != null) try {pstmt.close();} catch(SQLException e) {}
if(conn != null) try {conn.close();} catch(SQLException e) {}
}
}
}
데이터베이스와 연결된 커넥션을 미리 만들어서 풀(pool)속에 저장해 두고 있다가 필요할때 풀에서 가져다쓰고 다시 풀에 반환하는 기법
자바에서 DB에 직접 연결해서 처리하는 경우(JDBC) 드라이버 로드하고 커넥션 객체를 받아와야 하는데, 그러면 매번 사용자가 요청을 할 때마다 드라이버를 로드하고 커넥션 객체 생성하여 연결하고 종료하기때문에 매우 비효율적.
이러한 문제를 해결하기 위해서 커넥션풀(DBCP)을 사용.
프로세스만드는 클래스 ProcessBuilder
Foreground Process
일반적인 애플리케이션(앱 / 응용프로그램)
Background Process
서버계열을 많이 사용 / 화면이 없다.
윈도우가 관리하는 프로그램은 서비스라고 한다.
실행흐름 확인은
작업관리자에서 확인
스레드는 프로세스 동작의 최소 단위.
모든 프로세스는 하나 이상의 스레드로 구성된다.
메인스레드가 main()메서드를 실행하면서 애플리케이션이 구동됨.
쓰레드의 실행순서는 OS의 스케줄러가 작성한 스케쥴에 의해 결정된다.
cpu를 중심으로
스레드 장점
1. cpu 사용률 향상
2. 작업의 분리로 응답성 향상
3. 자원의 공유를 통한 효율성 증대
스레드 단점
1. 컨텍스트 스위칭 비용 발생
2. 스레드 제어의 어려움
main에서 변수.run()을 호출하는 것은 생성된 쓰레드를 실행시키는 것이 아니라 단순히 클래스에 선언된 메서드를 호출하는 것일 뿐.
Go 클래스 생성
Come 클래스 생성
Main에서 순차처리 실행
변수.run()을 호출하는 것은 생성된 쓰레드를 실행시키는 것이 아니라 단순히 클래스에 선언된 메서드를 호출하는 것일 뿐.
순차처리와는 다르게 스레드를 상속받고, 스레드의 run() 메서드를 오버라이딩하여 실행 멀티 스레드 실행으로 실행시킴.
start()로 호출해야 스레드가 실행이 된다.
start()가 호출됐다고 해서 바로 실행되는 것이 아니라, 실행 대기 상태에 있다가 차례가 되면 실행됨. (실행대기중인 스레드가 하나도 없으면 곧바로 실행상태가 됨)
쓰레드의 실행순서는 OS의 스케줄러가 작성한 스케쥴에 의해 결정된다.
스레드를 상속받는 Go 클래스 생성 / 메서드 오버라이딩
스레드를 상속받는 Come 클래스 생성 / 메서드 오버라이딩
main에서 병렬처리로 출력 / 변수.start() : 스레드한테 실행시켜달라고 위임시킴
순차적이 아닌 섞여서 병렬로 출력
Runnable 인터페이스는 구현할 메소드가 run() 하나 뿐인 함수형 인터페이스.
따라서 Java8에서 도입된 람다를 이용해서 좀 더 깔끔하게 구현할 수도 있다.
package pack4;
public class MainEx01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=1; i<=10; i++) {
System.out.println("go : " + i);
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 1; i <= 10; i++) {
System.out.println("come : " + i);
}
}
});
System.out.println("시작");
t1.start();
t2.start();
System.out.println("끝");
}
}
람다식으로 코드 변경
package pack4;
public class MainEx01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread t1 = new Thread (() -> {
// TODO Auto-generated method stub
for(int i=1; i<=10; i++) {
System.out.println("go : " + i);
}
});
Thread t2 = new Thread(() -> {
// TODO Auto-generated method stub
for (int i = 1; i <= 10; i++) {
System.out.println("come : " + i);
}
});
System.out.println("시작");
t1.start();
t2.start();
System.out.println("끝");
}
}
멀티스레드의 순서를 정하는 것을 스레드 스케줄링(thread scheduling)이라고 한다.
쓰레드의 실행순서는 OS의 스케줄러가 작성한 스케쥴에 의해 결정된다.
우선순위의 범위는 1 ~ 10이며 숫자가 높을수록 우선순위가 높다.
스레드 우선순위는 스레드를 생성한 스레드로부터 상속받는다.
ex) main메서드를 수행하는 스레드의 우선순위가 5라면 main메서드 내에서 생성하는 스레드의 우선순위는 자동적으로 5가 된다.
스레드를 상속받는 클래스 생성
스레드를 상속받는 클래스 생성
Main에서 실행
t1의 우선순위를 높게 주었지만 그렇다고 무조건 우선순위가 높은쪽이 먼저 출력이 되는것은 아니다.
출력결과 우선순위와 클래스의 메서드들의 출력값이 섞여서 나온다.
package pack5;
public class PriorityTest {
static class MessengerThread extends Thread {
public MessengerThread(String name) {
super(name);
}
public void run() {
for(int i=0; i<30; i++) {
System.out.print(this.getName());
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread fThread = new MessengerThread("F");
Thread tThread = new MessengerThread("T");
fThread.setPriority(Thread.MIN_PRIORITY);
tThread.setPriority(Thread.MAX_PRIORITY);
fThread.start();
tThread.start();
}
}
잠시 멈추고싶을때 사용하는 메서드
Thread.sleep() 은 예외처리를 해줘야한다.
main에서 실행 / sleep()으로 1초 멈춰서 1초 있다가 구구단 결과 출력됨
2주 뒤 개인 프로젝트