Hashtable
Object유형을 저장할 수 있다
key와 value를 매핑하여 저장한다.
데이터가 75%가 차면 자동으로 저장 영역을 확대한다.
key값의 중복을 허용하지 않는다.
특징
-무순서
데이터 저장 : Object put(Object key, Object value)
데이터 꺼내기 : Object get(Object key)
package day22;
import java.awt.Color;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
public class HashtableTest {
public static void main(String[] args) {
Hashtable h = new Hashtable();
h.put("하나",new Integer(1));
h.put("둘","2");
h.put("빨강","Red");
h.put("파랑",java.awt.Color.blue);
Object o = h.get("둘");
System.out.println(o);
System.out.println(h.get("하나"));
Color cr= (Color)h.get("파랑");
System.out.println(cr);
//Generic 사용 => Hashtable<K,V>
Hashtable<String, Integer> h2 = new Hashtable<>();
h2.put("생년",new Integer(2003));
h2.put("나이",17);//auto boxing
h2.put("용돈",new Integer("50000"));
Integer age = h2.get("나이");
int money = h2.get("용돈");
System.out.println(money *2);
//Enumeration<V> elements() ==> value 값들만 추출함
//Collection<V> values()
//Enumeration<K> keys() ==> key값들만 추출함
//Set<K> keySet()
//keys()를 이용해서 key값들을 한꺼번에 출력해보세요
Enumeration<String> en = h2.keys();
while(en.hasMoreElements()) {
String key = en.nextElement();
Integer val = h2.get(key);
System.out.println(key);
System.out.println(val);
}
Collection<Integer> en2 = h2.values();
System.out.println(en2);
Iterator<Integer> it =en2.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
Set<String> en3 = h2.keySet();
System.out.println(en3);
}
}
key 값을 알면 value는 알 수 있지만 반대는 불가능, Key값으로 관리하기 떄문에 출력에 순서가 없다.
HashMap
Hashtable과 동일 차이점은 HastMap은 동기화가 구현되지 않음 => 웹에서 많이 사용
[예제]
* 회원가입 (아이디 K, 비밀번호V)
* 회원정보를 HashMap에 저장한 뒤
* 로그인 해보자 => 아이디, 비번 입력받기
* 1) 아이디가 회원이 맞다면
* 비번체크 ==> 비번도 일치하면 "환영합니다"
* 2) 아이디는 맞지만
* 비번이 불일치라면 => "비밀번호가 틀려요"
* 아디디도 틀린 경우
HashMap API를 참고하여
id_pw.containsKey(userid);를 이용해서 userid 가 키 값으로 있는지 확인할 수 있다
package day22;
import java.util.HashMap;
import java.util.Set;
public class HashMapTest {
HashMap<String, String> id_pw = new HashMap<>();
public void join() {
id_pw.put("cksgns93", "q1q1q1q1");
id_pw.put("Hong", "123");
id_pw.put("Kim", "qwerty");
System.out.println("회원가입 완료! 회원수 "+id_pw.size());
}
//로그인 처리를 하는 메소드
public void loginCheck() {
java.io.Console con = System.console();
while(true) {
System.out.print("아이디 : ");
String userid = con.readLine();
System.out.print("비밀번호 : ");
char[] pwd = con.readPassword();
String passwd = new String(pwd);
System.out.println(userid +"\t"+passwd);
//사용자가 입력한 아이디가 회원이 맞는지 체크한다.
Set<String> chkid = id_pw.keySet();
boolean chk = false;
boolean ss = id_pw.containsKey(userid);
if(ss) {
if(passwd.equals(id_pw.get(userid))) {
System.out.println("로그인");
return;
}else {
System.out.println("비번 틀림");
}
}else {
System.out.println("없음");
}
/*
for(String s: chkid) {
if(userid.equals(s)) {
chk=true;
if(passwd.equals(id_pw.get(s))){
System.out.println("로그인 완료");
return;
}else {
System.out.println("비번 틀림");
break;
}
}
}
if(!chk) {
System.out.println("아이디 없음");
}
*/
}
}
public static void main(String[] args) {
HashMapTest hmt = new HashMapTest();
hmt.join();
hmt.loginCheck();
}
}
Console은 cmd창에서 실행하는 것이다.
cmd 창에서 위 파일을 실행하려면 day22 패키지 위로 설정을 해두고
( c:\myjava\workspace\Begin\bin )
java day22.HashMapTest를 실행하면 된다.
JTable
package day22;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.table.*;
public class JTableDemo extends JFrame {
JPanel p = new JPanel();
JTable table; //View
DefaultTableModel model; //Model (data를 갖는다)
Object [][] data= {
{new Integer(1), "홍길동", new ImageIcon("images/11.PNG"),new Boolean(true)},
{new Integer(2), "고양이", new ImageIcon("images/22.PNG"),new Boolean(false)},
{new Integer(3), "강아지", new ImageIcon("images/33.PNG"),new Boolean(false)},
{new Integer(4), "김길동", new ImageIcon("images/44.PNG"),new Boolean(true)}
};
String [] colHeader= {"번호","이름","이미지","사람인가?"};
public JTableDemo() {
super("::JTableDemo::");
Container cp = getContentPane();
cp.add(p, "Center");
p.setBackground(Color.white);
table= new JTable(); //view
model = new DefaultTableModel(data,colHeader); //모델
table.setModel(model); //view와 모델 연결
p.add(new JScrollPane(table));
table.setRowHeight(25);
table.setSelectionBackground(Color.blue);
table.setSelectionForeground(Color.white);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
JTableDemo ae = new JTableDemo();
ae.setSize(500, 500);
ae.setVisible(true);
}
}
나만의 고유한 테이블 모델 만들기
1) TableModel 인터페이스르 상속받아 만드는 방법
2) AbstractTableModel 추상클래스 상속
3) DefaulTableModel 클래스를 상속
AbstractTableModel을 상속받으면 F2로 Override해야할 메소드를 확인해준다.
package day22;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.*;
/*
* 나만의 고유한 테이블 모델 만들기
* 1) TableModel 인터페이스를 상속받아 만드는 방법
* 2) AbstractTableModel 추상클래스 상속
* 3) DefaultTableModel 클래스를 상속
* */
public class MyTableModel extends AbstractTableModel{
Object[][] data;
String [] colHeader;
public MyTableModel(Object[][] arr, String[] col) {
this.data=arr;
this.colHeader=col;
}
@Override
public int getRowCount() {
return data.length;
};
@Override
public int getColumnCount() {
return colHeader.length;
};
@Override
public Object getValueAt(int row, int column) {
return data[row][column];
};
// 옵션 : 필수는 아니지만 재정의하면 기능이 풍부해짐
@Override
public String getColumnName(int col) {
return colHeader[col];
}
//옵션 : 각 컬럽 셀을 편집할 수 있도록
@Override
public boolean isCellEditable(int row, int col) {
//번호 (PK)는 편집 불가, 나머지는 편집 가능
return (col==0)? false : true;
}
//옵션 : 실제로 편집된 값을 적용하기 위해서 재정의
@Override
public void setValueAt(Object obj , int row, int col) {
//obj : 수정할 대상 객체
String str = obj.toString();
switch(col) {
case 0:
data[row][col]= new Integer(str);
//8버전보다 높으면 Integer.valueof(str); 사용
break;
case 1:
data[row][col]=str;
break;
case 2:
data[row][col]=new ImageIcon(str);
break;
case 3:
data[row][col]=new Boolean(str);
break;
}
}
//옵션 : 이미지 형태로 보여주거나 체크박스 형태로 보여죽려면 재정의
@Override
public Class<?> getColumnClass(int col){
Object obj = this.getValueAt(0, col);
Class<?> cls = obj.getClass();
return cls;
}
}
OUTER JOIN
- 두 개 이상의 테이블을 EQUI JOIN방법으로 조인하는 경우, 한 쪽 테이블에 일치하는 행이 없으면 다른 쪽 테이블을 NULL로 하여 그 값을 보여준다.
옛날 버전
select dept.deptno,dname,ename
from dept, emp
where dept.deptno = emp.deptno(+)
order by 1;
(+) 기호는 null 값으로 표현해야 하는 쪽에 붙인다.
명시적 join절을 이용한 outer join
1) LEFT OUTER JOIN : 왼쪽 테이블을 기준으로 JOIN함
2) RIGHT OUTER JOIN : 오른쪽 테이블을 기준으로 JOIN
3) FULL OUTER JOIN : 양쪽 테이블에 다 OUTER
select distinct(e.deptno), d.deptno
from dept d left outer join emp e
on d.deptno = e.deptno;
-- 상품 테이블의 상품을 공급업체코드, 공급업체명, 상품이름, 공급가 순으로 출력하되
-- 공급업체가 없는 상품도 출력하세요
select ep_code_fk, ep_name ,products_name, output_price
from supply_comp s right outer join products p
on s.ep_code = p.ep_code_fk;
-- 상품 테이블의 상품을 카테고리명, 상품명 , 판매가, 공급업체명을 함께 출력하되 공급업체나
-- 카테고리가 없는 상품도 함께 보여주세요
select c.category_name, p.products_name, output_price, ep_name
from products p
left outer join category c
on c.category_code = p.category_fk
left outer join supply_comp s
on s.ep_code = p.ep_code_fk;
SELF JOIN
사원과 사원의 관리자를 출력할 수 있다
select e1.empno, e1.ename, e1.mgr, e2.empno,e2.ename
from emp e1 join emp e2
on e1.mgr = e2.empno;
[문제1] emp에서 "누구의 관리자는 누구이다"라는 형태로 출력
select e1.ename||'의 관리자는 '|| e2.ename||'이다'
from emp e1 join emp e2
on e1.mgr = e2.empno;
select e1.ename as Employee,e1.empno ,nvl(e2.ename,' ') as "관리자 이름",nvl(e2.empno,0) as mgr
from emp e1 left outer join emp e2
on e1.mgr = e2.empno
order by 3 desc;
--null도 자료형을 맞춰서 줘야한다. NVL(e.empno, ' ')
SET OPERATOR
1) UNION SET OPERATOR
- 하나 이상의 테이블로부터 자료를 검색하는 또 다른 방법은
SET연산자를 이용하는 방법이 있다.
즉 SET연산자를 이용하여 여러 개의 SELECT문장을 연결하여 작성
할 수 있다.
- 구문형식
SELECT 컬럼1[,컬럼2, 컬럼3....] FROM table1
SET OPERATOR
SELECT 컬럼1[,컬럼2, 컬럼3....] FROM table2
[ORDER BY COLUMN|EXPRESSION];
- 가이드라인
* 첫번째 SELECT 구문에서 기술된 컬럼과 두번재 SELECT구문에서
기술된 컬럼들은 좌측부터 1대 1로 대응하며 그 개수와 타입이
일치해야 한다.
* FROM 절 뒤에 기술되는 테이블은 같을 수도 있고 다를 수도 있다.
* 출력되는 HEADING은 첫 번째 SELECT 구문에서 기술된 컬럼이 출력된다.
* ORDER BY 는 단 한번만 기술 가능하고 SELECT구문의 마지막에 기술한다.
* SELECT문장은 위에서 아래로 수행되고 이를 변경하고자 할 경우는
괄호를 사용한다.
- 종류
---------------------------------------------------------------
종류 : 설명
---------------------------------------------------------------
UNION :각 결과의 합(합집합: 중복되는 값은 한번 출력)
---------------------------------------------------------------
UNION ALL :각 결과의 합(합집합)
---------------------------------------------------------------
INTERSECT :각 결과의 중복되는 부분만 출력(교집합)
---------------------------------------------------------------
MINUS : 첫번째 결과에서 두번째 결과를 뺌(차집합)
---------------------------------------------------------------
[실습]
6_1)
UNION과 UNION ALL의 차이를 알아보자.[합집합]
select deptno from dept union
select deptno from emp
==> 4개의 행이 출력됨
select deptno from dept union all
select deptno from emp
==> 18개의 행이 출력됨 (dept의 4개 + emp의 14개)
6_2) INTERSECT 연산자[교집합]
select deptno from dept INTERSECT
select deptno from emp
6_3) MINUS 연산자[차집합]
두번째 SELECT 문장에서 검색되지 않았던 값을 첫번째 SELECT문장에서
출력한다.
select deptno from dept minus select deptno from emp;
SUBQUERY
1). 서브 쿼리 이용하기
- 서브 쿼리란 SELECT한 결과를 조건 비교에 이용하거나
UPDATE 또는 DELETE 등에 사용할 때 이용하거나,
SELECT한 결과를 조건으로 이용하여 다시
SELECT를 하는 것처럼 DML 안에
다시 SELECT구문이 포함되는 형태를 말한다.
- 서브 쿼리는 여러 절에서 사용가능하다.
- NESTED SUBQUERY 는 MAIN QUERY 이전에 한번만 수행되며,
SUBQUERY의 결과를 MAIN QUERY에서 조건으로 사용된다.
- 가이드라인
* 서브쿼리는 괄호로 묶어야 한다.
* 두 종류의 비교연산자들이 서브쿼리에 사용된다.
=,>,>=, <,ㅡ=,<>,!=
IN, NOT IN, ANY
* 서브쿼리는 연산자의 오른쪽에 나타나야 한다.
* 서브쿼리는 많은 SQL명령에서 사용가능하다.
* 서브쿼리는 ORDER BY 절을 포함할 수 없다.
--서브쿼리
select sal from emp where ename =upper('scott');
--메인쿼리
select empno,ename,job,sal from emp
where sal >= (select sal from emp where ename =upper('scott'));
[문제2] emp에서 사번이 7521번인 사원과 업무가 같고, 급여가 7934번인 사원보다 많은 사원의
사번, 이름, 업무, 급여를 출력하세요
select empno, ename, job, sal from emp
where job = (select job from emp where empno = 7521) and sal>=(select sal from emp
where empno =7934);
고객 테이블에 있는 고객 정보 중 마일리지 점수가 가장 높은 고객의 이름, 직업 ,마일리지 점수를 보여주세요
select name, job, mileage from member
where mileage = (select max(mileage) from member);