23.04.04

이준영·2023년 4월 4일
0

java.sql

Connection = 접속관리
Statement = SQL / PreparedStatement = 미리 준비된 Statement (속도가 더 빠름)
Resultset = Select Return Data 관리

PreparedStatement 사용 ( insert )

Statement와 동일한 기능
PreparedStatement는 SQL 쿼리의 틀을 미리 생성해 놓고 값을 나중에 지정


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JDBCEX9 {

	public static void main(String[] args) {
		String url = "jdbc:mariadb://localhost:3306/sample";
		String user = "root";
		String password = "123456";
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		
		try {
			//Connecter 제공업체에서 알 수 있다.
			//처리 로직
			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, "30");
			pstmt.setString(2, "사회");
			pstmt.setString(3, "서울");
			
			int result = pstmt.executeUpdate(); //()에 아무것도 안넣음
			
			System.out.println("실행 완료 :" + result);
			
		} catch (ClassNotFoundException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (SQLException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if (pstmt != null)  try { pstmt.close(); } catch(SQLException e) {};
			if (conn != null)  try { conn.close(); } catch(SQLException e) {};
		}
	}

}



PreparedStatement 사용 ( update )

String sql = "update dept2 set loc = ? where deptno = ?";
pstmt = conn.prepareStatement(sql);
			
pstmt.setString(1, "부산");   --> 위에 sql에 쓴 순서대로 setString 사용
pstmt.setString(2, "30");

다른 코드는 위와 같다.



PreparedStatement 사용 ( delete )

String sql = "delete from dept2 where deptno = ?";
pstmt = conn.prepareStatement(sql);
			
pstmt.setString(1, "30");



PreparedStatement 사용 ( 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) {
		String url = "jdbc:mariadb://localhost:3306/sample";
		String user = "root";
		String password = "123456";
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			//Connecter 제공업체에서 알 수 있다.
			//처리 로직
			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, "10");
		
			
			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) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (SQLException e) {
			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로 시작하는 사원 이름 출력

다른 부분 동일

String sql = "select empno, ename, sal, job from emp where ename like ? "; --> 여긴 무조건 ?
pstmt = conn.prepareStatement(sql);
			
pstmt.setString(1, "s%");  -->여기다 s%해서 s로 시작하는 이름 출력하게 하기



응용 문제 - zipcode 주소 파일 db에 연동하기

zipcode 테이블 구성

create table zipcode (
zipcode char(7) not null,
sido varchar(4) not null,
gugun varchar(17),
dong varchar(26) not null,
ri varchar(45) not null,
bunji varchar(17) not null,
seq int(5) unsigned not null
);
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 JDBCEX9 {

	public static void main(String[] args) {
		
		BufferedReader br = null;
		
		String url = "jdbc:mariadb://localhost:3306/project";
		String user = "project";
		String password = "1234";
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		

			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 = null;
				
				while((str = br.readLine()) != null) {
					String strArr[] = str.split(",");
				
				
				String sql = "insert into zipcode values (?, ?, ?, ?, ?, ?, ?)";
				pstmt = conn.prepareStatement(sql);
				
				
				
				pstmt.setString(1, strArr[0]);
				pstmt.setString(2, strArr[1]);
				pstmt.setString(3, strArr[2]);
				pstmt.setString(4, strArr[3]);
				pstmt.setString(5, strArr[4]);
				pstmt.setString(6, strArr[5]);
				pstmt.setString(7, strArr[6]);
				
				int result = pstmt.executeUpdate();
				
				System.out.println("실행 완료 :" + result);
				}
			} catch (ClassNotFoundException e) {
				System.out.println("[에러]" + e.getMessage());
			} catch (FileNotFoundException e) {
				System.out.println("[에러]" + e.getMessage());
			} catch (SQLException e) {
				System.out.println("[에러]" + e.getMessage());
			} catch (IOException e) {
				System.out.println("[에러]" + e.getMessage());
			} finally {
				if(pstmt != null) try { pstmt.close();} catch (SQLException e) {}
				if(conn != null) try { conn.close();} catch (SQLException e) {}
				if(br != null) try { br.close();} catch (IOException e) {}
			}
	}
}
  1. 사용자 : project / database 명 project / table : zipcode로 관리자에서 생성하고 권한 부여하기(위 코드에서는 all 부여)

  2. zipcode문서를 읽을
    java.io (buffereReader / FileReader) +
    db 연결에 필요한 java.sql (Connection, PreparedStatement)
    구문을 사용하고 전부 예외처리 해주기

  3. zipcode 문서를 끝까지 읽기 위해 while문 사용하고, 그 안에 쿼리에 하나씩 넣어 줄 PreparedStatement 구문을 사용하여 zipcode의 내용을 db에 전부 insert 하기

  1. db에서 확인하기!



응용문제 - 동이름 검색하면(정확하게 말고 유사검색 가능하게) 주소 정보 나오게 하기 (exit 누르면 종료)

1. scanner로 읽기

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class JDBCEX9 {

	public static void main(String[] args) {

		String url = "jdbc:mariadb://localhost:3306/project";
		String user = "project";
		String password = "1234";
		
		Scanner sc = new Scanner(System.in);
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;

			try {
				Class.forName("org.mariadb.jdbc.Driver");
				
				conn = DriverManager.getConnection(url, user, password);
				
				String str = null;
				

				while(true) {
				System.out.println("동 입력 : ");
				String dong = sc.nextLine();
				
				String sql = "select zipcode, sido, gugun, dong, ri, bunji from zipcode where dong like ?";
				
				pstmt = conn.prepareStatement(sql);
				
				pstmt.setString(1, dong + "%");
				
				rs = pstmt.executeQuery(); 

				if(!dong.equals("exit")) {
					
				while(rs.next()) {
					System.out.printf("[%s] %s %s %s %s %s", rs.getString("zipcode"),
							rs.getString("sido"), rs.getString("gugun"), rs.getString("dong"),
							rs.getString("ri"),rs.getString("bunji"));
					System.out.println();
					}
				}
				else {
                	System.out.println("프로그램 종료");
					break;
				}
				}
			} catch (ClassNotFoundException e) {
				System.out.println("[에러]" + e.getMessage());
			} catch (SQLException e) {
				System.out.println("[에러]" + e.getMessage());
			} finally {
				if(pstmt != null) try { pstmt.close();} catch (SQLException e) {}
				if(conn != null) try { conn.close();} catch (SQLException e) {}
			}
	}
}

2. BufferedReader로 읽기

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class JDBCEX9 {

	public static void main(String[] args) {

		String url = "jdbc:mariadb://localhost:3306/project";
		String user = "project";
		String password = "1234";

		BufferedReader br = null;

		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;

		try {
			Class.forName("org.mariadb.jdbc.Driver");

			conn = DriverManager.getConnection(url, user, password);

			String str = null;

			br = new BufferedReader(new InputStreamReader(System.in));

			String dong = "";
			while (true) {
				System.out.println("동이름 : ");
				dong = br.readLine();

				String sql = "select zipcode, sido, gugun, dong, ri, bunji from zipcode where dong like ?";

				pstmt = conn.prepareStatement(sql);

				pstmt.setString(1, dong + "%");

				rs = pstmt.executeQuery();

				if (dong.equals("exit")) {
					System.out.println("프로그램 종료");
					break;
				} else {
					while (rs.next()) {
						System.out.printf("[%s] %s %s %s %s %s", rs.getString("zipcode"), rs.getString("sido"),
								rs.getString("gugun"), rs.getString("dong"), rs.getString("ri"), rs.getString("bunji"));
						System.out.println();
					}
				}
			}
		} catch (ClassNotFoundException e) {
			System.out.println("[에러]" + e.getMessage());
		} catch (SQLException e) {
			System.out.println("[에러]" + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러]" + e.getMessage());
		} finally {
			if (pstmt != null) try { pstmt.close(); } catch (SQLException e) {}
			if (conn != null) try { conn.close(); } catch (SQLException e) {}
			if (br != null) try { br.close(); } catch (IOException e) {}
		}
	}
}



ResultSet 커서 조정하기

게시판 같은 거 만들 때 응용해서 사용


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class JDBCEX12 {

	public static void main(String[] args) {
		String url = "jdbc:mariadb://localhost:3306/sample";
		String user = "root";
		String password = "123456";
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			//Connecter 제공업체에서 알 수 있다.
			//처리 로직
			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); // 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); // 13번째 행으로 가겠다.	
			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());
			
			rs.beforeFirst(); // 1행 이전으로 올라감( 커서 초기화 상태 )
			System.out.println("행번호 : " + rs.getRow());
			
		} catch (ClassNotFoundException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (SQLException e) {
			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) {};
		}
	}
}

absolute(n) -> n번째 행으로 이동
next() -> 다음 행으로 이동
beforeFirst() -> 1행 이전(0행)으로 이동, 커서 초기화 상태 만듦



데이터 베이스 기타 정보

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseMeta1 {
	public static void main(String[] args) {
		String url = "jdbc:mariadb://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();
			
			System.out.println(dmd.getDatabaseProductName());
			System.out.println(dmd.getDatabaseProductVersion());
			
			System.out.println(dmd.getDriverName());
			System.out.println(dmd.getDriverVersion());
			System.out.println(dmd.getJDBCMajorVersion() + 
					" : " + dmd.getJDBCMinorVersion());
			
		} catch (ClassNotFoundException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (SQLException e) {
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(conn != null) try { conn.close(); } catch(SQLException e) {}
			}
		}
	}
.getDatabaseProductName() = 데이터베이스 제품 이름
.getDatabaseProductVersion() = 데이터베이스 제품 버전
.getDriverName() =  JDBC 드라이버 이름
.getDriverVersion() = 드라이버 버전
getJDBCMajorVersion() / getJDBCMinorVersion() : 드라이버 최대 / 최소 버전?




import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

public class ResultSet1 {

	public static void main(String[] args) {
		String url = "jdbc:mariadb://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();
			//System.out.println(rsmd.getColumnCount());  // String sql 컬럼의 개수
			
			for(int i = 1; i <= rsmd.getColumnCount(); i++) {
				// i번째만큼 컬럼 이름 출력
				System.out.println(rsmd.getColumnName(i));
				System.out.println(rsmd.getColumnTypeName(i));

				System.out.println(rsmd.getPrecision(i)); // n번째 컬럼의 크기
			}
			
		} catch (ClassNotFoundException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (SQLException e) {
			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) {}
			}
		}
	}
.getColumnCount()  -> String sql 컬럼의 개수
.getColumnName(n)  -> n번째 컬럼의 이름
.getColumnTypeName(n) -> n번째 컬럼의 타입
.getPrecision(n) -> n번째 컬럼의 크기




커넥션 풀

커넥션 풀 기법이란 데이터베이스와 연결된 커넥션을 미리 만들어서 풀(pool) 속에 저장해 두고 있다가 필요할 때에 커넥션을 풀에서 가져다쓰고 다시 풀에 반환하는 기법을 의미



프로세스

애플리케이션(브라우저, 워드 등) 실행 -> 운영체제에서 메모리 할당받고 CPU / HDD 통하여 동작 (프로세스)

프로세스 - ProcessBuilder

  • Forground Process - 일반적인 애플리케이션( = 앱, 응용 프로그램)
  • Background Process - 서버 계열(화면이 없다) + 윈도우가 관리하는 프로그램(서비스)

= > 작업관리자를 통해 확인 가능


스레드

프로세스 동작의 최소 단위
모든 프로세스는 하나 이상의 스레드로 구성
스레드끼리는 공유되지 않는다

일반적으로 runnable 인터페이스나 스레드 상속하여 구현한다.

메인스레드가 메인 메서드 실행하면서 애플리케이션 구동

둘 이상의 스레드로 구성된 프로세스를 멀티스레드 프로세스라고 함

장점 / 단점

  1. cpu 사용률 향상 -

  2. 작업의 분리로 응답성 향상

  3. 자원의 공유를 통한 효율성 증대

(여기서부터 단점)

  1. 컨텍스트 스위칭 비용 발생

  2. 스레드 제어의 어려움

스레드 생성(상속으로)

순차처리 기능

go, come 메서드 생성

메인에서 실행 (일반 메서드 호출)


병렬처리 기능


go, come 메서드 재정의 ( 스레드 상속 )

메인에서 실행(start 사용) = 스레드가 실행 위임받음




스레드 생성 (인터페이스)

go, come 메서드 재정의 ( 인터페이스 구현 )

메인에서 실행 ( Thread 타입 변수 만들어서 실행)

println 구문들 / t1 / t2 각자 실행됨




스레드 생명주기 (중요!)

  1. start() 메서드 호출시 스레드 상태 Runuable(실행 대기)로변경 (위임느낌)
    start() -> run() 메서드가 호출될 수 있도록 준비하는 과정

  2. jvm이 운영체제의 스레드 스케줄러에 의해 가능할 때 run 메서드 호출하여 running 상태로 변경되어 동작됨



익명 이너 클래스 이용

package pack4;

public class main1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread t1 = new Thread(new Runnable() { //익명 클래스

			@Override
			public void run() { 
				// 스레드에서 처리할 작업
				for (int i = 1; i <= 10; i++) {
					System.out.println("go : " + i);
				}
			}
		});

		Thread t2 = new Thread(new Runnable() { //익명 클래스

			@Override
			public void run() {
				// 스레드에서 처리할 작업
				for (int i = 1; i <= 10; i++) {
					System.out.println("come : " + i);
				}
			}
		});

		System.out.println("시작");
		t1.start();
		t2.start();
		System.out.println("끝");
	}
}

t1 / t2 둘 다 익명 클래스로 스레드 만들어서 start 호출



위 코드 람다식으로 변경

package pack4;

public class main1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Thread t1 = new Thread( () -> { 
				for (int i = 1; i <= 10; i++) {
					System.out.println("go : " + i);
				}
		});

		Thread t2 = new Thread(() -> {

				for (int i = 1; i <= 10; i++) {
					System.out.println("come : " + i);
			}
		});

		System.out.println("시작");
		t1.start();
		t2.start();
		System.out.println("끝");
	}
}



스레드 선택과 우선순위

ex 메세지(톡)와 파일전송이 동시에 이뤄져야하는 상황일 때

setPriority(n) 으로 n에 따라 우선순위 정해짐 ( 1~10 중 5가 default, 우선순위가 높은 것이 좋음)

우선순위가 높다고 해서 반드시 그렇게 실행되는 것은 아님!! (실행 추천 정도로 생각, 항상 그 순서대로 실행되는 것이 아니다)



MyThread1 / MyThread2 를 thread 상속받아 생성


메인에서 각각 객체 생성 후 t1에 우선순위 7 주고 실행


실행 - t1이 우선순위긴 하지만 항상 그렇게 실행되지 않는 점 주의


우선순위는 이렇게도 가능하다.



MIN_PRIORITY(1) / MAX_PRIORITY(10) 로 설정하여 우선순위 지정




sleep : 스레드 상태 제어


sleep으로 1초 쉬기


메인에서 실행시 1초 쉬었다가 콘솔에 출력

응용 : 1초마다 실행되는 시계 출력(3번만)

package pack6;

import java.time.LocalTime;

public class SleepTest1 {

	static class Timer extends Thread {
		public void run() {
			for(int i = 0; i < 3; i++) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("째깍 : " + LocalTime.now()); --> 현재시각
			}
		}
	}
	public static void main(String[] args) {
		Timer timer = new Timer();
		
		timer.start();
	}
}


1초 간격으로 실행됨

profile
끄적끄적

0개의 댓글