List는 Row 관리한다.
Generic 타입은 Col에 해당하는 값을 관리한다.
VO / MAP타입을 사용할 수 있는데 VO타입에는 타입이 정확해서 형전환을 할 필요가 없지만 Map은 객체타입으로 받기 때문에 그 값을 가지고 놀 때는 형 전환을 해야한다.
제네릭타입에는 멀티타입으로 적을 수 없어서 2개 이상의 집합을 조인했을 경우 VO타입 보다는 MAP을 사용하는게 복잡도를 줄일 수 있다.
Spring - JPA API - Hibernate사용함 - sql문이 없다.
sql은 없지만 클래스 설계를 해야 한다.
업무적인 depth가 깊어지면 조인대상 테이블이 4~5개 이상이다
무한 루프(반복) - 재귀호출
자바API를 활용하여 오라클 서버(동기화, 데이터영속성 보장)와 통신하기
java.sql.* - 커넥션 풀을 사용하지 않고....
javax.sql.* - 엔터프라이즈 서버(중간에 미들웨어 관리:EJB기술-Spring 경량서비스)가 제공하는 커넥션 풀을 사용할 때
4단계
물리적으로 떨어져 있는 서버와 연결통로를 확보하기
(전처리 부분 : 각 벤더가 제공하는 드라이버 클래스를 로딩하기) - ojdbc6.jar배포 - 운영서버에 배포시 첨부해야 함
서버의 ip주소 , port, scott, tiger - 상수로 처리해서 캡슐화 해서
java.sql.Connection(Interface)
DML문(SELECT, INSERT, UPDATE, DELETE) - 데이터 조작어
SELECT - 단순 검색 - 물리적인 테이블에 값을 변경하지 않음 - commit, rollback대상이 아님
INSERT, UPDATE, DELETE는 commit과 rollback의 대상임 - 물리적인 변화가 있다
DELETE - row가 전체 삭제 됨 - 컬럼명에 해당하는 셀만 삭제하는 것 불가함
INSERT는 없던 row를 새로 추가함 - add
sql문을 자바로 작성하여 오라클 서버에 전달하고 그 처리를 요청함
SELECT문 - executeQuery():ResultSet(Interface-커서를 조작하는데 필요한 메소드를 정의하고 있음)
INSERT, UPDATE, DELETE - executeUpdate():int - PreparedStatement(Interface) - 전령역할
Connection con = DriverManager.getConnection(URL, "scott", "tiger");
PreparedStatement pstmt = con.preparedStatement("sql문");
ResultSet rs = pstmt.executeQuery();
while(rs.next()){
Map or VO담기 - 한개 로우만 담을 수 있다.
list.add(Map or VO)
}
오라클 서버에서 응답으로 오는 정보를 취득하려면 이종간이므로 오라클에서 제공하는 기능들을 추상화 해야 한다 확장성, 유지보수 구현하는 메소드가 존재함(메소드 오버라이딩)
사용한 자원은 반드시 명시적으로 반납하라. - 자바 튜닝팀 요구사항
공통코드 - 반복되는 코드를 줄임 이유는 MyBatis로 처리한다.
계속해서 반복되는 코드를 찾아보자! -> 개선 의지가 필요하다.
orcle.jdbc.driver.OracleDriver 클래스 이름
SQL
SELECT
컬럼명1, 컬럼명2,.....
FROM 집합이름1, 집합이름2,....
WHERE 집합이름1.컬럼명 = 집합이름2.컬럼명
SELECT
e.empno, e.ename, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno;
-- 오라클 컬럼은 자바에서 변수이다.
-- 기본키는 not null제약조건이다. unique(유일무이)하다, 식별자 역할함, 인덱스를 제공함 - 검색 속도빠름
-- 메모장에 저장하는 것과는 뭔가 달라야 함
-- dept집합과 1:n관계형태에 있는 emp집합은 dept집합의 deptno를 받아서 태어난 집합임
-- 부서집합의 deptno은 emp집합으로 가서 외래키가 되었다.
SELECT empno FROM emp;
SELECT empno from emp;
select empno, ename
from emp
where empno = "x"; ---> x 자리에 자바에선 파라미터가 들어간다.
- 업무에 따라 집합이름과 컬럼명만 바뀐다. && 나머지는 다 그래로다. - synta - 문법
1. 문법적으로 맞는지 안 맞는지 파싱하고
2. DBMS에게 실행계획을 받아낸다.
3. 옵티마이저가 실행계획에 따라 처리한다.
4. open, cursor .. fetch .. close
2. URL : jdbc:oracle:thin:ip(172:16.2.66:1521:orcl11) - SID 이름
주소방식을 사용한다.
디비 조인
1. 관계 형태에는 1:1, 1:n , n:n (조인하지 않는다.) - 카타시안의 곱이다.(데이터가 복제된다.) -> 일어날 수 있는 모든 경우의 수가 조회된다.
2. 카타시안의 곱 : 데이터를 복제할 목적이 아니라면 사용하지 않는다.
3. equals 조인은 natural 조인이란 양쪼 집합에 모두 존재하는 것만 출력한다.
4. 카타시안의 곱은 (n:n) 관계는 업무적인 정의가 덜 되었다. 설계가 덜 되었다.
* 사용자로부터 동이름을 입력 받아서 조건 검색을 구현하기
* @Param dong
* sql문
* select zipcode, address
-> 두개의 컬럼이 DTO or Map -> List에 담아라 -> row레벨을 담는 컨셉이다.
from zipcode_t
where dong like '당산' || '%';
* 화면이 존재하는 경우 DB서버에서 가져온 정보를 가지고 후처리를 해야함.
* 전처리는 Conection 맺는거.
* return타입을 void로 했으니까
* UI-react-화면과 로직(Model-계층 = UI+데이터셋 만난다.) 분리
*DefaultTableModel -> addRow(Vector), addRow(Object[])
*-데이터셋에 데이터를 추가 하는 건 row 단위로 처리된다.
package com.step6;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
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;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import com.util.DBConnectionMgr;
public class ZipCodeView extends JFrame implements ActionListener, FocusListener {
//선언부
String zdo = null;
//물리적으로 떨어져 있는 db서버와 연결통로 만들기
Connection con = null;
//위에서 연결되면 쿼리문을 전달할 전령의 역할을 하는 인터페이스 객체 생성하기
PreparedStatement pstmt = null;
//조회된 결과를 화면에 처리해야 하므로 오라클에 커서를 조작하기 위해 ResultSet추가
ResultSet rs = null;
//JFrame 은 기본적으로 BorderLayout이다(동,서,남,북,중앙 배치)
//디폴트는 FlowLayout, -> BorderLayout -> setLayout
//jp_north.add("Center", jtf_dong)
//jp_north.add("West",jbtn_search)
JPanel jp_north = new JPanel();//Div태그 span생각
//insert here
String zdos[] = {"전체","서울","경기","강원"};
String zdos2[] = {"전체","부산","전남","대구"};
Vector<String> vzdos = new Vector<>();//vzdos.size()==>0
JComboBox jcb_zdo = new JComboBox(zdos);//West
JComboBox jcb_zdo2 = null;//West
JTextField jtf_search = new JTextField("동이름을 입력하세요.");//Center
JButton jbtn_search = new JButton("조회");//East
String cols[] = {"우편번호","주소"};
String data[][] = new String[0][2];
DefaultTableModel dtm_zipcode = new DefaultTableModel(data,cols);
JTable jtb_zipcode = new JTable(dtm_zipcode);
JTableHeader jth = jtb_zipcode.getTableHeader();
JScrollPane jsp_zipcode = new JScrollPane(jtb_zipcode
,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
String zdos3[] = null;
DBConnectionMgr dbMgr = null;//싱글톤 패턴으로 관리한다. 복제본을 만들지 않는다. 절대로....
//MemberShip memberShip = null;
//생성자
public ZipCodeView() {
}
//화면처리부
public void initDisplay() {
jtb_zipcode.requestFocus();
jtf_search.addFocusListener(this);
jbtn_search.addActionListener(this);
jtf_search.addActionListener(this);
//북쪽 배치하는 속지를 FlowLayout-> 동서남북중앙 - UI솔루션
jp_north.setLayout(new BorderLayout());
/* */
//vzdos.copyInto(zdos2);
for(int x=0;x<zdos2.length;x++) {
vzdos.add(zdos2[x]);
}
for(String s:vzdos) {
System.out.println("s===>"+s);
}
//jcb_zdo2 = new JComboBox(zdos3);//West
//jp_north.add("East",jcb_zdo2);
jp_north.add("Center",jtf_search);
jp_north.add("East",jbtn_search);
this.add("North",jp_north);
this.add("Center",jsp_zipcode);
this.setTitle("우편번호 검색");
this.setSize(430, 400);
this.setVisible(true);
}
//메인메소드
public static void main(String[] args) {
ZipCodeView zcs = new ZipCodeView();
zcs.initDisplay();
}
/******************************************************
* 사용자로부터 동이름을 입력 받아서 조건 검색을 구현하기
* @param dong - 동이름
* sql문
SELECT zipcode, address - 두 개의 컬럼이 DTO or Map - > List담아라 - > row레벨을 담는다
FROM zipcode_t
WHERE dong LIKE ?||'%';
* 화면이 존재하는 경우 DB서버에서 가져온 정보를 가지고 후처리를 해야 함
* return타입을 void로 했으니까 이 메소드에서 화면처리까지 진행함
* UI - react - 화면과 로직(Model계층-UI+데이터셋만난다) 분리 -
* 데이터셋에 데이터를 추가하는 것은 row단위(1차배열, Vector)로 처리된다
* DefaultTableModel -> addRow(Objectr[]), addRow(Vector)
* ClassNotFoundException - > ojdbc6.jar -> build path
* NullPointerException발동 -> con.prepareStatement("SELECT문"); - con이 널이다. ip주소, port:1521, 1522, `1523
* scott/tiger - 인증실패관련메시지
* sid가 이미 설치된 컴터 orcl
* SQLException은 sql문의 오류이다. 자바의 문제가 아님 - 토드에서 단위테스트 해볼것.
******************************************************/
public void refreshData(String dong) {
List<Map<String,Object>> list = new ArrayList<>();
StringBuilder sql = new StringBuilder();
sql.append("SELECT zipcode, address ");
sql.append(" FROM zipcode_t ");
sql.append(" WHERE dong LIKE ?||'%'");
dbMgr = DBConnectionMgr.getInstance();
try {
con = dbMgr.getConnection();//물리적으로 떨어져 있는 서버와 연결통로 확보
pstmt = con.prepareStatement(sql.toString());//쿼리문을 먼저 스캔하여 있을 지 모르는 변수의 자리를 치환할것.
pstmt.setString(1, dong);//dong, 당산, 가산, 공덕
rs = pstmt.executeQuery();
Map<String,Object> rmap = null;
while(rs.next()) {
rmap = new HashMap<>();
rmap.put("zipcode", rs.getInt("zipcode"));
rmap.put("address", rs.getString("address"));
list.add(rmap);
}
System.out.println(list);//주소번지가 33번 출력될것이다. - 단위테스트 하자
} catch (SQLException se) {
System.out.println(sql.toString());//출력된 쿼리문을 갈무리해서 토드에서 확인해 볼것.
} catch (Exception e) {
// TODO: handle exception
}
}
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if(obj == jbtn_search || obj == jtf_search) {
System.out.println(jtf_search.getText());//당산
String dong = jtf_search.getText();
refreshData(dong);
}
}
@Override
public void focusGained(FocusEvent e) {
Object obj = e.getSource();
if(obj == jtf_search) {
jtf_search.setText("");
}
}
@Override
public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
}
}
* 사용자로부터 동이름을 입력 받아서 조건 검색을 구현하기
* @param dong - 동이름
* sql문
SELECT zipcode, address - 두 개의 컬럼이 DTO or Map - > List담아라 - > row레벨을 담는다
FROM zipcode_t
WHERE dong LIKE ?||'%';
* 화면이 존재하는 경우 DB서버에서 가져온 정보를 가지고 후처리를 해야 함
* return타입을 void로 했으니까 이 메소드에서 화면처리까지 진행함
* UI - react - 화면과 로직(Model계층-UI+데이터셋만난다) 분리 -
* 데이터셋에 데이터를 추가하는 것은 row단위(1차배열, Vector)로 처리된다
* DefaultTableModel -> addRow(Objectr[]), addRow(Vector)
* ClassNotFoundException - > ojdbc6.jar -> build path
* NullPointerException발동 -> con.prepareStatement("SELECT문"); - con이 널이다. ip주소, port:1521, 1522, `1523
* scott/tiger - 인증실패관련메시지
* sid가 이미 설치된 컴터 orcl
* SQLException은 sql문의 오류이다. 자바의 문제가 아님 - 토드에서 단위테스트 해볼것.
package com.step6;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
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;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import com.util.DBConnectionMgr;
public class ZipCodeView extends JFrame implements ActionListener, FocusListener {
//선언부
String zdo = null;
//물리적으로 떨어져 있는 db서버와 연결통로 만들기
Connection con = null;
//위에서 연결되면 쿼리문을 전달할 전령의 역할을 하는 인터페이스 객체 생성하기
PreparedStatement pstmt = null;
//조회된 결과를 화면에 처리해야 하므로 오라클에 커서를 조작하기 위해 ResultSet추가
ResultSet rs = null;
//JFrame 은 기본적으로 BorderLayout이다(동,서,남,북,중앙 배치)
//디폴트는 FlowLayout, -> BorderLayout -> setLayout
//jp_north.add("Center", jtf_dong)
//jp_north.add("West",jbtn_search)
JPanel jp_north = new JPanel();//Div태그 span생각
//insert here
String zdos[] = {"전체","서울","경기","강원"};
String zdos2[] = {"전체","부산","전남","대구"};
Vector<String> vzdos = new Vector<>();//vzdos.size()==>0
JComboBox jcb_zdo = new JComboBox(zdos);//West
JComboBox jcb_zdo2 = null;//West
JTextField jtf_search = new JTextField("동이름을 입력하세요.");//Center
JButton jbtn_search = new JButton("조회");//East
String cols[] = {"우편번호","주소"};
String data[][] = new String[0][2];
DefaultTableModel dtm_zipcode = new DefaultTableModel(data,cols);
JTable jtb_zipcode = new JTable(dtm_zipcode);
JTableHeader jth = jtb_zipcode.getTableHeader();
JScrollPane jsp_zipcode = new JScrollPane(jtb_zipcode
,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
String zdos3[] = null;
DBConnectionMgr dbMgr = null;//싱글톤 패턴으로 관리한다. 복제본을 만들지 않는다. 절대로....
//MemberShip memberShip = null;
//생성자
public ZipCodeView() {
}
//화면처리부
public void initDisplay() {
jtb_zipcode.requestFocus();
jtf_search.addFocusListener(this);
jbtn_search.addActionListener(this);
jtf_search.addActionListener(this);
//북쪽 배치하는 속지를 FlowLayout-> 동서남북중앙 - UI솔루션
jp_north.setLayout(new BorderLayout());
/* */
//vzdos.copyInto(zdos2);
for(int x=0;x<zdos2.length;x++) {
vzdos.add(zdos2[x]);
}
for(String s:vzdos) {
System.out.println("s===>"+s);
}
//jcb_zdo2 = new JComboBox(zdos3);//West
//jp_north.add("East",jcb_zdo2);
jp_north.add("Center",jtf_search);
jp_north.add("East",jbtn_search);
this.add("North",jp_north);
this.add("Center",jsp_zipcode);
this.setTitle("우편번호 검색");
this.setSize(430, 400);
this.setVisible(true);
}
//메인메소드
public static void main(String[] args) {
ZipCodeView zcs = new ZipCodeView();
zcs.initDisplay();//화면이 먼저 열리도록 하고 오라클서버를 나중에 연결하자
//zcs.refreshData("가산");
}
public void refreshData(String dong) {
List<Map<String,Object>> list = new ArrayList<>();
StringBuilder sql = new StringBuilder();
sql.append("SELECT zipcode, address ");
sql.append(" FROM zipcode_t ");
sql.append(" WHERE dong LIKE ?||'%'");
dbMgr = DBConnectionMgr.getInstance();
try {
con = dbMgr.getConnection();//물리적으로 떨어져 있는 서버와 연결통로 확보
pstmt = con.prepareStatement(sql.toString());//쿼리문을 먼저 스캔하여 있을 지 모르는 변수의 자리를 치환할것.
pstmt.setString(1, dong);//dong, 당산, 가산, 공덕
rs = pstmt.executeQuery();
Map<String,Object> rmap = null;
while(rs.next()) {
rmap = new HashMap<>();
rmap.put("zipcode", rs.getInt("zipcode"));
rmap.put("address", rs.getString("address"));
list.add(rmap);
}
System.out.println(list);//주소번지가 33번 출력될것이다. - 단위테스트 하자
//메소드 설계가 리턴타입이 빠져 있으므로 화면 처리까지 여기서 해야 함.
for(int i=0;i<list.size();i++) {//33번 반복됨 - row수
Map<String, Object> map = list.get(i);
Vector<Object> v = new Vector<>();
v.add(0,map.get("zipcode"));
v.add(1,map.get("address"));
dtm_zipcode.addRow(v);
}
} catch (SQLException se) {
System.out.println(sql.toString());//출력된 쿼리문을 갈무리해서 토드에서 확인해 볼것.
} catch (Exception e) {
// TODO: handle exception
}
}
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if(obj == jbtn_search || obj == jtf_search) {
System.out.println(jtf_search.getText());//당산
String dong = jtf_search.getText();
refreshData(dong);
}
}
@Override
public void focusGained(FocusEvent e) {
Object obj = e.getSource();
if(obj == jtf_search) {
jtf_search.setText("");
}
}
@Override
public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
}
}
----------------------------------------
s===>전체
s===>부산
s===>전남
s===>대구
당산
[{zipcode=150040, address=서울 영등포구 당산동}, {zipcode=150041, address=서울 영등포구 당산동1가}, {zipcode=150800, address=서울 영등포구 당산동1가 1~256}, {zipcode=150750, address=서울 영등포구 당산동1가 진로아파트}, {zipcode=150801, address=서울 영등포구 당산동1가 257~457}, {zipcode=150042, address=서울 영등포구 당산동2가}, {zipcode=150935, address=서울 영등포구 당산동2가 대우미래사랑}, {zipcode=150935, address=서울 영등포구 당산동2가 대우메종리브르}, {zipcode=150752, address=서울 영등포구 당산동2가 당산2가현대아파트 101-107}, {zipcode=150043, address=서울 영등포구 당산동3가}, {zipcode=150802, address=서울 영등포구 당산동3가 1~10}, {zipcode=150803, address=서울 영등포구 당산동3가 11~384}, {zipcode=150804, address=서울 영등포구 당산동3가 385~560}, {zipcode=150720, address=서울 영등포구 당산동3가 영등포구청}, {zipcode=150955, address=서울 영등포구 당산동3가 영등포세무서}, {zipcode=150720, address=서울 영등포구 당산동3가 영등포구보건소}, {zipcode=150802, address=서울 영등포구 당산동3가 561~563}, {zipcode=150044, address=서울 영등포구 당산동4가}, {zipcode=150805, address=서울 영등포구 당산동4가 1~32}, {zipcode=150722, address=서울 영등포구 당산동4가 동양타워빌딩}, {zipcode=150753, address=서울 영등포구 당산동4가 현대3차아파트 101-106}, {zipcode=150754, address=서울 영등포구 당산동4가 현대5차아파트 501-513}, {zipcode=150806, address=서울 영등포구 당산동4가 33~96}, {zipcode=150045, address=서울 영등포구 당산동5가}, {zipcode=150755, address=서울 영등포구 당산동5가 효성아파트}, {zipcode=150771, address=서울 영등포구 당산동5가 삼성래미안4차아파트 401-425}, {zipcode=150046, address=서울 영등포구 당산동6가}, {zipcode=150807, address=서울 영등포구 당산동6가 1~120}, {zipcode=150808, address=서울 영등포구 당산동6가 121~173}, {zipcode=150809, address=서울 영등포구 당산동6가 174~325}, {zipcode=150810, address=서울 영등포구 당산동6가 326~378}, {zipcode=150942, address=서울 영등포구 당산동6가 강변삼성래미안아파트 301-313}, {zipcode=150723, address=서울 영등포구 당산동2가 영등포유통상가}]
* 올 수 있는 Exception 종류는?
* 1. ClassNotFoundException -> ojdbc6.jar -> build path 문제
*
* 2. NullPointerException발동
* -> con.prepareStatement("SELECT문"); - con이 null이다.
* -> ip 주소가 문제다.(port1521,1522,1523)
* -> scott/tiger - 인증 실패 관련 메시지
* ->sid가 이미 설치된 컴터 orcl 바꿔줘야 한다.
*
* 3.SQLException은 sql문의 오류이다. 자바의 문제가 아님
* -> 토드에서 단위테스트 해볼것.
package com.chat;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class MemberShipView extends JDialog implements ActionListener{
//선언부
JPanel jp_center = new JPanel();
JLabel jlb_id = new JLabel("아이디");
JTextField jtf_id = new JTextField(10);
JLabel jlb_pw = new JLabel("패스워드");
JTextField jtf_pw = new JTextField(10);
JLabel jlb_nickName = new JLabel("대화명");
JTextField jtf_nickName = new JTextField(20);
JLabel jlb_name = new JLabel("성명");
JTextField jtf_name = new JTextField(30);
JLabel jlb_gender = new JLabel("성별");
String[] genderList = {"남자","여자"};
JComboBox jcb_gender = new JComboBox(genderList);
JLabel jlb_zipcode = new JLabel("우편번호");
public JTextField jtf_zipcode = new JTextField(6);
JLabel jlb_address = new JLabel("주소");
public JTextField jtf_address = new JTextField(100);
JButton jbtn_zipcode = new JButton("우편번호찾기");
JScrollPane jsp = null;
JPanel jp_south = new JPanel();
JButton jbtn_ins = new JButton("등록");
JButton jbtn_close = new JButton("닫기");
//insert here
//우편번호 검색기 클래스를 전역변수 자리에서 생성한다 - MemberShipView가 생성될때 그때 생성이 됨
//파라미터 자리에 this를 쓸 수 있는건 이 어플리케이션을 실행했을때 비로서 객체가 로딩됨
ZipCodeView zcView = new ZipCodeView(this);//this는 현재 로딩중인 원본이다.
//생성자
public MemberShipView(){
//initDisplay();
}
//화면처리부
public void initDisplay() {
jbtn_zipcode.addActionListener(this);
jp_center.setLayout(null);
jlb_id.setBounds(20, 20, 100, 20);
jtf_id.setBounds(120, 20, 120, 20);
jlb_pw.setBounds(20, 45, 100, 20);
jtf_pw.setBounds(120, 45, 120, 20);
jlb_nickName.setBounds(20, 70, 100, 20);
jtf_nickName.setBounds(120, 70, 150, 20);
jlb_name.setBounds(20, 95, 100, 20);
jtf_name.setBounds(120, 95, 150, 20);
jlb_gender.setBounds(20, 120, 100, 20);
jcb_gender.setBounds(120, 120, 150, 20);
jcb_gender.setFont(new Font("굴림",1,14));
jlb_zipcode.setBounds(20, 145, 100, 20);
jtf_zipcode.setBounds(120, 145, 100, 20);
jbtn_zipcode.setBounds(230, 145, 120, 20);
jlb_address.setBounds(20, 170, 100, 20);
jtf_address.setBounds(120, 170, 250, 20);
jp_center.add(jlb_id);
jp_center.add(jtf_id);
jp_center.add(jlb_pw);
jp_center.add(jtf_pw);
jp_center.add(jlb_nickName);
jp_center.add(jtf_nickName);
jp_center.add(jlb_name);
jp_center.add(jtf_name);
jp_center.add(jlb_gender);
jp_center.add(jcb_gender);
jp_center.add(jlb_zipcode);
jp_center.add(jtf_zipcode);
jp_center.add(jbtn_zipcode);
jp_center.add(jlb_address);
jp_center.add(jtf_address);
jp_south.setLayout(new FlowLayout(FlowLayout.RIGHT));
jp_south.add(jbtn_ins);
jp_south.add(jbtn_close);
this.add("South",jp_south);
jsp = new JScrollPane(jp_center);
this.add("Center",jsp);
this.setTitle("회원가입");
this.setSize(400, 500);
this.setVisible(true);
}
public static void main(String[] args) {
MemberShipView ms = new MemberShipView();// 전역변수자리에 인스턴스화 한 객체들이 비로서 이때 로딩이 됨
ms.initDisplay();
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("action");
Object obj = e.getSource();
if(obj == jbtn_zipcode) {
//insert here 우편번호 검색기
zcView.initDisplay();
}
}
}
package com.chat;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
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;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import com.util.DBConnectionMgr;
public class ZipCodeView extends JFrame implements ActionListener, FocusListener, MouseListener {
//선언부
String zdo = null;
//물리적으로 떨어져 있는 db서버와 연결통로 만들기
Connection con = null;
//위에서 연결되면 쿼리문을 전달할 전령의 역할을 하는 인터페이스 객체 생성하기
PreparedStatement pstmt = null;
//조회된 결과를 화면에 처리해야 하므로 오라클에 커서를 조작하기 위해 ResultSet추가
ResultSet rs = null;
//JFrame 은 기본적으로 BorderLayout이다(동,서,남,북,중앙 배치)
//디폴트는 FlowLayout, -> BorderLayout -> setLayout
//jp_north.add("Center", jtf_dong)
//jp_north.add("West",jbtn_search)
JPanel jp_north = new JPanel();//Div태그 span생각
//insert here
String zdos[] = {"전체","서울","경기","강원"};
String zdos2[] = {"전체","부산","전남","대구"};
Vector<String> vzdos = new Vector<>();//vzdos.size()==>0
JComboBox jcb_zdo = new JComboBox(zdos);//West
JComboBox jcb_zdo2 = null;//West
JTextField jtf_search = new JTextField("동이름을 입력하세요.");//Center
JButton jbtn_search = new JButton("조회");//East
String cols[] = {"우편번호","주소"};
String data[][] = new String[0][2];
DefaultTableModel dtm_zipcode = new DefaultTableModel(data,cols);
JTable jtb_zipcode = new JTable(dtm_zipcode);
JTableHeader jth = jtb_zipcode.getTableHeader();
JScrollPane jsp_zipcode = new JScrollPane(jtb_zipcode
,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
String zdos3[] = null;
DBConnectionMgr dbMgr = null;//싱글톤 패턴으로 관리한다. 복제본을 만들지 않는다. 절대로....
MemberShipView memberShipView = null;//null이 뭔가를 가리키는 시점은 ZipCodeVIew생성자가 호출될때
//생성자
public ZipCodeView() {
}
public ZipCodeView(MemberShipView memberShipView) {
this.memberShipView = memberShipView;// 재정의, 치환하기
}
//화면처리부
public void initDisplay() {
jtb_zipcode.requestFocus();
jtf_search.addFocusListener(this);
jtb_zipcode.addMouseListener(this);
jbtn_search.addActionListener(this);
jtf_search.addActionListener(this);
//북쪽 배치하는 속지를 FlowLayout-> 동서남북중앙 - UI솔루션
jp_north.setLayout(new BorderLayout());
/* */
//vzdos.copyInto(zdos2);
for(int x=0;x<zdos2.length;x++) {
vzdos.add(zdos2[x]);
}
for(String s:vzdos) {
System.out.println("s===>"+s);
}
//jcb_zdo2 = new JComboBox(zdos3);//West
//jp_north.add("East",jcb_zdo2);
jp_north.add("Center",jtf_search);
jp_north.add("East",jbtn_search);
this.add("North",jp_north);
this.add("Center",jsp_zipcode);
this.setTitle("우편번호 검색");
this.setSize(430, 400);
this.setVisible(true);
}
//메인메소드
public static void main(String[] args) {
ZipCodeView zcs = new ZipCodeView();
zcs.initDisplay();//화면이 먼저 열리도록 하고 오라클서버를 나중에 연결하자
//zcs.refreshData("가산");
}
/******************************************************
* 사용자로부터 동이름을 입력 받아서 조건 검색을 구현하기
* @param dong - 동이름
* sql문
SELECT zipcode, address - 두 개의 컬럼이 DTO or Map - > List담아라 - > row레벨을 담는다
FROM zipcode_t
WHERE dong LIKE ?||'%';
* 화면이 존재하는 경우 DB서버에서 가져온 정보를 가지고 후처리를 해야 함
* return타입을 void로 했으니까 이 메소드에서 화면처리까지 진행함
* UI - react - 화면과 로직(Model계층-UI+데이터셋만난다) 분리 -
* 데이터셋에 데이터를 추가하는 것은 row단위(1차배열, Vector)로 처리된다
* DefaultTableModel -> addRow(Objectr[]), addRow(Vector)
* ClassNotFoundException - > ojdbc6.jar -> build path
* NullPointerException발동 -> con.prepareStatement("SELECT문"); - con이 널이다. ip주소, port:1521, 1522, `1523
* scott/tiger - 인증실패관련메시지
* sid가 이미 설치된 컴터 orcl
* SQLException은 sql문의 오류이다. 자바의 문제가 아님 - 토드에서 단위테스트 해볼것.
******************************************************/
public void refreshData(String dong) {
List<Map<String,Object>> list = new ArrayList<>();
StringBuilder sql = new StringBuilder();
sql.append("SELECT zipcode, address ");
sql.append(" FROM zipcode_t ");
sql.append(" WHERE dong LIKE ?||'%'");
dbMgr = DBConnectionMgr.getInstance();
try {
con = dbMgr.getConnection();//물리적으로 떨어져 있는 서버와 연결통로 확보
pstmt = con.prepareStatement(sql.toString());//쿼리문을 먼저 스캔하여 있을 지 모르는 변수의 자리를 치환할것.
pstmt.setString(1, dong);//dong, 당산, 가산, 공덕
rs = pstmt.executeQuery();
Map<String,Object> rmap = null;
while(rs.next()) {
rmap = new HashMap<>();
rmap.put("zipcode", rs.getInt("zipcode"));
rmap.put("address", rs.getString("address"));
list.add(rmap);
}
System.out.println(list);//주소번지가 33번 출력될것이다. - 단위테스트 하자
//메소드 설계가 리턴타입이 빠져 있으므로 화면 처리까지 여기서 해야 함.
for(int i=0;i<list.size();i++) {//33번 반복됨 - row수
Map<String, Object> map = list.get(i);
Vector<Object> v = new Vector<>();
v.add(0,map.get("zipcode"));
v.add(1,map.get("address"));
dtm_zipcode.addRow(v);
}
} catch (SQLException se) {
System.out.println(sql.toString());//출력된 쿼리문을 갈무리해서 토드에서 확인해 볼것.
} catch (Exception e) {
// TODO: handle exception
}
}
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if(obj == jbtn_search || obj == jtf_search) {
System.out.println(jtf_search.getText());//당산
String dong = jtf_search.getText();
refreshData(dong);
}
}
@Override
public void focusGained(FocusEvent e) {
Object obj = e.getSource();
if(obj == jtf_search) {
jtf_search.setText("");
}
}
@Override
public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
if(e.getClickCount()==2) {//더블클릭한거야?
//화면 테이블에서 더블클릭했을 때 선택된 로우의 index값을 반환해줌
int index = jtb_zipcode.getSelectedRow();//1.8부터 오토박싱을 통해서 int와 Wrapper클래스는 자동으로 형전환
int zipcode = (int)dtm_zipcode.getValueAt(index, 0);//선택된 로우의 우편번호가 담김
String address = (String)dtm_zipcode.getValueAt(index, 1);
System.out.println(zipcode +", "+ address);//
//insert here - 부모창인 회원가입 창에서 우편번호 와 주소자리(MemberShipView)에 조회된 결과를 자동으로 출력해줌
//부모(MemberShipView)의 주소번지가 필요하다.
//valueOf메소드의 파라미터자리에 어떤 값이 오든 String 타입으로 형전환해주는 메소드 이다.
//관전 포인트 하나더 - 싱글톤으로 제공되는 메소드 입니다.
//MemberShipView를 인스턴스화 하면 그 때 즉시 전역변수의 ZipCodeView객체가 생성되고 이때 파라미터 자리에 this는
//앞에 인스턴스화를 통해 현재 로딩 중인 그 원본이므로 복사본이 아니다.
memberShipView.jtf_zipcode.setText(String.valueOf(zipcode));
memberShipView.jtf_address.setText(String.valueOf(address));
}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}