JFrame crud & List<Map> 강화

지환·2023년 10월 14일
0

JAVA

목록 보기
31/39
post-thumbnail

DeptManager - 초본

package com.week5;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
// ActionListener al = new DeptManager();
//자바는 단일 상속만 가능하다.- 다중상속은 불가함 - 다중상속의 단점을 보완하기 위해 인터페이스가 제공됨
//단 인터페이스는 여러개를 implements할 수 있다.(추상클래스, 인터페이스는 설계관점에서 중요함 - 특징, 컨벤션)
public class DeptManager extends JFrame implements ActionListener{
	//선언부
	String header[] = {"부서번호","부서명","지역"};
	String datas[][] = new String[0][0];//2차배열 - 대괄호가 2쌍이 필요함
	//생성자의 파라미터를 통해서 서로 다른 클래스가 의존관계를 맺고 하나의 기능을 서비스 할 수  있다.
	//생성자도 파라미터를 여러개 갖을 수 있다. - 메소드 오버로딩
	DefaultTableModel dtm_dept = new DefaultTableModel(datas, header);//<table>-양식  자바가 있어야 DataSet구성함
	JTable jt_dept = new JTable(dtm_dept);
	JScrollPane jsp_dept = new JScrollPane(jt_dept);
	JPanel jp_north = new JPanel();
	JButton jbtnSelect = new JButton("조회");
	JButton jbtnAdd = new JButton("행추가");
	JButton jbtnDel = new JButton("행삭제");
	JButton jbtnExit = new JButton("종료");
	//생성자
	DeptManager(){
		initDisplay();
	}////////////// end of DeptManager

	}
	//화면 처리부
	public void initDisplay() {
		jbtnSelect.addActionListener(this);
		jbtnSelect.addActionListener(this);
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jp_north.add(jbtnSelect);
		jp_north.add(jbtnAdd);
		jp_north.add(jbtnDel);
		jp_north.add(jbtnExit);
		this.add("North", jp_north);
		this.add("Center", jsp_dept);
		this.setSize(500, 400);//this:DeptManager
		this.setVisible(true);
	}//////////// end of initDisplay  /////////////
	//메인 메소드
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		DeptManager dm = new DeptManager();//new JFrame()호출되는 것이다.
	}//////////////// end of main ////////////////
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed호출은 반드시 addActionListener가 있어야 됨");
		Object obj = e.getSource();
		//너 조회버튼 누른거야?
		if(obj == jbtnSelect) {

			
			
		}////////////////// end of if ///////////////
		
	}///////////////////// end of actionPerformed


}

Array로 바꿔라

새로고침 시나리오1

  • 전역변수로 선언 된 deptlist 를 끌어다가 DeptDTO 라는 변수를 하나 선언해서 값을 담은 다음
  • Vector 객체를 하나 만든다음 그 값들을 Vector에다 추가 -> dtm_dept.row에 추가

답안

어떤 메소드를 설계해야 하나? - 입력,수정,삭제,조회
삭제하기

성공 했을 때

  • 입력 -> 늘어남
    View -> 입력함(VO,DTO) -> 저장 -> Insert문(오라클 서버) -> select
    View -> action(insert) -> action(select) -> View
  • 삭제 - 줄어듦
    View -> action(delete) -> action(select) -> View
  • 수정 - 수정된 내용이 현재 화면에 반영된다.
    action(Select) -> View -> action(update) -> action(select) -> View
package com.step5;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
// ActionListener al = new DeptManager();
//자바는 단일 상속만 가능하다.- 다중상속은 불가함 - 다중상속의 단점을 보완하기 위해 인터페이스가 제공됨
//단 인터페이스는 여러개를 implements할 수 있다.(추상클래스, 인터페이스는 설계관점에서 중요함 - 특징, 컨벤션)
public class DeptManager extends JFrame implements ActionListener{
	//선언부
	List<DeptDTO> deptList = new ArrayList<>();//왜 전역변수로 하는가? 입력|수정|삭제|조회
	String header[] = {"부서번호","부서명","지역"};
	String datas[][] = new String[0][0];//2차배열 - 대괄호가 2쌍이 필요함
	//생성자의 파라미터를 통해서 서로 다른 클래스가 의존관계를 맺고 하나의 기능을 서비스 할 수  있다.
	//생성자도 파라미터를 여러개 갖을 수 있다. - 메소드 오버로딩
	DefaultTableModel dtm_dept = new DefaultTableModel(datas, header);//<table>-양식  자바가 있어야 DataSet구성함
	JTable jt_dept = new JTable(dtm_dept);
	JScrollPane jsp_dept = new JScrollPane(jt_dept);
	JPanel jp_north = new JPanel();
	JButton jbtnSelect = new JButton("조회");
	JButton jbtnAdd = new JButton("행추가");
	JButton jbtnDel = new JButton("행삭제");
	JButton jbtnExit = new JButton("종료");
	//생성자
	DeptManager(){
		getDeptList();
		initDisplay();
	}////////////// end of DeptManager
	public List<DeptDTO> getDeptList(){
		DeptDTO dept = new DeptDTO(10,"영업부","부산");
		deptList.add(dept);
		dept = new DeptDTO(20,"개발부","대전");
		deptList.add(dept);
		dept = new DeptDTO(30,"운영부","인천");
		deptList.add(dept);
		return deptList;
	}
	//화면 처리부
	public void initDisplay() {
		jbtnSelect.addActionListener(this);
		jbtnSelect.addActionListener(this);
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jp_north.add(jbtnSelect);
		jp_north.add(jbtnAdd);
		jp_north.add(jbtnDel);
		jp_north.add(jbtnExit);
		this.add("North", jp_north);
		this.add("Center", jsp_dept);
		this.setSize(500, 400);//this:DeptManager
		this.setVisible(true);
	}//////////// end of initDisplay  /////////////
	//메인 메소드
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		DeptManager dm = new DeptManager();//new JFrame()호출되는 것이다.
	}//////////////// end of main ////////////////
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed호출은 반드시 addActionListener가 있어야 됨");
		Object obj = e.getSource();
		//너 조회버튼 누른거야?
		if(obj == jbtnSelect) {
			System.out.println("조회버튼 클릭");//log
			while(dtm_dept.getRowCount()>0) {
				dtm_dept.removeRow(0);
			}
			for(int i=0;i<deptList.size();i++) {
				DeptDTO rdept = deptList.get(i);
				Vector<Object>  v = new Vector<>();//3번 생성됨
				v.add(0,rdept.getDeptno());
				v.add(1,rdept.getDname());
				v.add(2,rdept.getLoc());
				dtm_dept.addRow(v);
			}
		}////////////////// end of if ///////////////
		
	}///////////////////// end of actionPerformed


}

  • refresh로 빼기
package com.step5;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
// ActionListener al = new DeptManager();
//자바는 단일 상속만 가능하다.- 다중상속은 불가함 - 다중상속의 단점을 보완하기 위해 인터페이스가 제공됨
//단 인터페이스는 여러개를 implements할 수 있다.(추상클래스, 인터페이스는 설계관점에서 중요함 - 특징, 컨벤션)
public class DeptManager2 extends JFrame implements ActionListener{
	//선언부
	List<DeptDTO> deptlist = new ArrayList<>();
	String header[] = {"부서번호","부서명","지역"};
	String datas[][] = new String[0][0];//2차배열 - 대괄호가 2쌍이 필요함
	//생성자의 파라미터를 통해서 서로 다른 클래스가 의존관계를 맺고 하나의 기능을 서비스 할 수  있다.
	//생성자도 파라미터를 여러개 갖을 수 있다. - 메소드 오버로딩
	DefaultTableModel dtm_dept = new DefaultTableModel(datas, header);//<table>-양식  자바가 있어야 DataSet구성함
	JTable jt_dept = new JTable(dtm_dept);
	JScrollPane jsp_dept = new JScrollPane(jt_dept);
	JPanel jp_north = new JPanel();
	JButton jbtnSelect = new JButton("조회");
	JButton jbtnAdd = new JButton("행추가");
	JButton jbtnDel = new JButton("행삭제");
	JButton jbtnExit = new JButton("종료");
	//생성자
	DeptManager2(){
    	getDeptList();
		initDisplay();
	}////////////// end of DeptManager

	/*
	 * deptlist에 DeptDTO 값을 넣어야지 -> 계속 메소드를 사용하면서 재활용 하고 싶어 how?
	 */
	public List<DeptDTO> getDeptList()
	{
		// DeptDTO가 필요한 이유는 값을 set해야 되기 때문이다. -> 그래야지 밑에 조회를 눌렀을 때 값이 뜬다.
		// 언제까지 set 써서 값 넣을래 -> 할 수 있는 방법이 있다. -> 생성자에다가 처음에 대입할 때 하면  된다.
		DeptDTO deptDTO = new DeptDTO(20,"오지환","인천");
		// add 해야지 -> 또 "재정의" 해서 -> 하게 되면 업데이트가 된다.
		deptlist.add(deptDTO);// 0번 인덱스에 해당 값이 저장된다. -> 이 줄이 넘어가면 1번 인덱스로 바뀌게 된다
		deptDTO = new DeptDTO(23,"김수진","서울");
		deptlist.add(deptDTO);
		deptDTO = new DeptDTO(25,"김유진","성남");
		deptlist.add(deptDTO);
		
		return deptlist;
		/*
		 * 20,"오지환","인천" --> 0
		 * 23,"김수진","서울" --> 1
		 * 25,"김유진","성남" --> 2
		 */
		
		
	}
	
	
	//화면 처리부
	public void initDisplay() {
		jbtnSelect.addActionListener(this);
		jbtnSelect.addActionListener(this);
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jp_north.add(jbtnSelect);
		jp_north.add(jbtnAdd);
		jp_north.add(jbtnDel);
		jp_north.add(jbtnExit);
		this.add("North", jp_north);
		this.add("Center", jsp_dept);
		this.setSize(500, 400);//this:DeptManager
		this.setVisible(true);
	}//////////// end of initDisplay  /////////////
	//메인 메소드
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		DeptManager dm = new DeptManager();//new JFrame()호출되는 것이다.
	}//////////////// end of main ////////////////
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed호출은 반드시 addActionListener가 있어야 됨");
		Object obj = e.getSource();
		//너 조회버튼 누른거야?
		if(obj == jbtnSelect) {
		while(dtm_dept.getRowCount()>0)
		{
			dtm_dept.removeRow(0);
		}
		for(int i = 0; i<deptlist.size(); i++)
		{
			// 값을 테이블에 저장을 해야 된다.
			/*---새로고침 시나리오1------
			 * 전역변수로 선언 된 deptlist 를 끌어다가 DeptDTO 라는 변수를 하나 선언해서 값을 담은 다음
			 * Vector 객체를 하나 만든다음 그 값들을 Vector에다 추가 -> dtm_dept.row에 추가
			 */
			DeptDTO redept = deptlist.get(i);
			Vector<Object> v = new Vector(); // Object로 하는 이유가   dtm_dept로 받을 수 있는 파라미터가 addrow(object[], int)이기 떄문이다.
			v.add(0,redept.getDeptno());
			v.add(1,redept.getDname());
			v.add(2,redept.getLoc());
			dtm_dept.addRow(v);
			
		}
		
		

			
			
		}////////////////// end of if ///////////////
		
		
	}///////////////////// end of actionPerformed
	
	public void refresh() // 새로고침하는 메소드 
	{
		while(dtm_dept.getRowCount()>0)
		{
			dtm_dept.removeRow(0);
		}
		for(int i = 0; i<deptlist.size(); i++)
		{
			// 값을 테이블에 저장을 해야 된다.
			/*---새로고침 시나리오1------
			 * 전역변수로 선언 된 deptlist 를 끌어다가 DeptDTO 라는 변수를 하나 선언해서 값을 담은 다음
			 * Vector 객체를 하나 만든다음 그 값들을 Vector에다 추가 -> dtm_dept.row에 추가
			 */
			DeptDTO redept = deptlist.get(i);
			Vector<Object> v = new Vector(); // Object로 하는 이유가   dtm_dept로 받을 수 있는 파라미터가 addrow(object[], int)이기 떄문이다.
			v.add(0,redept.getDeptno());
			v.add(1,redept.getDname());
			v.add(2,redept.getLoc());
			dtm_dept.addRow(v);
			
		}
	}


}
  • 실행순서를 보자. main에서 인스턴스화를 하면 -> 생성자(DeptManager2)가 호출된다. 내부를 돌기전에 -> 생성자는 전역변수를 초기화 하는 역할이 있기 때문에 먼저 전역변수를 돈다. -> List가 선언되고(껍데기) 전역변수 쭉 돌고 -> 생성자 내부에 들어와서 -> getDeptList() 실행한다. -> 실행하면 getDeptList 리턴값으로 deptlist 받고 -> 그 값이 저장된 상태로(표시가 되진 않음) -> initDisplay를 한다.
  • 해당 부분 참고하기 1차배열 ArrayIndexOutOfBoundsException
package com.step5;

public class Array3 {

	public static void main(String[] args) {
		int[] a = new int[3];
		System.out.println(a[3]); //  java.lang.ArrayIndexOutOfBoundsException:
		
		for(int i = 0; i<= a.length; i++)
		{
			System.out.println(a[3]);// java.lang.ArrayIndexOutOfBoundsException: 왜? for문 <= 때문에
		}
	}
}
-----------------------------------------
0
0
0
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
	at com.step5.Array3.main(Array3.java:10)
  • 왜? for문 <= 때문에

+ 삭제 메소드 추가하기 refreshData

package com.step5;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
// ActionListener al = new DeptManager();
//자바는 단일 상속만 가능하다.- 다중상속은 불가함 - 다중상속의 단점을 보완하기 위해 인터페이스가 제공됨
//단 인터페이스는 여러개를 implements할 수 있다.(추상클래스, 인터페이스는 설계관점에서 중요함 - 특징, 컨벤션)
public class DeptManager extends JFrame implements ActionListener{
	//선언부
	List<DeptDTO> deptList = new ArrayList<>();//왜 전역변수로 하는가? 입력|수정|삭제|조회
	String header[] = {"부서번호","부서명","지역"};
	String datas[][] = new String[0][0];//2차배열 - 대괄호가 2쌍이 필요함
	//생성자의 파라미터를 통해서 서로 다른 클래스가 의존관계를 맺고 하나의 기능을 서비스 할 수  있다.
	//생성자도 파라미터를 여러개 갖을 수 있다. - 메소드 오버로딩
	DefaultTableModel dtm_dept = new DefaultTableModel(datas, header);//<table>-양식  자바가 있어야 DataSet구성함
	JTable jt_dept = new JTable(dtm_dept);
	JScrollPane jsp_dept = new JScrollPane(jt_dept);
	JPanel jp_north = new JPanel();
	JButton jbtnSelect = new JButton("조회");
	JButton jbtnDelete = new JButton("삭제");
	JButton jbtnAdd = new JButton("행추가");
	JButton jbtnDel = new JButton("행삭제");
	JButton jbtnExit = new JButton("종료");
	//생성자
	DeptManager(){
		getDeptList();
		initDisplay();
	}////////////// end of DeptManager
	public List<DeptDTO> getDeptList(){
		DeptDTO dept = new DeptDTO(10,"영업부","부산");
		deptList.add(dept);
		dept = new DeptDTO(20,"개발부","대전");
		deptList.add(dept);
		dept = new DeptDTO(30,"운영부","인천");
		deptList.add(dept);
		return deptList;
	}
	//화면 처리부
	public void initDisplay() {
		jbtnSelect.addActionListener(this);
		jbtnDelete.addActionListener(this);
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jp_north.add(jbtnSelect);
		jp_north.add(jbtnDelete);
		jp_north.add(jbtnAdd);
		jp_north.add(jbtnDel);
		jp_north.add(jbtnExit);
		this.add("North", jp_north);
		this.add("Center", jsp_dept);
		this.setSize(500, 400);//this:DeptManager
		this.setVisible(true);
	}//////////// end of initDisplay  /////////////
	//메인 메소드
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		DeptManager dm = new DeptManager();//new JFrame()호출되는 것이다.
	}//////////////// end of main ////////////////
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed호출은 반드시 addActionListener가 있어야 됨");
		Object obj = e.getSource();
		
		//너 삭제 할거니?
		if(obj == jbtnDelete) {
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 데이터를 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}
			//여기로 못오게 함
			else {
				System.out.println(index); // 여기서 Object는 DeptDTO
				DeptDTO rdept = deptList.remove(index);
				System.out.println(rdept+","+"rdept.getDeptno()"+rdept.getDeptno());
				refreshData();
			}
		}
		
		//너 조회버튼 누른거야?
		else if(obj == jbtnSelect) {
			System.out.println("조회버튼 클릭");//log
			//웹 개발이더라도 html이 데이터를 쥘수는 없다
			//html과 자바코드를 섞어쓰기가 가능한가? - 불가 - jsp공부함  - 자바자료구조를 JSON형식으로 넘기기
			//dtm_dept는 실제 데이터를 포용함
			//JTable은 클릭이벤트 같은 것은 가능함 - 실제 데이터를 쥐고 있지 못함
			//getRowCount는 데이터의 로우 수 반환 - 3건
			while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
				dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
			}
			for(int i=0;i<deptList.size();i++) {
				DeptDTO rdept = deptList.get(i);
				Vector<Object>  v = new Vector<>();//3번 생성됨
				v.add(0,rdept.getDeptno());
				v.add(1,rdept.getDname());
				v.add(2,rdept.getLoc());
				dtm_dept.addRow(v);
			}
		}////////////////// end of if ///////////////
		
	}///////////////////// end of actionPerformed
	//새로고침(F5) 구현하기
	public void refreshData() {
		while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
			dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
		}
		for(int i=0;i<deptList.size();i++) {
			DeptDTO rdept = deptList.get(i);
			Vector<Object>  v = new Vector<>();//3번 생성됨
			v.add(0,rdept.getDeptno());
			v.add(1,rdept.getDname());
			v.add(2,rdept.getLoc());
			dtm_dept.addRow(v);
		}		
	}//////////////////end of refreshData //////////////////
}
  • 삭제부분과 remove 받는 타입 & 신경쓰기

초기상태


+ 행추가만 하는 부분 구현하기

if(obj == jbtnAdd)
		{
			Vector addRow = new Vector();
			dtm_dept.addRow(addRow);
		}

행을 추가 하는데 있어 내부적인 이벤트 처리가 필요할까?


같은 구현

		if(obj == jbtnAdd)
		{
			Object addRow2[] = new Object[3];
			dtm_dept.addRow(addRow2);
		}

추가적인 요구사항 : 삭제 버튼을 눌렀을 때 삭제가 되었습니다 라고 창이 뜨고 해당 row 전체 삭제

		//너 삭제 할거니?
		else if(obj == jbtnDelete) {
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 데이터를 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}
			//여기로 못오게 함
			else {
				System.out.println(index); // 여기서 Object는 DeptDTO
				DeptDTO rdept = deptList.remove(index);
				System.out.println(rdept+","+"rdept.getDeptno()"+rdept.getDeptno());
				if(rdept != null)
				{
					JOptionPane.showMessageDialog(this,"삭제 성공하였습니다.","INFO", JOptionPane.INFORMATION_MESSAGE);
					refreshData();
					
				}
				else
				{
					JOptionPane.showMessageDialog(this,"삭제가 실패하였습니다.","INFO", JOptionPane.INFORMATION_MESSAGE);
					return;
				
				}
				//JOptionPane.showMessageDialog(this,"삭제 성공하였습니다.","INFO", JOptionPane.INFORMATION_MESSAGE);
			}
		}

확인을 눌렀을 때 -> refreshData(); 실행 되서 -> 삭제

행삭제

		if(obj == jbtnDel)
		{
			dtm_dept.removeRow(0); // 리턴타입이 0이여서 void이다.
		}
		
        
 ------------------------------------
 
 

ArrayList 구현


import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
// ActionListener al = new DeptManager();
//자바는 단일 상속만 가능하다.- 다중상속은 불가함 - 다중상속의 단점을 보완하기 위해 인터페이스가 제공됨
//단 인터페이스는 여러개를 implements할 수 있다.(추상클래스, 인터페이스는 설계관점에서 중요함 - 특징, 컨벤션)
public class DeptManager extends JFrame implements ActionListener{
	//선언부
	List<DeptDTO> deptList = new ArrayList<>();//왜 전역변수로 하는가? 입력|수정|삭제|조회
	String header[] = {"부서번호","부서명","지역"};
	String datas[][] = new String[0][0];//2차배열 - 대괄호가 2쌍이 필요함
	//생성자의 파라미터를 통해서 서로 다른 클래스가 의존관계를 맺고 하나의 기능을 서비스 할 수  있다.
	//생성자도 파라미터를 여러개 갖을 수 있다. - 메소드 오버로딩
	DefaultTableModel dtm_dept = new DefaultTableModel(datas, header);//<table>-양식  자바가 있어야 DataSet구성함
	JTable jt_dept = new JTable(dtm_dept);
	JScrollPane jsp_dept = new JScrollPane(jt_dept);
	JPanel jp_north = new JPanel();
	JButton jbtnSelect = new JButton("조회");
	JButton jbtnDelete = new JButton("삭제");
	JButton jbtnAdd = new JButton("행추가");
	JButton jbtnDel = new JButton("행삭제");
	JButton jbtnExit = new JButton("종료");
	//생성자
	DeptManager(){
		getDeptList();
		initDisplay();
	}////////////// end of DeptManager
	public List<DeptDTO> getDeptList(){
		DeptDTO dept = new DeptDTO(10,"영업부","부산");
		deptList.add(dept);
		dept = new DeptDTO(20,"개발부","대전");
		deptList.add(dept);
		dept = new DeptDTO(30,"운영부","인천");
		deptList.add(dept);
		return deptList;
	}
	
	//화면 처리부
	public void initDisplay() {
		jbtnSelect.addActionListener(this);
		jbtnDelete.addActionListener(this);
		jbtnAdd.addActionListener(this);
		jbtnDelete.addActionListener(this);
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jp_north.add(jbtnSelect);
		jp_north.add(jbtnDelete);
		jp_north.add(jbtnAdd);
		jp_north.add(jbtnDel);
		jp_north.add(jbtnExit);
		this.add("North", jp_north);
		this.add("Center", jsp_dept);
		this.setSize(500, 400);//this:DeptManager
		this.setVisible(true);
	}//////////// end of initDisplay  /////////////
	
	//메인 메소드
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		DeptManager dm = new DeptManager();//new JFrame()호출되는 것이다.
	}//////////////// end of main ////////////////
	
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed호출은 반드시 addActionListener가 있어야 됨");
		Object obj = e.getSource();
		
		if(obj == jbtnDel)
		{
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 행을 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}
			else
			{
				dtm_dept.removeRow(index);
			}
		}
		
		
		else if(obj == jbtnAdd)
		{
			Object addRow2[] = new Object[3];
			dtm_dept.addRow(addRow2);
		}
		
		
		//너 삭제 할거니?
		else if(obj == jbtnDelete) {
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 데이터를 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}
			//여기로 못오게 함
			else {
				System.out.println(index); // 여기서 Object는 DeptDTO
				DeptDTO rdept = deptList.remove(index);
				System.out.println(rdept+","+"rdept.getDeptno()"+rdept.getDeptno());
				if(rdept != null)
				{
					JOptionPane.showMessageDialog(this,"삭제 성공하였습니다.","INFO", JOptionPane.INFORMATION_MESSAGE);
					refreshData();
					
				}
				else
				{
					JOptionPane.showMessageDialog(this,"삭제가 실패하였습니다.","INFO", JOptionPane.INFORMATION_MESSAGE);
					return;
				
				}
				//JOptionPane.showMessageDialog(this,"삭제 성공하였습니다.","INFO", JOptionPane.INFORMATION_MESSAGE);
			}
		}

		
		//너 조회버튼 누른거야?
		else if(obj == jbtnSelect) {
			System.out.println("조회버튼 클릭");//log
			//웹 개발이더라도 html이 데이터를 쥘수는 없다
			//html과 자바코드를 섞어쓰기가 가능한가? - 불가 - jsp공부함  - 자바자료구조를 JSON형식으로 넘기기
			//dtm_dept는 실제 데이터를 포용함
			//JTable은 클릭이벤트 같은 것은 가능함 - 실제 데이터를 쥐고 있지 못함
			//getRowCount는 데이터의 로우 수 반환 - 3건
			while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
				dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
			}
			for(int i=0;i<deptList.size();i++) {
				DeptDTO rdept = deptList.get(i);
				Vector<Object>  v = new Vector<>();//3번 생성됨
				v.add(0,rdept.getDeptno());
				v.add(1,rdept.getDname());
				v.add(2,rdept.getLoc());
				dtm_dept.addRow(v);
			}
		}////////////////// end of if ///////////////
		
	}///////////////////// end of actionPerformed
	
	
	
	
	
	//새로고침(F5) 구현하기
	public void refreshData() {
		while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
			dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
		}
		for(int i=0;i<deptList.size();i++) {
			DeptDTO rdept = deptList.get(i);
			Vector<Object>  v = new Vector<>();//3번 생성됨
			v.add(0,rdept.getDeptno());
			v.add(1,rdept.getDname());
			v.add(2,rdept.getLoc());
			dtm_dept.addRow(v);
		}		
		
	}//////////////////end of refreshData //////////////////
}

List & Map 구현

package com.step5;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
// ActionListener al = new DeptManager();
//자바는 단일 상속만 가능하다.- 다중상속은 불가함 - 다중상속의 단점을 보완하기 위해 인터페이스가 제공됨
//단 인터페이스는 여러개를 implements할 수 있다.(추상클래스, 인터페이스는 설계관점에서 중요함 - 특징, 컨벤션)
public class DeptManager2 extends JFrame implements ActionListener{
	//선언부
	List<Map<String, Object>> deptList = new ArrayList<>();//왜 전역변수로 하는가? 입력|수정|삭제|조회
	String header[] = {"부서번호","부서명","지역"};
	String datas[][] = new String[0][0];//2차배열 - 대괄호가 2쌍이 필요함
	//생성자의 파라미터를 통해서 서로 다른 클래스가 의존관계를 맺고 하나의 기능을 서비스 할 수  있다.
	//생성자도 파라미터를 여러개 갖을 수 있다. - 메소드 오버로딩
	DefaultTableModel dtm_dept = new DefaultTableModel(datas, header);//<table>-양식  자바가 있어야 DataSet구성함
	JTable jt_dept = new JTable(dtm_dept);
	JScrollPane jsp_dept = new JScrollPane(jt_dept);
	JPanel jp_north = new JPanel();
	JButton jbtnSelect = new JButton("조회");
	JButton jbtnDelete = new JButton("삭제");
	JButton jbtnAdd = new JButton("행추가");
	JButton jbtnDel = new JButton("행삭제");
	JButton jbtnExit = new JButton("종료");
	//생성자
	DeptManager2(){
		getDeptList();
		initDisplay();
	}////////////// end of DeptManager
	public List<Map<String,Object>> getDeptList(){
		Map<String,Object> map = new HashMap<>();//복사본
		map.put("DEPTNO", 10);
		map.put("DNAME", "영업부");
		map.put("LOC", "부산");
		deptList.add(map);
		map = new HashMap<>();
		map.put("DEPTNO", 20);
		map.put("DNAME", "개발부");
		map.put("LOC", "대구");
		deptList.add(map);
		map = new HashMap<>();
		map.put("DEPTNO", 30);
		map.put("DNAME", "인사부");
		map.put("LOC", "서울");
		deptList.add(map);
		return deptList;
	}
	//화면 처리부
	public void initDisplay() {
		jbtnSelect.addActionListener(this);
		jbtnDelete.addActionListener(this);
		jbtnAdd.addActionListener(this);//행추가
		jbtnDel.addActionListener(this);//행삭제
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jp_north.add(jbtnSelect);
		jp_north.add(jbtnDelete);
		jp_north.add(jbtnAdd);//행추가 JPanel붙이기
		jp_north.add(jbtnDel);
		jp_north.add(jbtnExit);
		this.add("North", jp_north);
		this.add("Center", jsp_dept);
		this.setSize(500, 400);//this:DeptManager
		this.setVisible(true);
	}//////////// end of initDisplay  /////////////
	//메인 메소드
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		DeptManager2 dm = new DeptManager2();//new JFrame()호출되는 것이다.
	}//////////////// end of main ////////////////
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed호출은 반드시 addActionListener가 있어야 됨");
		Object obj = e.getSource();
		//행삭제해 보기
		if(obj == jbtnDel) {
			//dtm_dept.removeRow(0);
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 행을 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}		
			else {
				dtm_dept.removeRow(index);
			}
		}
		//행추가해보기
		else if(obj == jbtnAdd) {
			//Vector addRow = new Vector();
			Object addRow2[] = new Object[3];
			dtm_dept.addRow(addRow2);
		}
		//너 삭제 할거니?
		else if(obj == jbtnDelete) {
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 데이터를 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}
			//여기로 못오게 함
			else {
				System.out.println(index);//index값을 add(int, E)  1 remove(1), 
				//insert here
				Map<String,Object> map = deptList.remove(index);
				System.out.println(map+", rdept.get(DEPTNO):"+map.get("DEPTNO"));
				//insert here - 삭제 성공하였습니다.
				if(map !=null) {
					JOptionPane.showMessageDialog(this, "삭제 성공하였습니다.","Info" , JOptionPane.INFORMATION_MESSAGE);
					refreshData();
				}else {
					JOptionPane.showMessageDialog(this, "삭제 실패하였습니다.","Info" , JOptionPane.ERROR_MESSAGE);
					return;
				}
			}
		}
		//너 조회버튼 누른거야?
		else if(obj == jbtnSelect) {
			System.out.println("조회버튼 클릭");//log
			//웹 개발이더라도 html이 데이터를 쥘수는 없다
			//html과 자바코드를 섞어쓰기가 가능한가? - 불가 - jsp공부함  - 자바자료구조를 JSON형식으로 넘기기
			//dtm_dept는 실제 데이터를 포용함
			//JTable은 클릭이벤트 같은 것은 가능함 - 실제 데이터를 쥐고 있지 못함
			//getRowCount는 데이터의 로우 수 반환 - 3건
			while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
				dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
			}
			for(int i=0;i<deptList.size();i++) {
				Map<String,Object> map = deptList.get(i);
				Vector<Object>  v = new Vector<>();//3번 생성됨
				v.add(0,map.get("DEPTNO"));
				v.add(1,map.get("DNAME"));
				v.add(2,map.get("LOC"));
				dtm_dept.addRow(v);
			}
		}////////////////// end of if ///////////////
		
	}///////////////////// end of actionPerformed
	//새로고침(F5) 구현하기
	public void refreshData() {
		while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
			dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
		}
		for(int i=0;i<deptList.size();i++) {
			Map<String,Object> map = deptList.get(i);
			Vector<Object>  v = new Vector<>();//3번 생성됨
			v.add(0,map.get("DEPTNO"));
			v.add(1,map.get("DNAME"));
			v.add(2,map.get("LOC"));
			dtm_dept.addRow(v);
		}	
	}//////////////////end of refreshData //////////////////
}

JDBC 연동

변경 전

package com.step5;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
// ActionListener al = new DeptManager();
//자바는 단일 상속만 가능하다.- 다중상속은 불가함 - 다중상속의 단점을 보완하기 위해 인터페이스가 제공됨
//단 인터페이스는 여러개를 implements할 수 있다.(추상클래스, 인터페이스는 설계관점에서 중요함 - 특징, 컨벤션)
public class DeptManager2 extends JFrame implements ActionListener{
	//선언부
	List<Map<String, Object>> deptList = new ArrayList<>();//왜 전역변수로 하는가? 입력|수정|삭제|조회
	String header[] = {"부서번호","부서명","지역"};
	String datas[][] = new String[0][0];//2차배열 - 대괄호가 2쌍이 필요함
	//생성자의 파라미터를 통해서 서로 다른 클래스가 의존관계를 맺고 하나의 기능을 서비스 할 수  있다.
	//생성자도 파라미터를 여러개 갖을 수 있다. - 메소드 오버로딩
	DefaultTableModel dtm_dept = new DefaultTableModel(datas, header);//<table>-양식  자바가 있어야 DataSet구성함
	JTable jt_dept = new JTable(dtm_dept);
	JScrollPane jsp_dept = new JScrollPane(jt_dept);
	JPanel jp_north = new JPanel();
	JButton jbtnSelect = new JButton("조회");
	JButton jbtnDelete = new JButton("삭제");
	JButton jbtnAdd = new JButton("행추가");
	JButton jbtnDel = new JButton("행삭제");
	JButton jbtnExit = new JButton("종료");
	//생성자
	DeptManager2(){
		getDeptList();
		initDisplay();
	}////////////// end of DeptManager
	public List<Map<String,Object>> getDeptList(){
		Map<String,Object> map = new HashMap<>();//복사본
		map.put("DEPTNO", 10);
		map.put("DNAME", "영업부");
		map.put("LOC", "부산");
		deptList.add(map);
		map = new HashMap<>();
		map.put("DEPTNO", 20);
		map.put("DNAME", "개발부");
		map.put("LOC", "대구");
		deptList.add(map);
		map = new HashMap<>();
		map.put("DEPTNO", 30);
		map.put("DNAME", "인사부");
		map.put("LOC", "서울");
		deptList.add(map);
		return deptList;
	}
	//화면 처리부
	public void initDisplay() {
		jbtnSelect.addActionListener(this);
		jbtnDelete.addActionListener(this);
		jbtnAdd.addActionListener(this);//행추가
		jbtnDel.addActionListener(this);//행삭제
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jp_north.add(jbtnSelect);
		jp_north.add(jbtnDelete);
		jp_north.add(jbtnAdd);//행추가 JPanel붙이기
		jp_north.add(jbtnDel);
		jp_north.add(jbtnExit);
		this.add("North", jp_north);
		this.add("Center", jsp_dept);
		this.setSize(500, 400);//this:DeptManager
		this.setVisible(true);
	}//////////// end of initDisplay  /////////////
	//메인 메소드
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		DeptManager2 dm = new DeptManager2();//new JFrame()호출되는 것이다.
	}//////////////// end of main ////////////////
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed호출은 반드시 addActionListener가 있어야 됨");
		Object obj = e.getSource();
		//행삭제해 보기
		if(obj == jbtnDel) {
			//dtm_dept.removeRow(0);
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 행을 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}		
			else {
				dtm_dept.removeRow(index);
			}
		}
		//행추가해보기
		else if(obj == jbtnAdd) {
			//Vector addRow = new Vector();
			Object addRow2[] = new Object[3];
			dtm_dept.addRow(addRow2);
		}
		//너 삭제 할거니?
		else if(obj == jbtnDelete) {
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 데이터를 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}
			//여기로 못오게 함
			else {
				System.out.println(index);//index값을 add(int, E)  1 remove(1), 
				//insert here
				Map<String,Object> map = deptList.remove(index);
				System.out.println(map+", rdept.get(DEPTNO):"+map.get("DEPTNO"));
				//insert here - 삭제 성공하였습니다.
				if(map !=null) {
					JOptionPane.showMessageDialog(this, "삭제 성공하였습니다.","Info" , JOptionPane.INFORMATION_MESSAGE);
					refreshData();
				}else {
					JOptionPane.showMessageDialog(this, "삭제 실패하였습니다.","Info" , JOptionPane.ERROR_MESSAGE);
					return;
				}
			}
		}
		//너 조회버튼 누른거야?
		else if(obj == jbtnSelect) {
			System.out.println("조회버튼 클릭");//log
			//웹 개발이더라도 html이 데이터를 쥘수는 없다
			//html과 자바코드를 섞어쓰기가 가능한가? - 불가 - jsp공부함  - 자바자료구조를 JSON형식으로 넘기기
			//dtm_dept는 실제 데이터를 포용함
			//JTable은 클릭이벤트 같은 것은 가능함 - 실제 데이터를 쥐고 있지 못함
			//getRowCount는 데이터의 로우 수 반환 - 3건
			while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
				dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
			}
			for(int i=0;i<deptList.size();i++) {
				Map<String,Object> map = deptList.get(i);
				Vector<Object>  v = new Vector<>();//3번 생성됨
				v.add(0,map.get("DEPTNO"));
				v.add(1,map.get("DNAME"));
				v.add(2,map.get("LOC"));
				dtm_dept.addRow(v);
			}
		}////////////////// end of if ///////////////
		
	}///////////////////// end of actionPerformed
	//새로고침(F5) 구현하기
	public void refreshData() {
		while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
			dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
		}
		for(int i=0;i<deptList.size();i++) {
			Map<String,Object> map = deptList.get(i);
			Vector<Object>  v = new Vector<>();//3번 생성됨
			v.add(0,map.get("DEPTNO"));
			v.add(1,map.get("DNAME"));
			v.add(2,map.get("LOC"));
			dtm_dept.addRow(v);
		}	
	}///

OracleTest

package com.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class OracleTest {
	DBConnectionMgr dbMgr = new DBConnectionMgr();
	Connection con = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	public OracleTest() {
	
	}
	public List<Map<String,Object>> getDeptList(){
		List<Map<String,Object>> dList = null;
		StringBuilder sql = new StringBuilder();
		try {
			sql.append("SELECT deptno, dname, loc FROM dept");
			con = dbMgr.getConnection();
			pstmt = con.prepareStatement(sql.toString());
			rs = pstmt.executeQuery();
			dList = new ArrayList<>();
			Map<String,Object> rmap =  null;
			while(rs.next()) {
				rmap = new HashMap<>();
				rmap.put("deptno", rs.getInt("deptno"));
				rmap.put("dname", rs.getString("dname"));
				rmap.put("loc", rs.getString("loc"));
				dList.add(rmap);
			}
		} catch (SQLException se) {
			System.out.println(se.toString());
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		return dList;
	}
	public static void main(String[] args) {
		OracleTest ot = new OracleTest();
		List<Map<String,Object>> dList = ot.getDeptList();
		for(int i=0;i<dList.size();i++) {
			Map<String,Object> map = dList.get(i);
			System.out.println(map);
		}
	}
}

DeptManager

package util;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import com.CollectionFrameWork.DeptDTO;
import com.google.gson.Gson;
import com.util.DBConnectionMgr;
// ActionListener al = new DeptManager();
//자바는 단일 상속만 가능하다.- 다중상속은 불가함 - 다중상속의 단점을 보완하기 위해 인터페이스가 제공됨
//단 인터페이스는 여러개를 implements할 수 있다.(추상클래스, 인터페이스는 설계관점에서 중요함 - 특징, 컨벤션)
public class DeptManager extends JFrame implements ActionListener{
	//선언부
	//JDBC API 를 활용하여 오라클 서버에서 부서목록 조회하기
	Connection 					con  	= null;//연결통로확보
	PreparedStatement 	pstmt 	= null;//Connection생성되야 PreparedStatement메모리 로딩됨
	ResultSet						rs			= null;//open..cursor..fectch..close 커서를 조작해서 원하는 정보를 반환받음
	//공통코드에서 재사용 가능한 메소드를 설계함
	DBConnectionMgr dbMgr = null;                                                       
	List<Map<String, Object>> deptList = new ArrayList<>();//왜 전역변수로 하는가? 입력|수정|삭제|조회
	String header[] = {"부서번호","부서명","지역"};
	String datas[][] = new String[0][0];//2차배열 - 대괄호가 2쌍이 필요함
	//생성자의 파라미터를 통해서 서로 다른 클래스가 의존관계를 맺고 하나의 기능을 서비스 할 수  있다.
	//생성자도 파라미터를 여러개 갖을 수 있다. - 메소드 오버로딩
	DefaultTableModel dtm_dept = new DefaultTableModel(datas, header);//<table>-양식  자바가 있어야 DataSet구성함
	JTable jt_dept = new JTable(dtm_dept);
	JScrollPane jsp_dept = new JScrollPane(jt_dept);
	JPanel jp_north = new JPanel();
	JButton jbtnSelect = new JButton("조회");
	JButton jbtnDelete = new JButton("삭제");
	JButton jbtnAdd = new JButton("행추가");
	JButton jbtnDel = new JButton("행삭제");
	JButton jbtnExit = new JButton("종료");
	//생성자
	//A a = new A();//기초
	//A a = A.getInstance();//복제본을 허락하지 않고 원본 하나만 관리한다. - 싱글톤 패턴
	//B  b = new A();//추상클래스 상속관계
	//C c = new A();//인터페이스 구현체 클래스
	DeptManager(){
		dbMgr  = DBConnectionMgr.getInstance();
		//Calendar cal = Calendar.getInstance();
		initDisplay();
	}////////////// end of DeptManager

	//화면 처리부
	public void initDisplay() {
		jbtnSelect.addActionListener(this);
		jbtnDelete.addActionListener(this);
		jbtnAdd.addActionListener(this);//행추가
		jbtnDel.addActionListener(this);//행삭제
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jp_north.add(jbtnSelect);
		jp_north.add(jbtnDelete);
		jp_north.add(jbtnAdd);//행추가 JPanel붙이기
		jp_north.add(jbtnDel);
		jp_north.add(jbtnExit);
		this.add("North", jp_north);
		this.add("Center", jsp_dept);
		this.setSize(500, 400);//this:DeptManager
		this.setVisible(true);
	}//////////// end of initDisplay  /////////////
	//select가 모든 업무 페이지의 시작 페이지이므로  맡은 업무의 첫 시작임 - 
	public List<DeptDTO> getDTOList(){//먼저 연습하고 Map을 연습 할것
		System.out.println("제네릭 타입을 getter/setter로 처리할때");
		List<DeptDTO> list = new ArrayList<>();
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT deptno, dname, loc FROM dept");//4건 모두 조회함 10,20,30,40
		try {
			//아래 코드에서 NullPointerException이 발생 했다면 생성자에서 객체 주입이 안됨
			//dbMgr.코드에서 직접적인 원인이 있음
			//DBConnectionMgr이 생성되어야 getConnection메소드를 호출할 수 있을 것이고
			//호출이 되어야 리턴값으로 Connection 객체를 주입 받음
			con = dbMgr.getConnection();
			pstmt = con.prepareStatement(sql.toString());
			rs = pstmt.executeQuery();
			DeptDTO dto = null;
			while(rs.next()) {
				//아래 코드에서 반복문이 실행될 때마다 서로 다른 주소번지가 4개 만들어지니까
				dto = new DeptDTO(rs.getInt("deptno"), rs.getString("dname"),rs.getString("loc"));
				//아래 코드를 작성하지 않으면 4개의 정보가 모두 유지되지 않음
				list.add(dto);//0, null, null, 0 ,null, null, 0,null, null, 0 , null,null
			}
			System.out.println(list);
			//자바를 통해서 DB연동한 후에 후처리하기(자바컬렉션 프레임워크를 JSON포맷으로 변경함)
			//Gson g = new Gson();브라우저를 통해서 출력할 때만 사용하면 된다. - JSON포맷이어야 javascript에서 꺼내기가 가능함
			//String temp = g.toJson(list);
		} catch (SQLException se) {
			System.out.println(se.toString());//부적합한 식별자  - 컬럼명이 존재하지 않을 때 - SQLException해당됨
		} catch (Exception e) {
			e.printStackTrace();//stack메모리에 쌓여있는 에러 메시지 히스토리를 볼 수  있다.(라인번호와 함께 메시지 출력됨)
		}
		return list;
	}
	public List<Map<String,Object>> getMapList(){//2개 이상의 테이블 조인시 - 이것으로 연습 더 많이
		System.out.println("제네릭 타입을 Map으로 처리할 때");
		List<Map<String,Object>> list = new ArrayList<>();
		return list;
	}	
	//메인 메소드
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		DeptManager dm = new DeptManager();//new JFrame()호출되는 것이다.
	}//////////////// end of main ////////////////
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed호출은 반드시 addActionListener가 있어야 됨");
		Object obj = e.getSource();
		//행삭제해 보기
		if(obj == jbtnDel) {
			//dtm_dept.removeRow(0);
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 행을 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}		
			else {
				dtm_dept.removeRow(index);
			}
		}
		//행추가해보기
		else if(obj == jbtnAdd) {
			//Vector addRow = new Vector();
			Object addRow2[] = new Object[3];
			dtm_dept.addRow(addRow2);
		}
		//너 삭제 할거니?
		else if(obj == jbtnDelete) {
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 데이터를 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}
			//여기로 못오게 함
			else {
				System.out.println(index);//index값을 add(int, E)  1 remove(1), 
				//insert here
				Map<String,Object> map = deptList.remove(index);
				System.out.println(map+", rdept.get(DEPTNO):"+map.get("DEPTNO"));
				//insert here - 삭제 성공하였습니다.
				if(map !=null) {
					JOptionPane.showMessageDialog(this, "삭제 성공하였습니다.","Info" , JOptionPane.INFORMATION_MESSAGE);
					refreshData();
				}else {
					JOptionPane.showMessageDialog(this, "삭제 실패하였습니다.","Info" , JOptionPane.ERROR_MESSAGE);
					return;
				}
			}
		}
		//너 조회버튼 누른거야?
		else if(obj == jbtnSelect) {
			System.out.println("조회버튼 클릭");//log
			//웹 개발이더라도 html이 데이터를 쥘수는 없다
			//html과 자바코드를 섞어쓰기가 가능한가? - 불가 - jsp공부함  - 자바자료구조를 JSON형식으로 넘기기
			//dtm_dept는 실제 데이터를 포용함
			//JTable은 클릭이벤트 같은 것은 가능함 - 실제 데이터를 쥐고 있지 못함
			//getRowCount는 데이터의 로우 수 반환 - 3건
			while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
				dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
			}
			for(int i=0;i<deptList.size();i++) {
				Map<String,Object> map = deptList.get(i);
				Vector<Object>  v = new Vector<>();//3번 생성됨
				v.add(0,map.get("DEPTNO"));
				v.add(1,map.get("DNAME"));
				v.add(2,map.get("LOC"));
				dtm_dept.addRow(v);
			}
		}////////////////// end of if ///////////////
		
	}///////////////////// end of actionPerformed
	//새로고침(F5) 구현하기
	public void refreshData() {
		while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
			dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
		}
		for(int i=0;i<deptList.size();i++) {
			Map<String,Object> map = deptList.get(i);
			Vector<Object>  v = new Vector<>();//3번 생성됨
			v.add(0,map.get("DEPTNO"));
			v.add(1,map.get("DNAME"));
			v.add(2,map.get("LOC"));
			dtm_dept.addRow(v);
		}	
	}//////////////////end of refreshData //////////////////
}

DBConnectionMgr

package com.util;

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

public class DBConnectionMgr {
	static DBConnectionMgr  dbMgr = null;
	/*
	 * null로 초기화 하는 이유는 nullcheck를 해서 null일 때만 새로 인스턴스화 하고 null이 아닐 떄는 계속 사용한다.
	 * 
	 */
	Connection con = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	public static final String _DRIVER = "oracle.jdbc.driver.OracleDriver";
	public static final String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl11";
	public static final String user = "scott";
	public static final String pw = "tiger";
	public static DBConnectionMgr getInstance()
	{
		
		if(dbMgr == null)
		{
			dbMgr =  new DBConnectionMgr();
		}
		return dbMgr;
		
	}
	 // 리턴 타입으로 연결통로를 확보한 con을 얻는다.
	// connection(url,계정정보가 일치해야함) - PrepareStatement(쿼리문 전달, 처리 요청한다.) - ResultSet(커서를 조작하는 메소드) 를 제공 받는다.
	// 앞에 객체가 주입되지 않으면 나머지 뒤에는 모두 null인 상태에 놓인다.
	
	public Connection getConnection()
	{
		/*
		 * 예외처리 시 try..catch 블록을 사용하는데 멀티 블록이 가능함. 단 하위에서 상위클래스로 처리함.
		 * 
		 * 중복으로 예외처리를 하면 되는데 범위를 따져야한다. -> 적은 범위를 처음으로 했으면 다음엔 더 넓은 범위 
		 * 그 다음은 더 넓은 범위로 해야한다.
		 */
	
		try {
			// 각 제조사의 드라이버 클래스를 로딩하기
			Class.forName("oracle.jdbc.driver.OracleDriver");
			// 물리적으로 떨어져 있는 오라클 서버와 연결통로 확보 
			con = DriverManager.getConnection(url,user,pw);
		}catch(ClassNotFoundException e)
		{
			System.out.println("ojdbc6.jar를 설정하지 않았다. 그래서 클래스를 못 찾는다.");
		
		}
		
		catch (Exception e) { // 비번이 맞지 않을 때
			e.printStackTrace();
		}
		return con;
	}
	
	/*
	 * 29 && 31번 호출 시 에러가 없다면 catch 블록은 실행하지 않는다.
	 */
	public static void freeConnection(ResultSet rs, PreparedStatement pstmt, Connection con){
		try {
			if(rs !=null) rs.close();
			if(pstmt !=null) pstmt.close();
			if(con !=null) con.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void freeConnection(PreparedStatement pstmt, Connection con){
		try {
			if(pstmt !=null) pstmt.close();
			if(con !=null) con.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void freeConnection(ResultSet rs, CallableStatement cstmt, Connection con){
		try {
			if(rs !=null) rs.close();
			if(cstmt !=null) cstmt.close();
			if(con !=null) con.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void freeConnection(CallableStatement cstmt, Connection con){
		try {
			if(cstmt !=null) cstmt.close();
			if(con !=null) con.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

  • 싱글톤에 대한 예제
package com.step6;

import java.sql.Connection;

import com.util.DBConnectionMgr;

public class Exception1 {
 DBConnectionMgr dbMgr =null;
 Connection  con = null;
	// 여기서 null 값으로 초기화 하는 이유는 사용자로부터 필요할 때 입력 받으려고 
	// new Exception() 했을 때 메모리에 상주된다. -> 이 부분은 몰랐음. 확인 해야함.
	public Exception1()
	{
			dbMgr = DBConnectionMgr.getInstance();
			System.out.println("Exception() " + dbMgr);
			test();
		
	}
	public void test()
	{
		System.out.println("test() : " + dbMgr);
		// 인터페이스가 getConnection 호출을 통해서 주소번지를 갖게 되었다. 
		// 메모리에 로딩되었다. ( 로딩되지 않으면 NullPointException 이다. )
		con = dbMgr.getConnection();
		System.out.println(con);
		try
		{
			
		}
		catch(Exception e)
		{
			
		}
	}
	public static void main(String[] args) {
		new Exception1();
		
	}

}

DBTest

package util;

public class DBTest {
	public static void main(String[] args) {
		DeptManager dm = new DeptManager();
		dm.getDTOList();
	}

}
-------------------------------------------
--------------------------------------------
제네릭 타입을 getter/setter로 처리할때
[com.CollectionFrameWork.DeptDTO@7bab3f1a, com.CollectionFrameWork.DeptDTO@437da279, com.CollectionFrameWork.DeptDTO@23c30a20, com.CollectionFrameWork.DeptDTO@1e1a0406]
actionPerformed호출은 반드시 addActionListener가 있어야 됨
조회버튼 클릭
actionPerformed호출은 반드시 addActionListener가 있어야 됨
actionPerformed호출은 반드시 addActionListener가 있어야 됨
actionPerformed호출은 반드시 addActionListener가 있어야 됨
actionPerformed호출은 반드시 addActionListener가 있어야 됨
actionPerformed호출은 반드시 addActionListener가 있어야 됨
조회버튼 클릭
actionPerformed호출은 반드시 addActionListener가 있어야 됨
조회버튼 클릭

ArrayList로 교체하기

  • 2가지 방법이 있다. 1. 지역변수로 선언한 부분 || 2. 전역변수로 선언한 경우

  • List<Map<String, Object>> deptList = new ArrayList<>(); 얘를 말하는 것.

    • List 방법
    • List & Map 이용

ArrayList 전체코드

package util;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import com.CollectionFrameWork.DeptDTO;
import com.google.gson.Gson;
import com.util.DBConnectionMgr;
// ActionListener al = new DeptManager();
//자바는 단일 상속만 가능하다.- 다중상속은 불가함 - 다중상속의 단점을 보완하기 위해 인터페이스가 제공됨
//단 인터페이스는 여러개를 implements할 수 있다.(추상클래스, 인터페이스는 설계관점에서 중요함 - 특징, 컨벤션)
public class DeptManager extends JFrame implements ActionListener{
	//선언부
	//JDBC API 를 활용하여 오라클 서버에서 부서목록 조회하기
	Connection 					con  	= null;//연결통로확보
	PreparedStatement 	pstmt 	= null;//Connection생성되야 PreparedStatement메모리 로딩됨
	ResultSet						rs			= null;//open..cursor..fectch..close 커서를 조작해서 원하는 정보를 반환받음
	//공통코드에서 재사용 가능한 메소드를 설계함
	DBConnectionMgr dbMgr = null;                                                       
	List<Map<String, Object>> deptList = new ArrayList<>();//왜 전역변수로 하는가? 입력|수정|삭제|조회
	String header[] = {"부서번호","부서명","지역"};
	String datas[][] = new String[0][0];//2차배열 - 대괄호가 2쌍이 필요함
	//생성자의 파라미터를 통해서 서로 다른 클래스가 의존관계를 맺고 하나의 기능을 서비스 할 수  있다.
	//생성자도 파라미터를 여러개 갖을 수 있다. - 메소드 오버로딩
	DefaultTableModel dtm_dept = new DefaultTableModel(datas, header);//<table>-양식  자바가 있어야 DataSet구성함
	JTable jt_dept = new JTable(dtm_dept);
	JScrollPane jsp_dept = new JScrollPane(jt_dept);
	JPanel jp_north = new JPanel();
	JButton jbtnSelect = new JButton("조회");
	JButton jbtnDelete = new JButton("삭제");
	JButton jbtnAdd = new JButton("행추가");
	JButton jbtnDel = new JButton("행삭제");
	JButton jbtnExit = new JButton("종료");
	//생성자
	//A a = new A();//기초
	//A a = A.getInstance();//복제본을 허락하지 않고 원본 하나만 관리한다. - 싱글톤 패턴
	//B  b = new A();//추상클래스 상속관계
	//C c = new A();//인터페이스 구현체 클래스
	DeptManager(){
		dbMgr  = DBConnectionMgr.getInstance();
		//Calendar cal = Calendar.getInstance();
		initDisplay();
	}////////////// end of DeptManager

	//화면 처리부
	public void initDisplay() {
		jbtnSelect.addActionListener(this);
		jbtnDelete.addActionListener(this);
		jbtnAdd.addActionListener(this);//행추가
		jbtnDel.addActionListener(this);//행삭제
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jp_north.add(jbtnSelect);
		jp_north.add(jbtnDelete);
		jp_north.add(jbtnAdd);//행추가 JPanel붙이기
		jp_north.add(jbtnDel);
		jp_north.add(jbtnExit);
		this.add("North", jp_north);
		this.add("Center", jsp_dept);
		this.setSize(500, 400);//this:DeptManager
		this.setVisible(true);
	}//////////// end of initDisplay  /////////////
	//select가 모든 업무 페이지의 시작 페이지이므로  맡은 업무의 첫 시작임 - 
	public List<DeptDTO> getDTOList(){//먼저 연습하고 Map을 연습 할것
		System.out.println("제네릭 타입을 getter/setter로 처리할때");
		List<DeptDTO> list = new ArrayList<>();
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT deptno, dname, loc FROM dept");//4건 모두 조회함 10,20,30,40
		try {
			//아래 코드에서 NullPointerException이 발생 했다면 생성자에서 객체 주입이 안됨
			//dbMgr.코드에서 직접적인 원인이 있음
			//DBConnectionMgr이 생성되어야 getConnection메소드를 호출할 수 있을 것이고
			//호출이 되어야 리턴값으로 Connection 객체를 주입 받음
			con = dbMgr.getConnection();
			pstmt = con.prepareStatement(sql.toString());
			rs = pstmt.executeQuery();
			DeptDTO dto = null;
			while(rs.next()) {
				//아래 코드에서 반복문이 실행될 때마다 서로 다른 주소번지가 4개 만들어지니까
				dto = new DeptDTO(rs.getInt("deptno"), rs.getString("dname"),rs.getString("loc"));
				//아래 코드를 작성하지 않으면 4개의 정보가 모두 유지되지 않음
				list.add(dto);//0, null, null, 0 ,null, null, 0,null, null, 0 , null,null
			}
			System.out.println(list);
			//자바를 통해서 DB연동한 후에 후처리하기(자바컬렉션 프레임워크를 JSON포맷으로 변경함)
			//Gson g = new Gson();브라우저를 통해서 출력할 때만 사용하면 된다. - JSON포맷이어야 javascript에서 꺼내기가 가능함
			//String temp = g.toJson(list);
		} catch (SQLException se) {
			System.out.println(se.toString());//부적합한 식별자  - 컬럼명이 존재하지 않을 때 - SQLException해당됨
		} catch (Exception e) {
			e.printStackTrace();//stack메모리에 쌓여있는 에러 메시지 히스토리를 볼 수  있다.(라인번호와 함께 메시지 출력됨)
		}
		return list;
	}
	public List<Map<String,Object>> getMapList(){//2개 이상의 테이블 조인시 - 이것으로 연습 더 많이
		System.out.println("제네릭 타입을 Map으로 처리할 때");
		List<Map<String,Object>> list = new ArrayList<>();
		return list;
	}	
	//메인 메소드
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		DeptManager dm = new DeptManager();//new JFrame()호출되는 것이다.
	}//////////////// end of main ////////////////
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed호출은 반드시 addActionListener가 있어야 됨");
		Object obj = e.getSource();
		//행삭제해 보기
		if(obj == jbtnDel) {
			//dtm_dept.removeRow(0);
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 행을 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}		
			else {
				dtm_dept.removeRow(index);
			}
		}
		//행추가해보기
		else if(obj == jbtnAdd) {
			//Vector addRow = new Vector();
			Object addRow2[] = new Object[3];
			dtm_dept.addRow(addRow2);
		}
		//너 삭제 할거니?
		else if(obj == jbtnDelete) {
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 데이터를 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}
			//여기로 못오게 함
			else {
				System.out.println(index);//index값을 add(int, E)  1 remove(1), 
				//insert here
				Map<String,Object> map = deptList.remove(index);
				System.out.println(map+", rdept.get(DEPTNO):"+map.get("DEPTNO"));
				//insert here - 삭제 성공하였습니다.
				if(map !=null) {
					JOptionPane.showMessageDialog(this, "삭제 성공하였습니다.","Info" , JOptionPane.INFORMATION_MESSAGE);
					refreshData();
				}else {
					JOptionPane.showMessageDialog(this, "삭제 실패하였습니다.","Info" , JOptionPane.ERROR_MESSAGE);
					return;
				}
			}
		}
		//너 조회버튼 누른거야?
		else if(obj == jbtnSelect) {
			System.out.println("조회버튼 클릭");//log
			List<DeptDTO> list = getDTOList();//오라클 서버에서 조회한 결과를 쥐고 있다. - 리턴타입이 쥐고 있다.
			while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
				dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
			}
			
			for(int i=0;i<list.size();i++) {//list.size()=4이다. 10,20,30,40
				DeptDTO dept = list.get(i);
				Vector<Object>  v = new Vector<>();//3번 생성됨
				v.add(0, dept.getDeptno());
				v.add(1,dept.getDname());
				v.add(2,dept.getLoc());
				//addRow메소드의 오버로딩은 2가지 임 - 1)Vector, 2)Object[]
				dtm_dept.addRow(v);//4번 반복 되니까 - 로우에 추가하는 코드를 4번 실행함 - list.size()=4
			}
		}////////////////// end of if ///////////////
		
	}///////////////////// end of actionPerformed
	//새로고침(F5) 구현하기
	public void refreshData() {
		while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
			dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
		}
		for(int i=0;i<deptList.size();i++) {
			Map<String,Object> map = deptList.get(i);
			Vector<Object>  v = new Vector<>();//3번 생성됨
			v.add(0,map.get("DEPTNO"));
			v.add(1,map.get("DNAME"));
			v.add(2,map.get("LOC"));
			dtm_dept.addRow(v);
		}}}	
	

ArrayList

		//너 조회버튼 누른거야?
		else if(obj == jbtnSelect) {
			List<DeptDTO> list = getDTOList(); 
			System.out.println("조회버튼 클릭");
			while(dtm_dept.getRowCount()>0) {
				dtm_dept.removeRow(0);
			}
			for(int i=0;i<list.size();i++) { // list.size(4)이다. -> 
				DeptDTO dept = list.get(i);
				Vector<Object>  v = new Vector<>();
				v.add(0,dept.getDeptno());
				v.add(1,dept.getLoc());
				v.add(2,dept.getDname());
				dtm_dept.addRow(v);
				
				
			}
		}
		
	}
	/*
	 * 2가지 방법이 있다. 1. 지역변수로 선언한 부분  || 2. 전역변수로 선언한 경우 
	 * List<Map<String, Object>> deptList = new ArrayList<>(); 이친구 
	 */

SQL로 알아보자!


SELECT empno, ename, sal, dname
from emp,dept
where emp.deptno = dept.deptno;


select deptno from dept; -- 인덱스를 읽어서 조회를한다.+ 인덱스를 정렬을 할 수 있다.

select dname from dept; -- 테이블을 acess하여 조회한다.


-- 1.DML문을 파싱한다.
-- 2.DBMS매니저에게 실행계획을 작성하여 옵티마이저에게 넘긴다.
-- 3.옵티마이저가 실행계획을 따라서 데이터를 찾음
-- 4.Open(객체 접근)...cursor(ResultSet) ..fetch .. close
--

Map으로 교체하기

package com.step5;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import com.google.gson.Gson;
import com.util.DBConnectionMgr;
// ActionListener al = new DeptManager();
//자바는 단일 상속만 가능하다.- 다중상속은 불가함 - 다중상속의 단점을 보완하기 위해 인터페이스가 제공됨
//단 인터페이스는 여러개를 implements할 수 있다.(추상클래스, 인터페이스는 설계관점에서 중요함 - 특징, 컨벤션)
public class DeptManager3 extends JFrame implements ActionListener{
	//선언부
	//JDBC API 를 활용하여 오라클 서버에서 부서목록 조회하기
	Connection 					con  	= null;//연결통로확보
	PreparedStatement 	pstmt 	= null;//Connection생성되야 PreparedStatement메모리 로딩됨
	//데이터베이스가 지원하는 커서를 조작하는데 필요한 메소드를 정의하고 있는 인터페이스이다.
	ResultSet						rs			= null;//open..cursor..fectch..close 커서를 조작해서 원하는 정보를 반환받음
	//공통코드에서 재사용 가능한 메소드를 설계함
	DBConnectionMgr dbMgr = null;                                                       
	List<Map<String, Object>> deptList = new ArrayList<>();//왜 전역변수로 하는가? 입력|수정|삭제|조회
	String header[] = {"부서번호","부서명","지역"};
	String datas[][] = new String[0][0];//2차배열 - 대괄호가 2쌍이 필요함
	//생성자의 파라미터를 통해서 서로 다른 클래스가 의존관계를 맺고 하나의 기능을 서비스 할 수  있다.
	//생성자도 파라미터를 여러개 갖을 수 있다. - 메소드 오버로딩
	DefaultTableModel dtm_dept = new DefaultTableModel(datas, header);//<table>-양식  자바가 있어야 DataSet구성함
	JTable jt_dept = new JTable(dtm_dept);
	JScrollPane jsp_dept = new JScrollPane(jt_dept);
	JPanel jp_north = new JPanel();
	JButton jbtnSelect = new JButton("조회");
	JButton jbtnDelete = new JButton("삭제");
	JButton jbtnAdd = new JButton("행추가");
	JButton jbtnDel = new JButton("행삭제");
	JButton jbtnExit = new JButton("종료");
	//생성자
	//A a = new A();//기초
	//A a = A.getInstance();//복제본을 허락하지 않고 원본 하나만 관리한다. - 싱글톤 패턴
	//B  b = new A();//추상클래스 상속관계
	//C c = new A();//인터페이스 구현체 클래스
	//접근제한자가 없는 경우는 friendly상태라 하는데
	//다른 패키지에서 접근이 불가능한 상태임
	//public>protected(패키지가 다르더라도 서로 상속관계이면 접근가능함)>friendly상태>private
	public DeptManager3(){
		//메소드를 통해서 객체를 주입받고 있는데 .연산자 앞에 인스턴스변수가 아니라 클래스 타입이 직접 사용되었다.
		dbMgr  = DBConnectionMgr.getInstance();//초기화 하였다.
		//Calendar cal = Calendar.getInstance();
		initDisplay();
	}////////////// end of DeptManager

	//화면 처리부
	public void initDisplay() {
		jbtnSelect.addActionListener(this);
		jbtnDelete.addActionListener(this);
		jbtnAdd.addActionListener(this);//행추가
		jbtnDel.addActionListener(this);//행삭제
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jp_north.add(jbtnSelect);
		jp_north.add(jbtnDelete);
		jp_north.add(jbtnAdd);//행추가 JPanel붙이기
		jp_north.add(jbtnDel);
		jp_north.add(jbtnExit);
		this.add("North", jp_north);
		this.add("Center", jsp_dept);
		this.setSize(500, 400);//this:DeptManager
		this.setVisible(true);
	}//////////// end of initDisplay  /////////////
	//select가 모든 업무 페이지의 시작 페이지이므로  맡은 업무의 첫 시작임 - 
	//어떤 경우에 제네릭을 Map으로 가져갈 것인가? -  List<Map<String,Object>> -> 조인시에 선택한다
	//현재 메소드 getDTOList는 무엇이 문제인가?
	public List<DeptDTO> getDTOList(){//먼저 연습하고 Map을 연습 할것
		System.out.println("제네릭 타입을 getter/setter로 처리할때");
		List<DeptDTO> list = new ArrayList<>();//list.size()=0
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT deptno, dname, loc FROM dept");//4건 모두 조회함 10,20,30,40
		try {
			//아래 코드에서 NullPointerException이 발생 했다면 생성자에서 객체 주입이 안됨
			//dbMgr.코드에서 직접적인 원인이 있음
			//DBConnectionMgr이 생성되어야 getConnection메소드를 호출할 수 있을 것이고
			//호출이 되어야 리턴값으로 Connection 객체를 주입 받음
			con = dbMgr.getConnection();
			pstmt = con.prepareStatement(sql.toString());
			rs = pstmt.executeQuery();
			DeptDTO dto = null;
			while(rs.next()) {
				//아래 코드에서 반복문이 실행될 때마다 서로 다른 주소번지가 4개 만들어지니까
				//문제점 - DeptDTO는 테이블 dept테이블을 클래스로 설계한 것이다.
				dto = new DeptDTO(rs.getInt("deptno"), rs.getString("dname"),rs.getString("loc"));
				//아래 코드를 작성하지 않으면 4개의 정보가 모두 유지되지 않음
				list.add(dto);//0, null, null, 0 ,null, null, 0,null, null, 0 , null,null
			}
			System.out.println(list);
			//자바를 통해서 DB연동한 후에 후처리하기(자바컬렉션 프레임워크를 JSON포맷으로 변경함)
			//Gson g = new Gson();브라우저를 통해서 출력할 때만 사용하면 된다. - JSON포맷이어야 javascript에서 꺼내기가 가능함
			//String temp = g.toJson(list);
		} catch (SQLException se) {
			System.out.println(se.toString());//부적합한 식별자  - 컬럼명이 존재하지 않을 때 - SQLException해당됨
		} catch (Exception e) {
			e.printStackTrace();//stack메모리에 쌓여있는 에러 메시지 히스토리를 볼 수  있다.(라인번호와 함께 메시지 출력됨)
		}
		return list;
	}
	public List<Map<String,Object>> getMapList(){//2개 이상의 테이블 조인시 - 이것으로 연습 더 많이
		System.out.println("제네릭 타입을 Map으로 처리할 때");
		List<Map<String,Object>> list = new ArrayList<>();
		//StringBuffer는 스레드안전, StringBuilder 불안전하다- 인터셉트를 당할 수 있다. - 로컬이니까 괜찮아
		StringBuilder sql = new StringBuilder();//String과 비교할 때 하나로 관리를 함 - 메모리에 대한 이익이 있다.
		//sql.append("SELECT deptno, dname, loc FROM dept");//4건 모두 조회함 10,20,30,40
		sql.append("SELECT empno, ename, sal, dname"); 
		sql.append("  FROM emp, dept               ");
		sql.append(" WHERE emp.deptno = dept.deptno");
		try {
			//아래 코드에서 NullPointerException이 발생 했다면 생성자에서 객체 주입이 안됨
			//dbMgr.코드에서 직접적인 원인이 있음
			//DBConnectionMgr이 생성되어야 getConnection메소드를 호출할 수 있을 것이고
			//호출이 되어야 리턴값으로 Connection 객체를 주입 받음
			con = dbMgr.getConnection();
			pstmt = con.prepareStatement(sql.toString());
			rs = pstmt.executeQuery();
			Map<String,Object> map = null;
			while(rs.next()) {
				//아래 코드에서 반복문이 실행될 때마다 서로 다른 주소번지가 4개 만들어지니까
				//문제점 - DeptDTO는 테이블 dept테이블을 클래스로 설계한 것이다.
				//사용자 정의 DTO클래스 처럼 생성자를 만들어서 사용불가함 - 제공받는 클래스 이다.
				map = new HashMap<>();
				map.put("empno", rs.getInt("empno"));
				map.put("ename", rs.getString("ename"));
				map.put("sal", rs.getInt("sal"));
				map.put("dname", rs.getString("dname"));
				//아래 코드를 작성하지 않으면 14개의 정보가 모두 유지되지 않음
				//사원의 수가 14명이다.
				list.add(map);//0, null, null, 0 ,null, null, 0,null, null, 0 , null,null
			}
			System.out.println(list);
			//자바를 통해서 DB연동한 후에 후처리하기(자바컬렉션 프레임워크를 JSON포맷으로 변경함)
			//Gson g = new Gson();브라우저를 통해서 출력할 때만 사용하면 된다. - JSON포맷이어야 javascript에서 꺼내기가 가능함
			//String temp = g.toJson(list);
		} catch (SQLException se) {
			System.out.println(se.toString());//부적합한 식별자  - 컬럼명이 존재하지 않을 때 - SQLException해당됨
		} catch (Exception e) {
			e.printStackTrace();//stack메모리에 쌓여있는 에러 메시지 히스토리를 볼 수  있다.(라인번호와 함께 메시지 출력됨)
		}		
		
		return list;
	}	
	//메인 메소드
	public static void main(String[] args) {
		JFrame.setDefaultLookAndFeelDecorated(true);
		DeptManager3 dm = new DeptManager3();//new JFrame()호출되는 것이다.
	}//////////////// end of main ////////////////
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("actionPerformed호출은 반드시 addActionListener가 있어야 됨");
		Object obj = e.getSource();
		//행삭제해 보기
		if(obj == jbtnDel) {
			//dtm_dept.removeRow(0);
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 행을 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}		
			else {
				dtm_dept.removeRow(index);
			}
		}
		//행추가해보기
		else if(obj == jbtnAdd) {
			//Vector addRow = new Vector();
			Object addRow2[] = new Object[3];
			dtm_dept.addRow(addRow2);
		}
		//너 삭제 할거니?
		else if(obj == jbtnDelete) {
			int index = jt_dept.getSelectedRow();//사용자가 선택한 로우의 index값을 반환함
			if(index<0) {//-1반환(EOF)
				JOptionPane.showMessageDialog(this,"삭제할 데이터를 선택하시오.","INFO", JOptionPane.INFORMATION_MESSAGE);
				return;//메소드 탈출
			}
			//여기로 못오게 함
			else {
				System.out.println(index);//index값을 add(int, E)  1 remove(1), 
				//insert here
				Map<String,Object> map = deptList.remove(index);
				System.out.println(map+", rdept.get(DEPTNO):"+map.get("DEPTNO"));
				//insert here - 삭제 성공하였습니다.
				if(map !=null) {
					JOptionPane.showMessageDialog(this, "삭제 성공하였습니다.","Info" , JOptionPane.INFORMATION_MESSAGE);
					refreshData();
				}else {
					JOptionPane.showMessageDialog(this, "삭제 실패하였습니다.","Info" , JOptionPane.ERROR_MESSAGE);
					return;
				}
			}
		}
		//너 조회버튼 누른거야?
		else if(obj == jbtnSelect) {
			System.out.println("조회버튼 클릭");//log
			List<DeptDTO> list = getDTOList();//오라클 서버에서 조회한 결과를 쥐고 있다. - 리턴타입이 쥐고 있다.
			while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
				dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
			}
			
			for(int i=0;i<list.size();i++) {//list.size()=4이다. 10,20,30,40
				DeptDTO dept = list.get(i);
				Vector<Object>  v = new Vector<>();//3번 생성됨
				v.add(0, dept.getDeptno());
				v.add(1,dept.getDname());
				v.add(2,dept.getLoc());
				//addRow메소드의 오버로딩은 2가지 임 - 1)Vector, 2)Object[]
				dtm_dept.addRow(v);//4번 반복 되니까 - 로우에 추가하는 코드를 4번 실행함 - list.size()=4
			}
		}////////////////// end of if ///////////////
		
	}///////////////////// end of actionPerformed
	//새로고침(F5) 구현하기
	public void refreshData() {
		while(dtm_dept.getRowCount()>0) {//dtm은 데이터셋(자바측)받는 클래스이다.
			dtm_dept.removeRow(0);//0번째 로우를 지우는 이유는 로우가 삭제 될때 마다 dtm의 로우수가 줄어든다. - 왜?
		}
		for(int i=0;i<deptList.size();i++) {
			Map<String,Object> map = deptList.get(i);
			Vector<Object>  v = new Vector<>();//3번 생성됨
			v.add(0,map.get("DEPTNO"));
			v.add(1,map.get("DNAME"));
			v.add(2,map.get("LOC"));
			dtm_dept.addRow(v);
		}	
	}//////////////////end of refreshData //////////////////
}
profile
아는만큼보인다.

0개의 댓글