티스토리 뷰

JDBC(Java Database Connectivity)

  • 자바 프로그램 안에서 SQL을 실행하기 위해 DB를 연결해주는 응용프로그램 인터페이스
  • 즉, 자바 프로그램 내에서 질의문을 실행하기 위한 API
  • 어떤 DB를 사용하든 간에 JDBC 드라이버만 제공된다면 코드의 수정이 거의 없이 바로 적용이 가능하다는 장점이 있다.

JDBC 프로그래밍 단계

1. 드라이버 로딩

- Class.forName()의 인자로 자신의 DB가 제공하는 드라이버 이름을 명시하면 된다.

Class.forName()을 호출하면 Driver가 자기자신을 초기화하여 객체가 생성되고, DriverManager에 등록한다.

Class.forName("oracle.jdbc.driver.OracleDriver");

2. 데이터베이스 연결

- Connection 객체를 이용해서 DriverManager에 등록된 DB와 연결을 한다.

- 연결에 성공하면 Connection 객체가 반환되고, 실패하면 예외가 발생한다.

Connection conn = null;

String user = "system";
String pw = "bitBIT1234";
String url = "jdbc:oracle:thin:@localhost:1521:orcl";

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

3. Statement 생성

  • Statement(정적쿼리)
    • PreparedStatement와 다르게 인자값이 변하지 않을 때 사용한다.
    • 인자값이 변하지 않더라도 PreparedStatement를 사용하는 것이 성능면에서 더 좋다.
Statement st = null;

// Statment객체 생성
st = conn.createStatement();
String sql = "SELECT * FROM CRUD_TABLE ORDER BY AGE ASC";
  • PreparedStatement(동적쿼리)
    • 인자만 변하고 구문이 같을 경우 JDBC는 구문 생성 및 컴파일 시간을 단축 시킬 수 있도록 지원하는 클래스
    • 변경하고자 하는 인자를 ? 로 표현하고 ? 에 값을 대입한다. 
PreparedStatement ps = null;

String sql = "INSERT INTO CRUD_TABLE(name, age) values(?, ?)";

// PrparedStatment객체 생성, 인자로 sql문이 주어짐
ps = conn.prepareStatement(sql);
ps.setString(1, data.name);
ps.setInt(2, data.age);

4. SQL문 전송(실행)

  • executeQuery()
    • 수행결과로 ResultSet 객체의 값을 반환한다.
    • SELECT 구문을 수행 할 때 사용하는 함수이다.
Statement st = null;

// Statment객체 생성
st = conn.createStatement();
String sql = "SELECT * FROM CRUD_TABLE ORDER BY AGE ASC";

//rs:ResultSet은 실행한 쿼리문의 결과 값을 받아들이다.
rs = st.executeQuery(sql);
  • executeUpdate()
    • 수행 결과를 int 타입의 값을 반환한다.
    • SELECT 구문을 제외한 다른 구문을 수행 할 때 사용되는 함수이다.
PreparedStatement ps = null;

String sql = "INSERT INTO CRUD_TABLE(name, age) values(?, ?)";

// PrparedStatment객체 생성, 인자로 sql문이 주어짐
ps = conn.prepareStatement(sql);
ps.setString(1, data.name);
ps.setInt(2, data.age);

// executeUpdate : insert, delete, update와 같이 값을 받아오지 않는 쿼리문 실행
ps.executeUpdate();

5. 결과 받기

  • ResultSet
    • SELECT 구문의 SQL문 통해 얻어지는 결과를 다루는 클래스
Statement st = null;
ResultSet rs = null;

// Statment객체 생성
st = conn.createStatement();
String sql = "SELECT * FROM CRUD_TABLE ORDER BY AGE ASC";

//rs:ResultSet은 실행한 쿼리문의 결과 값을 받아들이다.
rs = st.executeQuery(sql);

6. 연결해제

- Connection()을 close 해주지 않으면 사용하지 않는 자원이 남아있어 성능 저하가 발생한다.

- 사용하지 않는 자원으로 인해서 SQLException이 발생할 수 있다.

// 사용하지 않는 자원이 유지 되기 때문에 자원이 낭비된다.
public void dbClose() {
	try {
		if (rs != null)
			rs.close();
		if (st != null)
			st.close();
		if (ps != null)
			ps.close();
	} catch (Exception e) {
		System.out.println(e + "=> dbClose fail");
	}
}

7. CRUD 코드 및 실행결과

DAO.java

// DAO.java

package dbcrud2;

import java.sql.*;
import java.util.ArrayList;

public class DAO {

	// Connection은 데이터베이스와 연결하는 객체이다.
	Connection conn = null;
	// ResultSet : 실행한 쿼리문의 값을 받는 객체
	ResultSet rs = null;
	Statement st = null; // 그냥 가져오는거
	// PreparedStatement는 쿼리문에 ?를 사용해서 추가로 ?에 변수를 할당해 줄수 있도록 하는 객체
	PreparedStatement ps = null; // ?넣어서 집어넣는거

	// 생성자
	public DAO() {

		try {
			String user = "system";
			String pw = "bitBIT1234";
			String url = "jdbc:oracle:thin:@localhost:1521:orcl";

			// jdbc drive를 등록하는 과정
			// class.forName을 호출하면 Driver가 자기자신을 초기화하여 DriverManager에 등록한다.
			// 즉, 개발자가 따로 관리하지 않는 static 객체들이 알아서 DriverManager에 등록되는 것이다.
			// 그래서 Class.forName()을 호출하고 나서 어떤 인자로도 전달하지 않고 바로 getConnection()을 호출해도 드라이버가 찾아진다.
			
			// Driver Class를 로딩하면 객체가 생성되고, DriverManager에 등록된다.
			Class.forName("oracle.jdbc.driver.OracleDriver");
			// connection으로 db와 연결 (객체 생성)
			conn = DriverManager.getConnection(url, user, pw);

		} catch (ClassNotFoundException cnfe) {
			System.out.println("DB 드라이버 로딩 실패 :" + cnfe.toString());
		} catch (SQLException sqle) {
			System.out.println("DB 접속실패 : " + sqle.toString());
		} catch (Exception e) {
			System.out.println("Unkonwn error");
			e.printStackTrace();
		}
	}

	// 사용하지 않는 자원이 유지 되기 때문에 자원이 낭비된다.
	public void dbClose() {
		try {
			if (rs != null)
				rs.close();
			if (st != null)
				st.close();
			if (ps != null)
				ps.close();
		} catch (Exception e) {
			System.out.println(e + "=> dbClose fail");
		}
	}

	// Create
	public void insertData(Data data) {
		try {
			String sql = "INSERT INTO CRUD_TABLE(name, age) values(?, ?)";
			// PrparedStatment객체 생성, 인자로 sql문이 주어짐
			ps = conn.prepareStatement(sql);
			ps.setString(1, data.name);
			ps.setInt(2, data.age);
			// executeUpdate : insert, delete, update와 같이 값을 받아오지 않는 쿼리문 실행
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbClose();
		}
	}

	// Read
	public ArrayList<Data> readData() {
		ArrayList<Data> arr = new ArrayList<Data>();
		System.out.println(arr);
		try {
			// 쿼리문을 db에 넘김, 온전한 문자열 대입
			st = conn.createStatement();

			String sql = "SELECT * FROM CRUD_TABLE ORDER BY AGE ASC";
			//rs:ResultSet은 실행한 쿼리문의 결과 값을 받아들이다.
			rs = st.executeQuery(sql);

			// 받은 결과값을 출력
			while (rs.next()) {
				arr.add(new Data(rs.getString(1), rs.getInt(2)));
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbClose();
		}
		return arr;
	}

	// Update
	public void updateData(Data data) {
		try {
			String sql = "UPDATE CRUD_TABLE SET AGE=? WHERE NAME=?";
			ps = conn.prepareStatement(sql);
			ps.setInt(1, data.age);
			ps.setString(2, data.name);
			ps.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbClose();
		}
	}

	// Delete
	public void deleteData(String name) {
		try {

			String sql = "DELETE FROM CRUD_TABLE WHERE NAME=?";
			ps = conn.prepareStatement(sql);
			ps.setString(1, name);
			ps.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbClose();
		}
	}
}

CRUDGUI.java

// CRUDGUI.java

package dbcrud2;

import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;

public class CRUDGUI {
	JFrame jframe = new JFrame();
	JPanel jpanel = new JPanel();
	JTextField tf1 = new JTextField();
	JTextField tf2 = new JTextField();
	JTextArea ta = new JTextArea();
	JButton btn1, btn2, btn3, btn4, btn5;
	JLabel jl1 = new JLabel("NAME  : ");
	JLabel jl2 = new JLabel("AGE  : ");
	
	CRUDGUI() {
		GUI_init();
	}

	public void GUI_init() {
		// GUI 틀 만들기
		jframe.setBounds(50, 50, 500, 330); // 전체 창 크기
		jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 창 닫기 버튼 누르면 꺼지게 설정
		jframe.setVisible(true);
		
		jpanel.setLayout(null);
		jframe.add(jpanel);

		// 입력 공간
		tf1.setBounds(90, 25, 70, 25);
		jpanel.add(tf1); // 이름 입력 공간
		tf2.setBounds(215, 25, 70, 25);
		jpanel.add(tf2); // 나이 입력 공간
		
		jl1.setBounds(37, 21, 70, 30);
		jpanel.add(jl1);  // 이름 라벨
		jl2.setBounds(170, 21, 70, 30);
		jpanel.add(jl2);  // 나이 라벵

		// 입력한 글이 보이는 창
		JScrollPane jsp = new JScrollPane(ta); // 창 스크롤
		jsp.setBounds(20, 70, 300, 200);
		jpanel.add(jsp);

		// 입력 버튼 - create
		jpanel.add(btn1=new JButton("입력"));
		btn1.setBounds(350, 70, 100, 30);

		// 출력 버튼 - read
		jpanel.add(btn2=new JButton("출력"));
		btn2.setBounds(350, 110, 100, 30);

		// 수정 버튼 - update
		jpanel.add(btn3=new JButton("수정"));
		btn3.setBounds(350, 150, 100, 30);

		// 삭제 버튼 - delete
		jpanel.add(btn4=new JButton("삭제"));
		btn4.setBounds(350, 190, 100, 30);

		// 종료 버튼
		jpanel.add(btn5=new JButton("종료"));
		btn5.setBounds(350, 230, 100, 30);

		DAO dao = new DAO();

		// 입력 버튼 이벤트
		btn1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				ta.setText("");
				
				String name = tf1.getText();
				int age = Integer.parseInt(tf2.getText());
				
				dao.insertData(new Data(name, age));
				
				ta.append("입력 완료 \n");				
				
				tf1.setText(""); tf2.setText("");
			}
		});

		// 출력 버튼 이벤트
		btn2.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				ta.setText("");
				ArrayList<Data> arr = new ArrayList<Data>();
				arr = dao.readData();
				
				ta.append("name"+"\t"+"age"+"\n");
				ta.append("--------------------------\n");
				
				// 전체 출력
				for (int i = 0; i < arr.size(); i++) {
					ta.append(arr.get(i).getName() +" \t "+ arr.get(i).getAge() + "\n");
				}
			}
		});

		// 수정 버튼 이벤트
		btn3.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				ta.setText(""); 
				
				String name = tf1.getText();
				int age = Integer.parseInt(tf2.getText());

				dao.updateData(new Data(name, age));
				ta.append("수정 완료 \n");
				
				tf1.setText(""); tf2.setText("");
			}
		});

		// 삭제 버튼 이벤트
		btn4.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				ta.setText("");
				
				String name = tf1.getText();
				dao.deleteData(name);
				ta.append("삭제 완료 \n");
	
				tf1.setText(""); tf2.setText("");
			}
		});

		// 종료 버튼 이벤트
		btn5.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.exit(0);
			}
		});
	}
}

Data.java

// Data.java

package dbcrud2;

public class Data {
	String name;
	int age;

	public Data() {
	}
    
	public Data(String name, int age) {
		this.age = age;
		this.name = name;
	}

	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;
	}
}

Main.java

// Main.java

package dbcrud2;

public class Main {
	public static void main(String[] args) {
		CRUDGUI gui = new CRUDGUI();
	}
}

실행결과

출력(오름차순으로 출력)

출력

입력 후 출력

입력
입력 후 출력

수정 후 출력

수정
수정 후 출력

삭제 후 출력

삭제
삭제 후 출력

 

 

 

2019.08.09(금) Java swing을 사용한 crud

'Database' 카테고리의 다른 글

[DATABASE] MySQL SELECT문  (0) 2019.09.05
[DATABASE] MySQL install  (0) 2019.09.04
[DATABASE] Oracle install  (0) 2019.08.06
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함