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
어떤 메소드를 설계해야 하나? - 입력,수정,삭제,조회
삭제하기
성공 했을 때
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
}
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);
}
}
}
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)
+
삭제 메소드 추가하기 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 //////////////////
}
초기상태
+
행추가만 하는 부분 구현하기
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이다.
}
------------------------------------
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 //////////////////
}
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 //////////////////
}
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);
}
}///
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);
}
}
}
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 //////////////////
}
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();
}
}
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가 있어야 됨
조회버튼 클릭
2가지 방법이 있다. 1. 지역변수로 선언한 부분 || 2. 전역변수로 선언한 경우
List<Map<String, Object>> deptList = new 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);
}}}
//너 조회버튼 누른거야?
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
--
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 //////////////////
}