(22)-23.10.24[JAVA]

DANA·2023년 10월 25일

KDT-구디아카데미

목록 보기
22/56

자바로 자유게시판 구현하기 - CRUD - 목업(Mockup)
BoardController.java
BoardDao.java (자료구조처리 → 오라클연동 → MyBatis)
BoardView.java
페이지 Flow-Chart
클래스 설계 (MVC패턴)
개발시작
제네릭
List, List → 잘 쓰지 않음
List, List<Map<String, Object>> : 주소번지를 두 번{List VO or List Map} 접근해야 한다.
인터페이스와 추상클래스 차이점 추상 → 결정되지 않음, 미정이다, 모르겠다. → 하드웨어에 따라서 그 기능이 조금씩 달라진다. - 메소드 오버 라이딩 언제 결정되는가?? → 구현체 클래스에서 하드웨어가 결정되었으므로 그 기능을 결정지을 수 있다.
인터페이스 - 추상메소드를 선언만 하고있다. 예) public void m(); → 메소드 호출이 아닌데 세미콜론으로 끝남 List Map
List 나 Map은 요소들을 순회하는 메소드를 지원하고 있다. Set(UI솔루션에서 지원하지 않음)
그러나 Set은 순회하는 메소드를 지원하지 않아서 순회를 담당하는 Iterator, Enumeration 인터페이스를 추가로 사용해야 한다.
추상클래스 추상클래스는 일반메소드도 선언하고 추상메소드도 선언 가능하다. 인터페이스가 추상클래스보다 더 추상적이다. - 왜냐면 일반메소드는 못 가진다.
Collection요소를 순회하는 Interactior 요소의 순회란??
컬렉션 프레임워크에 저장된 요소들을 하나씩 차례로 참조하는 것.
순서(Map보다 느리다 : 읽기, 쓰기 속도가)가 있는 List는 Inerator없이도 순회가 가능하다.
인터페이스나 추상클래스는 반드시 구현체 클래스가 필요하다 ㄴ 자바에서는 생성부의 이름으로 객체가 생성된다.
List, Map, Set이 어떤 자료(수치, 문자열)을 읽고 쓰기에 대한 추상화 였다면, Enumerationrhk 과 Iterator는 List, Map, Set 꺼내는 일에 대해 추상화 하였다. A is a B - 소나타는 자동차 이다. - 상속관계 처리하라 A has a B - 도형안에 타원은 포함되어 있다. - 내부클래스로 설계하라

Room

package collec.list;

import java.util.ArrayList;
import java.util.List;

public class Room {
  	// 방의 제목을 나타내는 문자열 변수
	String title = null;
  	
  	// 방에 수용 가능한 인원을 나타내는 정수 변수, 초기값은 5
	int inwon = 5;
  
  	// 방에 있는 사람들의 이름을 저장하는 문자열 리스트
	List<String> names = new ArrayList<>();
}
List<String> names = new ArrayList<>();
  • List: Java에서 제공하는 인터페이스(interface)로, 여러 요소를 저장할 수 있는 동적 배열 데이터 구조
  • String: 이 리스트가 문자열(String) 타입의 요소를 저장한다는 것을 지정
  • ArrayList: Java의 컬렉션 프레임워크에서 동적 배열을 구현한 클래스
  • <>: 제네릭(generic) 타입. 여기서는 ArrayList가 어떤 타입의 요소를 저장할 것인지 지정

RoomMain

package collec.list;

public class RoomMain {
  	// Room 객체를 선언
	Room r1 = null;
	Room r2 = null;
  	
  	// 첫 번째 방의 정보를 초기화하는 메서드
	public void room1() {
  		// Room 객체 생성
		r1 = new Room();
  
  		// 첫 번째 방 정보 초기화
		r1.inwon = 7; // 최대 인원 7명
  		// 방 제목
		r1.title = "스프링 스터디 3기 모집";
  		// 방에 있는 사람들 이름 추가
		r1.names.add("나초보");
		r1.names.add("유재석");
		r1.names.add("강호동");
	}
  
  	// 두 번째 방의 정보를 초기화하는 메서드
	public void room2() {
  		// Room 객체를 다시 생성
		r1 = new Room();
  
  		// 두 번째 방 정보 초기화
		r1.inwon = 5; // 최대 인원 5명
  		// 방 제목 
		r1.title = "보드 같이 타실분 모집 - 달방 구함";
  		// 방에 있는 사람들 이름 추가
		r1.names.add("나신입");
		r1.names.add("나일등");
		r1.names.add("이성계");
	}
  
	public static void main(String[] args) {
		// RoomMain 객체 생성
		RoomMain rm = new RoomMain();
  
  		// room1 메서드 호출하여 첫 번째 방 정보 초기화
		rm.room1();
  
  		// 첫 번째 방 정보 출력
		for(int i = 0; i<rm.r1.names.size(); i++) {
		// 각 사람의 정보를 출력
		System.out.println("방 제목 : " + rm.r1.title);
		System.out.println("최대 인원수 : " + rm.r1.inwon);
		System.out.println(rm.r1.names.get(i));
		System.out.println("=================================================");
		}
	}
}

Spring에서는 개발자가 직접 인스턴스화 하지 않는다. 필요할 때 Spring이 대신(주도권이 넘어갔다) 객체를 주입해준다
(스프링 프레임워크는 객체 인스턴스화와 관리에 대한 많은 부분을 담당하며, 이를 통해 애플리케이션의 객체 라이프사이클을 관리)

객체가 생성되는 시점에 따라 문제가 발생할 수 있다

  • 이른 인스턴스화(Eager Instantiation)
    : 객체가 필요한 시점과 관계 없이 미리 생성되는 것. 클래스가 로드되거나 어플리케이션이 시작될 때 미리 생성되므로 객체가 필요한 시점에 빠르게 접근할 수 있지만, 메모리를 차지하고 초기화 비용이 발생할 수 있음(전역변수의 성격)
  • 게으른 인스턴스화(Lazy Instantiation)
    : 객체를 필요한 시점에서 생성(객체가 처음으로 요청될 때 생성). 초기화 비용과 메모리 사용을 줄일 수 있으나 객체가 필요한 시점까지 대기해야 할 수 있고, 일부 성능 저하가 발생할 수 있음(지역적으로 처리)

Spring 프레임워크의 IoC (Inversion of Control) 컨테이너는 객체의 라이프사이클과 의존성 관리를 담당하며, 이를 통해 NullPointerException과 같은 예외를 방지할 수 있음


<VO or Map으로 CRUD 처리하기>

CustomerVO

  • 이 클래스는 고객 정보를 저장하고 조작하는 데 사용될 수 있으며, 멤버 변수의 private 접근 제어자를 통해 캡슐화를 제공하고 데이터의 무결성을 보호
package collec.list;

public class CustomerVO {

    // 고객 id 저장하는 멤버 변수
	private int c_id;
    // 고객 이름 저장하는 멤버 변수
	private String c_name=null;
	// 고객 생년월일 저장하는 멤버 변수
	private String c_birthday;

    // 고객 ID 반환 메서드      
	public int getC_id() {
		return c_id;
	}
  	// 고객 ID 설정 메서드   
	public void setC_id(int c_id) {
		this.c_id = c_id;
	}
     
    // 고객 이름 반환 메서드                     
	public String getC_name() {
		return c_name;
	}
  	// 고객 이름 설정 메서드
	public void setC_name(String c_name) {
		this.c_name = c_name;
	}
  
    // 고객 생년월일 반환 메서드
	public String getC_birthday() {
		return c_birthday;
	}
  	// 고객 생년월일 설정 메서드
	public void setC_birthday(String c_birthday) {
		this.c_birthday = c_birthday;
	}
}                                             
  • Getter 메서드는 해당 멤버 변수의 값을 반환하고, Setter 메서드는 해당 멤버 변수에 값을 설정

캡슐화(Encapsulation)

  • 데이터와 데이터를 조작하는 메서드를 하나로 묶는 것

캡슐화의 주요 특징

1. 데이터 은닉: 캡슐화는 객체 내부의 데이터를 외부로부터 감추는 것을 의미합니다. 멤버 변수(데이터)를 private 또는 다른 적절한 접근 제어자로 설정함으로써, 외부에서 직접 접근할 수 없도록 합니다. 이렇게 함으로써 데이터의 무결성을 보호하고, 오류와 부작용을 방지할 수 있습니다.

2. 메서드 제공: 데이터를 조작하고 접근하기 위한 공개된 메서드를 제공합니다. 이 메서드를 통해 데이터에 접근하고 변경할 수 있으며, 메서드 내에서 데이터에 대한 유효성 검사 및 로직을 추가할 수 있습니다. 이로써 데이터의 일관성을 유지하고 제어할 수 있습니다.

3. 데이터 캡슐화: 데이터와 데이터를 조작하는 메서드를 하나의 단위로 묶어 데이터 캡슐화를 실현합니다. 이로써 객체의 내부 구현을 숨길 수 있으며, 객체 간의 상호작용을 명확하게 정의합니다.

CustomerManager

package collec.list;

import java.util.ArrayList;
import java.util.List;

public class CustomerManager {
	List<CustomerVO> cList = null;//전변은 언제 스캔이 되나요?
	CustomerManager(){
		cList = new ArrayList<>();
	}
	CustomerManager(int i){
	}
	/***********************************************************
	 * 고객정보 등록하기 구현 - 없는 것을 새로 등록하기
	 * INSERT INTO customer(c_id, c_name, c_birthday) VALUES(1,'zldnl', 2000-10-21')
	 * @param cVO - 한 번에 여러가지의 값을 넘겨 받을 수 있는 VO를 사용한다.
	 * @return
	 ***********************************************************/
	public boolean customerInsert(CustomerVO cVO) {
		boolean isOk = false;
		return isOk;
	}
	/************************************************************
	 * 고객정보 수정하기 구현 - 기존에 있는 정보를 변경하기
	 * select(1건) - rcVO(1건) or Map(1건) - pcVO - 1이면 수정 성공, 0이면 수정 실패 판정
	 * UPDATE customer SET c_name = ?, c_birthday = ? WHERE c_id = ?
	 * @param cVO
	 * @return
	 *************************************************************/
	public boolean customerUpdate(CustomerVO cVO) {
		boolean isOk = false;
		return isOk;
	}
	/**************************************************************
	 * 고객정보 삭제하기 구현
	 * DELETE FROM cutomer WHERE c_id = ? (primary key)
	 * @param int
	 * @return true이면 성공, false이면 실패 - 메소드 선언시에 파라미터타입에 대한 선택과 리턴타입에 대한 선택 기준
	 ***************************************************************/
	public boolean customerDelete(CustomerVO cVO) {
		boolean isOk = false;
		return isOk;
	}
	/****************************************************************
	 * 고객정보 상세보기 구현
	 * SELECT c_id, c_name, c_birthday FROM customer WHERE c_id = ?
	 * @param c_id
	 * @return CustomerVO(한 테이블 일 때,) or Map(두 테이블 이상이여서 조인이 불가피 할 때)
	 ****************************************************************/
	public CustomerVO customerSelect(int c_id) {
		CustomerVO rcVO = null;
		return rcVO;
	}
	/*****************************************************************
	 * 고객정보 전체보기 구현 - 파라미터가 필요없다. 왜냐하면 - 조건절이 필요없으니까요.
	 * SELECT c_id, c_name, c_birthday FROM customer
	 * @return List<VO> or List<Map>
	 ******************************************************************/
	public List<CustomerVO> customerSelectAll() {
		List<CustomerVO> cList = null;
		return cList;
	}
	public static void main(String[] args) {
		CustomerManager cm = null;
		cm = new CustomerManager(0);
	}

}

Map

변수를 사용시에는 검색기능 지원하려면 개발자가 직접 검색 엔진을 구현해야 한다. → api로 제공해줌(컬렉션 프레임워크)
자유게시판(Q&A게시판, 양도게시판, 공지게시판, 이벤트 게시판 등) - 게시판 솔루션화
새 글 쓰기 - insert - 글 번호가 없다. 왜? 글 번호를 새로 채번한다.
댓글 쓰기(응답, 요청,,, 등) - insert - 기존에 글을 읽고 나서 내 생각을 붙인다. ㄴ 현재 내가 보고있는 글(1건 조회 - 글 번호가 있다.)이 있고, 그 글을 읽은 후에 댓글쓰기 버튼을 누른다.

  • '새 글 쓰기/댓글 쓰기' 작업을 처리하는 boardInsert 메소드
    (두 가지 유형을 하나의 메소드 안에서 처리 가능함)
public int boardInsert() {
int result = 0;
  
	if(! pmap.constainsKey("b_no")) { 
  		// 새 글 쓰기 로직 구현
	} 
  	else { 
  		// 댓글 쓰기 로직 구현
	}
      	// 여기서 insert 처리하는 메소드를 호출하거나 결과를 반환하도록 구현
		return result;
}

MapMain1

HashMap
1. HashMap 객체 생성

HashMap<KeyType, ValueType> hashMap = new HashMap<>();
- KeyType: 키의 데이터 타입
- ValueType: 값의 데이터 타입
  1. 키-값 쌍 추가
    • HashMap에 값을 추가하려면 put 메서드를 사용
hashMap.put("apple", 5);
hashMap.put("banana", 10);
hashMap.put("cherry", 3);
  1. 값 검색
    • HashMap에서 값을 검색하려면 get 메서드를 사용해 특정 키에 대한 값을 가져옴
int count = hashMap.get("banana");
  1. 키 존재 여부 확인
    • HashMap에서 특정 키가 존재하는지 확인하려면 containsKey 메서드를 사용. 이 메서드는 true 또는 false를 반환
boolean exists = hashMap.containsKey("apple");
	// "apple" 키가 존재하면 exists를 true로 설정
package collec.map;

import java.util.HashMap;
import java.util.Map;

class Map1{
    // HashMap으로 인스턴스화된 map 변수 선언
	Map<String, Object> map = new HashMap<>();
  
  	// 기본 생성자
	Map1() {
  		// 초기 상태에서 HashMap의 크기 출력 (0) - 원본의 수
		System.out.println(map.size()); 
  
  		// HashMap에 "1" 키와 값 1을 추가하고, 크기 출력 (1)
		map.put("1", 1); 
		System.out.println(map.size()); 
  		
 		// HashMap에서 "1" 키가 존재하는지 확인 (true)
		System.out.println(map.containsKey("1"));  	
  		// HashMap에서 "2" 키가 존재하는지 확인 (false)
  		System.out.println(map.containsKey("2"));  
  
  		// HashMap의 내용 출력 ({1=1})
		System.out.println(map);  
	}
  
  	// 생성자, 매개변수 i를 받음
	Map1(int i){
  		// HashMap을 새로운 객체로 다시 초기화 - 복제본
		map = new HashMap<>();
  
  		// 초기 상태에서의 크기 출력 (0) - 복제본
  		// map을 복제하고 put을 호출하지 않았으므로 0
		System.out.println(map.size()); 
	}
}
public class MapMain1 {

	public static void main(String[] args) {
  		// Map1 클래스의 기본 생성자를 호출하여 객체 m1 생성
		Map1 m1 = new Map1(); 
  
		// HashMap에서 "1" 키를 통해 값을 가져와 출력 (1)
  		// 전역변수가 읽혀진다 - 디폴트 생성자가 호출되었으니까 출력이 될거야
		System.out.println(m1.map.get("1"));
  
		// Map1 클래스의 생성자를 호출하여 객체 m2 생성, 매개변수 0 전달
		Map1 m2 = new Map1(0);
	}
}

Q. Map은 인터페이스이기 때문에 구현체 클래스 HashMap으로 인스턴스화를 해야 한다?

Map<String, Object> map = new HashMap<>();
  • HashMap은 Map 인터페이스의 구현 중 하나로, HashMap이 제공하는 특별한 기능을 사용하려면 해당 클래스의 메서드를 직접 호출할 수 있어야 함(인터페이스만으로는 HashMap의 고유한 메서드에 액세스할 수 없음)
  • 위 코드는 map 변수의 데이터 타입이 Map 인터페이스로 선언되었지만, 실제로는 HashMap 클래스로 인스턴스화 되어 사용
  • 이렇게 함으로써 map을 다른 Map 인터페이스를 구현하는 클래스로 쉽게 교체하거나 확장할 수 있게 됨

클래스를 인스턴스화할 때, 변수의 데이터 타입은 해당 클래스가 아닌 인터페이스로 선언하는 것이 일반적으로 권장되는 프로그래밍 관행 중 하나입니다. 이렇게 하는 이유는 코드의 유연성을 높이고 다형성을 활용하기 위함입니다. 다음은 이에 대한 설명입니다:

1. 다형성 활용
: 변수를 인터페이스 타입으로 선언하면, 여러 구현 클래스를 대입할 수 있습니다. 이것은 코드의 확장성과 재사용성을 높입니다. 예를 들어, Map 인터페이스를 사용하면 HashMap, LinkedHashMap, TreeMap 등과 같은 다양한 Map 구현을 같은 변수에 대입할 수 있습니다.

2. 인터페이스에 의한 추상화
: 인터페이스를 사용하면 클래스가 아닌 특정 동작 및 기능에 초점을 맞출 수 있습니다. 코드를 인터페이스에 의존시키면 클래스 간의 결합도를 낮추고, 클래스의 변경이 다른 부분에 미치는 영향을 줄일 수 있습니다.

3. 유연한 코드
: 코드가 인터페이스에 의존할 때, 나중에 해당 인터페이스를 구현하는 다른 클래스로 교체하기가 더 쉬워집니다. 이것은 기존 코드의 수정을 최소화하고 새로운 클래스를 쉽게 통합할 수 있게 합니다.

Car

  • 추상 클래스(Abstract Class): 일부 메서드가 구현되지 않은(추상 메서드) 클래스로, 다른 클래스에 의해 확장되고 완성되어야 하는 클래스

    <추상 클래스 특징>

    1. 추상 메서드 포함
    : 추상 클래스는 하나 이상의 추상 메서드를 포함. 추상 메서드는 본문이 없고 메서드의 시그니처만 정의된 메서드로, 하위 클래스에서 구현해야 함
    2. 인스턴스화 불가능
    : 추상 클래스는 직접 인스턴스화할 수 없으며, 추상 클래스의 객체를 생성할 수 없음
    3. 하위 클래스에서 확장 및 구현
    : 추상 클래스는 하위 클래스에서 상속되고 확장되어야 함. 하위 클래스에서는 추상 메서드를 구현하고 나머지 메서드 및 속성을 확장할 수 있음
    4. 일반 메서드 포함 가능
    : 추상 클래스는 추상 메서드 외에도 구체적인 메서드(일반 메서드)를 포함할 수 있음. 하위 클래스에서 추상 메서드 외에도 일반 메서드를 상속하고 사용할 수 있음
    5. 상속을 통한 다형성 구현
    : 추상 클래스와 하위 클래스를 사용하면 다형성을 구현할 수 있음. 추상 클래스의 참조를 사용하여 다양한 하위 클래스의 객체를 다룰 수 있음

<추상클래스와 인터페이스의 차이>

1. 추상 클래스(Abstract Class)

  • 추상 클래스는 추상 메서드(abstract method)뿐만 아니라 일반 메서드(concrete method)를 포함할 수 있습니다.
  • 따라서 추상 클래스는 구체적인 메서드 구현과 추상 메서드를 혼합하여 가질 수 있습니다.
  • 추상 클래스를 확장하는 클래스는 모든 추상 메서드를 구현해야 합니다.


    2. 인터페이스(Interface)

  • 인터페이스는 오직 추상 메서드만을 선언할 수 있으며, 메서드에 대한 구체적인 구현을 가질 수 없습니다.
  • 인터페이스는 다중 상속을 지원하므로 클래스가 여러 인터페이스를 구현할 수 있습니다.
  • 구현(클래스)하는 클래스는 모든 인터페이스의 추상 메서드를 구현해야 합니다.
package collec.map;

// 추상 클래스 Car 정의
public abstract class Car {
  	
	int speed; 		 // 자동차 속도
	String carName;	 // 자동차 이름
	String carColor; // 자동차 색상
  	
  	// 기본 생성자
	Car() {}
  	
  	// 자동차 정보를 표시하는 추상 메서드
	public abstract void display();
  
  	// 속도를 증가시키는 메서드
	public void go() {
		speed = speed +1;
	}
  
  	// 속도를 감소시키는 메서드
	public void stop() {
		speed = speed -1;
	}
}
  • 이 추상 클래스를 상속받는 구체적인 자동차 클래스를 작성하려면 display 메서드를 반드시 구현해야 하며, go/stop 메서드는 이 클래스에서 상속받아 사용할 수 있음

Sonata

  • 오버라이딩(Overriding): 객체 지향 프로그래밍에서 하위 클래스(subclass)가 상위 클래스(superclass)로부터 상속받은 메서드를 재정의하는 과정

상속(Inheritance)
부모 클래스(슈퍼 클래스) - 자식 클래스(서브 클래스)

Q. 부모 클래스와 자식 클래스 양쪽에 같은 이름의 메서드가 있다면?

  • 만약 자식 클래스에서 해당 메서드를 재정의(오버라이딩)하였다면, 자식 클래스의 오버라이딩된 메서드가 호출(이게 일반적인 동작)
    *쉐도우 메서드(메서드 쉐도잉): 오버라이딩된 메서드가 부모 클래스의 메서드를 가리는 효과

  • 만약 자식 클래스에서 해당 메서드를 오버라이딩하지 않았거나, 부모 클래스의 메서드를 호출하기 위해 super 키워드를 사용한 경우, 부모 클래스의 메서드가 호출

<Sonata - 추상 클래스(Car)를 확장+여러 메서드를 구현>
  
package collec.map;

public class Sonata extends Car {
	
  	// Car 추상 클래스의 추상 메서드 display를 구현
	@Override
	public void display() {
		// 구체적인 내용은 비어있음
	}
  
  	// Sonata 클래스의 고유한 메서드
	public void other() {
		System.out.println("Sonata other메소드 호출");
	}
	
  	// 부모 클래스 Car의 메서드인 stop을 오버라이딩
	public void stop() {
		System.out.println("Sonata stop 호출");
		speed = speed -2;
	}
	public static void main(String[] args) {
  		// Car 클래스의 객체를 Sonata 클래스의 객체로 초기화
		Car myCar = new Sonata();
  
		// 메소드 오버라이딩
		Sonata himCar = new Sonata();
		// myCar.other();  // 불가능
  
  		// Sonata의 other 메서드 호출
		himCar.other(); 
  		// Sonata 객체의 stop 메서드 호출 (다형성)
		myCar.stop();
	}
}

Q. myCar타입의 변수로 Sonata클래스에 정의된 메소드를 호출할 수 있을까?

Car myCar = new Sonata();
  
- myCar 변수를 Car 타입으로 선언
- 이 변수에 Sonata 클래스의 인스턴스를 할당
- myCar 변수를 통해 Sonata 클래스의 메서드를 호출할 수 있음(다형성)
  • myCar 변수를 통해 Sonata 클래스에 정의된 메서드를 직접 호출할 수 없음. 변수의 정적 타입인 Car에 해당 메서드가 없기 때문
    : myCar 변수의 정적 타입은 Car이지만, 할당된 객체는 Sonata 클래스의 인스턴스

MapMain2

<MapMain2-1. Map 제네릭에 VO 넣기>
  
package collec.map;

import java.util.HashMap;
import java.util.Map;
  
import collec.list.CustomerVO;

class Map2{
  	// CustomerVO 객체를 값으로 갖는 Map 생성
	Map<String, CustomerVO> map = new HashMap<>();
  
	Map2() {
  		// Map의 크기 출력(0) (처음에는 비어 있음) - 원본
		System.out.println(map.size()); 
  
		// CustomerVO 객체 생성
		CustomerVO cvo = new CustomerVO();
  
  		// CustomerVO 객체의 이름 설정
		cvo.setC_name("나신입");
  
  		// Map에 "1" 키와 CustomerVO 객체를 매핑
		map.put("1", cvo);
  
  		// Map의 크기 출력(1) (하나의 요소를 추가했으므로) - 원본
		System.out.println(map.size());  
		
 		System.out.println(map.containsKey("1"));  // true
		System.out.println(map.containsKey("2"));  // false
  
  
  
		// map 안에 키가 "1"인 값은 CustomerVO타입이다.
		// 이것을 증명할 수 있는 낱말카드를 나는 작성할 수 있다? 없다?
		System.out.println(map);  // {1=CustomerVO 주소번지}
	}
}

public class MapMain2 {

	public static void main(String[] args) {
		System.out.println("main");
  
  		// Map2 클래스의 객체 생성
		Map2 m = new Map2(); 
  
  		// Map에서 "1" 키로 CustomerVO 객체를 가져옴
		CustomerVO cvo = m.map.get("1");
  
  		// CustomerVO 객체 출력
		System.out.println(cvo); // 여기서 출력되는 주소번지와
		System.out.println(m.map.get("1")); // 여기서 출력되는 주소번지가 같니?
  
		// 아래 두 코드는 같은 코드
		System.out.println(cvo.getC_name());
		System.out.println(m.map.get("1").getC_name());
		
		System.out.println(cvo.getC_name().equals(m.map.get("1").getC_name()));
		System.out.println(cvo.equals(m.map.get("1")));
  
		System.out.println(cvo instanceof CustomerVO); // 둘이 같은 타입이야??
		System.out.println(m.map.get("1") instanceof CustomerVO); // 둘이 같은 타입이야??
		// 화면 솔루션과 자바 연동할 때 - 이종간에 연계할 때  - 공통코드로 사용했던 부분
	}
}
<MapMain2-2. Map 제네릭에 VO 넣기, 값 꺼내기>
package collec.map;

import java.util.HashMap;
import java.util.Map;

import collec.list.CustomerVO;

class Map2{
	Map<String, CustomerVO> map = new HashMap<>();
  
	Map2() {
		System.out.println(map.size());  // 원본의 수 - 0
		// insert here
		CustomerVO cvo = new CustomerVO();
		cvo.setC_name("나신입");
		cvo.setC_id(1);
		cvo.setC_birthday("1996-10-10");
		map.put("1", cvo); // map.size() = 1 
		System.out.println(map.size());  // 원본의 수 - 1
		System.out.println(map.containsKey("1"));  // true
		System.out.println(map.containsKey("2"));  // false
		// map 안에 키가 "1"인 값은 CustomerVO타입이다.
		// 이것을 증명할 수 있는 낱말카드를 나는 작성할 수 있다? 없다?
		System.out.println(map);  // {1=CustomerVO 주소번지}
//		// JSON 포맷에서 [{},{},{} ,,,,,,,,, label:[{},{},{},,,,]]
	}
}
public class MapMain2 {

	public static void main(String[] args) {
		System.out.println("main");
		Map2 m = new Map2(); 
		CustomerVO cvo = m.map.get("1");
		System.out.println(cvo); // 여기서 출력되는 주소번지와
		System.out.println(m.map.get("1")); // 여기서 출력되는 주소번지가 같니?
		// 아래 두 코드는 같은 코드
		System.out.println(cvo.getC_name());
		System.out.println(m.map.get("1").getC_name());
		System.out.println(m.map.get("1").getC_id());
		System.out.println(m.map.get("1").getC_birthday());
		
		System.out.println(cvo.getC_name().equals(m.map.get("1").getC_name()));
		System.out.println(cvo.equals(m.map.get("1")));
		System.out.println(cvo instanceof CustomerVO); // 둘이 같은 타입이야??
		System.out.println(m.map.get("1") instanceof CustomerVO); // 둘이 같은 타입이야??
		// 화면 솔루션과 자바 연동할 때 - 이종간에 연계할 때  - 공통코드로 사용했던 부분
		
		
	}

}

MapMain3

< Map 안에 List 안에 Map 안에 VO>
package collec.map;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import collec.list.CustomerVO;

class Map3{
	Map<String, List<Map<String, CustomerVO>>> map = new HashMap<>();
	Map3(){
		List<Map<String, CustomerVO>> list = new ArrayList<>();
		Map<String, CustomerVO> imap = new HashMap<>();
		CustomerVO cvo = new CustomerVO();
		cvo.setC_id(12);
		cvo.setC_name("토마토");
		cvo.setC_birthday("2000-05-11");
		imap.put("1", cvo);
		list.add(imap);
		map.put("outer", list);
	}
}
public class MapMain3 {
	public static void main(String[] args) {
		Map3 m3 = new Map3();
		System.out.println(m3.map.size()); 
		// m3.map.get("1") 이것은 무슨 타입???
		System.out.println(m3.map.get("1"));
		// m3.map.get("outer") 이것은 무슨 타입?? - [{1=collec.list.CustomerVO@251a69d7}] -> List 타입
		System.out.println(m3.map.get("outer"));
		System.out.println(m3.map.get("outer") instanceof List);
		// m3.map.get("outer").get(0)은 무슨 타입? - Map 타입 {} 
		System.out.println(m3.map.get("outer").get(0) instanceof Map);
		System.out.println(m3.map.get("outer").get(0).get("1") instanceof CustomerVO);
		
		System.out.println(m3.map.get("outer").get(0).get("1").getC_id());
		System.out.println(m3.map.get("outer").get(0).get("1").getC_name());
		System.out.println(m3.map.get("outer").get(0).get("1").getC_birthday());
	}

}

MapMain4

// Map Delete

package collec.map;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import collec.list.CustomerVO;

class Map4{
	// 다형성을 누릴 수 있다. - 다를 수 밖에 없다. - 왜냐면 Map은 인터페이스 이기 때문에 구현체 클래스HashMap으로 인스턴스화를 해야 한다.
	Map<String, CustomerVO> map = new HashMap<>();
	Map4(){
		CustomerVO cvo = new CustomerVO();
		cvo.setC_name("나신입");
		cvo.setC_id(1);
		cvo.setC_birthday("1996-10-10");
		map.put("1", cvo); // map.size() = 1 
	}
	void mapDelete() {
		map.remove("1");
	}
}
public class MapMain4 {
	public static void main(String[] args) {
		Map4 m = new Map4(); 
		System.out.println(m.map);
		Set<Map.Entry<String, CustomerVO>> entrySet = m.map.entrySet();
		Iterator<Map.Entry<String, CustomerVO>> entryIterator = entrySet.iterator();
		while(entryIterator.hasNext()) {
			Map.Entry<String, CustomerVO> entry = entryIterator.next();
			String key = entry.getKey(); // String 타입임
			CustomerVO cvo = entry.getValue();
			System.out.println(key+", "+ cvo);
		}
		System.out.println("=============[[ 삭제 후 ]]=============");
//		m.mapDelete(); // 하나만 삭제하는 remove를 담은 메소드
		m.map.clear(); // 전체 삭제 메소드
		System.out.println(m.map);
	}
}

KeyMain1

package collec.map;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

// 소셜로그인 구현, 카카오 우편번호 검색, 카카오페이  도전? Map에 집중하기
public class KeyMain1 {

	public static void main(String[] args) {
		Map<Integer, String> map = new HashMap<>();
		map.put(1, "85"); 
		map.put(2, "75"); 
		map.put(3, "65");
		Object names[] = null;
//		System.out.println(names.length); 
		Set<Integer> set = map.keySet(); // Set의 제네릭 타입은 Map의 키값과 같은 타입으로 맞춰야 한다.
		names = set.toArray();
		System.out.println(names.length);
		for(int i = 0; i <names.length; i++) {
			int key = (Integer)names[i];
			System.out.println(key);
		}
	}

}

AMain1

// KeyMain1.java와 동일한 구조
package collec.map;
class A1{
	A2 keySet() {
		return new A2();
	}
}
class A2{
	Object[] toArray() {
		return new Object[3];
	}
}
public class AMain1 {
	public static void main(String[] args) {
		A1 a1 = new A1();
		Object objs[] = a1.keySet().toArray();
		System.out.println(objs.length);
		for(Object obj:objs)
		{
			System.out.println(obj);
		}
	}
}                               

아래 3가지를 사용해서 조회 하기
Dept[] dept[0] = new DeptVO(); dept[1] = new DeptVO(); dept[2] = new DeptVO();
List
List<Map<String, Object>>

DeptVO

<DeptVO-1>
package collec.map;
// Spring으로 가면 Lombok 이라는 라이브러리로 대체한다. -> Spring JPA로 DB연동을 하면 쿼리문 대신 클래스 설계가 필요함.
// 접근제한자를 private으로 하는 이유가 웹서비스시에 싱글톤 처리
// 인스턴스 변수 직접 접근하는 방식이 아니라 사용자 마다 인스턴스화를 통해서 지역적으로
// 사용하고 소멸시킨다. - 로그아웃 할 때 소멸시킨다. - 지역변수의 성격으로 처리함.(웹서비스 라서.)
// 지역변수의 성격을 갖는 파라미터 자리를 활용할 수 있어서 전역변수가 아니더라도 활용에 문제 없음
// 파라미터 자리에 값을 넘겨서 처리하면 그 메소드 영역에서만 유지됨 - 람다식, 화살표 함수 - 코드의 양을 줄여준다.
public class DeptVO { // 자바와 오라클 자바와 mysql 자바와 몽고dB
	private int deptno;
	private String dname;
	private String loc;
	public int getDeptno() {
		return deptno;
	}
	public void setDeptno(int deptno) {
		this.deptno = deptno;
	}
	public String getDname() {
		return dname;
	}
	public void setDname(String dname) {
		this.dname = dname;
	}
	public String getLoc() {
		return loc;
	}
	public void setLoc(String loc) {
		this.loc = loc;
	}
}
                                

DeptList1

package collec.map;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Map;
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;

public class DeptList1 extends JFrame implements ActionListener {
	JPanel jp_north = new JPanel();
	JButton jbtn_sel = new JButton("조회");
	String header[] = {"부서번호","부서명","지역"};
	String data[][] = new String[0][3];
	DefaultTableModel dtm = new DefaultTableModel(data, header);
	JTable jt = new JTable(dtm);
	JScrollPane jsp = new JScrollPane(jt);
	DeptVO init1(int deptno, String dname, String loc) {
		DeptVO dvo = new DeptVO();
		dvo.setDeptno(deptno);
		dvo.setDname(dname);
		dvo.setLoc(loc);
		return dvo;
	}
	void arrayPrint() {
		DeptVO[] dvos = getDeptList1();
		for(int i=0;i<dvos.length;i++) {
			Vector<Object> v = new Vector<>();
			v.add(dvos[i].getDeptno());
			v.add(dvos[i].getDname());
			v.add(dvos[i].getLoc());
			dtm.addRow(v);
		}
	}
	DeptVO[] getDeptList1() {
		DeptVO[] dvos = new DeptVO[3];
		for(int i=0;i<dvos.length;i++) {
			dvos[i] = init1((i+1)*10,"개발"+(i+1)+"팀", "서울"+(i+1));
		}
		return dvos;
	}
	
	List<DeptVO> getDeptList2(){
		return null;
	}
	
	List<Map<String,Object>> getDeptList3(){
		return null;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		Object obj = e.getSource();
		if(obj == jbtn_sel) { // 너 조회버튼 누른거야?
			arrayPrint();
		}
	}
	void initDisplay() {
		jp_north.setLayout(new FlowLayout(FlowLayout.LEFT));
		jbtn_sel.addActionListener(this);
		jp_north.add(jbtn_sel);
		this.add("North", jp_north);
		this.add("Center", jsp);
		this.setTitle("부서목록");
		this.setSize(600, 400);
		this.setVisible(true);
	}
	public static void main(String[] args) {
		DeptList1 dt = new DeptList1();
		dt.initDisplay();
	}
}

0개의 댓글