JAVA

221027 Serializable, DTO

주영재 2022. 10. 27. 18:34

Serializable(직렬화)
=>인스턴스를 다른 곳에 전송할 수 있도록 해주는 것
=>전송한다는 의미는 파일 단위로 읽고 쓰는 것도 전송으로 간주하고 컴퓨터와 컴퓨터 또는 Component와 Component 사이를 왔다갔다 하는 것도 전송한다고 합니다.
이럴 때 사용하는 값의 집합을 나타내기 위한 인스턴스를 DTO(Data Transfer Object)라고 합니다.
=>Java에서는 인스턴스 단위로 데이터를 전송하고자 하면 Serializable 인터페이스를 implements하면 됩니다.
별도의 메서드 구현이 필요 없음. 유일하게 추상메서드를 오버라이딩 할 필요도 없다. 그냥 implements하면 끝.
=>응용프로그램을 만들 때 자신만의 저장 형식을 갖고자 하는 경우 사용하고 안드로이드에서 Activity(화면) 사이에 데이터 전송을 하고자 하면 사용합니다.
=>DataInputStream과 DataOutputStream을 이용해서 사용합니다.
=>데이터를 전송하고 전송받을 때 데이터는 항상 하나로 만들어두는 것이 좋음
블랙박스나 이메일도 이 과정을 거친다. 

 
/*
데이터의 분류
=>하나의 데이터(scala data): Byte, Short, Character, Integer, Long, Float, Boolean, 자바는 String도. 
=>여러 개의 데이터(vector data)
배열과 List(Collection) : 동일한 종류의 비교 가능한 데이터-인덱스를 이용해서 데이터를 구분
VO클래스나 Map : 여러 개의 데이터를 하나로 묶을 때 사용-이름을 이용해서 데이터를 구분--->특별한 경우가 아니면 이거 사용. 인덱스로 구분하는건 만든 사람만 안다.
*/

1)직렬화를 위한 DTO클래스 생성
=>정수로 된 번호, 문자열로 된 이름, Date로 만들어진 생일을 저장

2)Main클래스를 만들어서 직렬화한 1개의 클래스를 확인하고 읽어오기

3)Main클래스를 만들어서 직렬화한 여러 개의 클래스를 확인하고 읽어오기


try~resource
=>jdk 1.7에서부터 지원되는 문법
=>Stream은 만들면 반드시 close를 해주어야 합니다.
하지 않으면 메모리 누수가 발생합니다.

형식
try(여기서 만든 객체가 AutoCloseable 인터페이스를 implements하고 있다면 close하지 않아도 try~catch구문을 벗어나면 자동적으로 close를 호출함){
}catch(Exception e){
}
단, AutoCloseable를 implements하고있는지 확인할 것.

 

DTO 클래스

package java_DTO.practice;

import java.io.Serializable;
import java.util.Date;


//인스턴스 단위로 읽고 쓰기가 가능한 클래스-Serializable 인터페이스 때문
public class DTOTestEx implements Serializable{
	private int num;
	private String name;
	private Date birthday;
	
	public DTOTestEx() {
		super();
		
	}
	
	public DTOTestEx(int num, String name, Date birthday) {
		super();
		this.num = num;
		this.name = name;
		this.birthday = birthday;
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	@Override
	public String toString() {
		return "DTOTestEx [num=" + num + ", name=" + name + ", birthday=" + birthday + "]";
	}
	
}

 

Main

package java_DTO.practice;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Date;

public class SerializableMain {
	public static void main(String[] args) {
		
		//인스턴스 단위에 파일에 기록할 수 있는 객체를 생성
		try (ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream("multiobject.txt"))){//이렇게하면 close()호출할 필요 없음.
			
			//기록할 인스턴스 생성
			DTOTestEx dto1 = new DTOTestEx(1, "아담", new Date());
			DTOTestEx dto2 = new DTOTestEx(2, "강진축구", new Date());
			
			
			//기록할 인스턴스가 여러개이므로 하나의 List로 묶어줍니다
			ArrayList<DTOTestEx> list = new ArrayList<>();
			list.add(dto1);
			list.add(dto2);
			
			//기록
			oos.writeObject(list);//write는 한번만에 해야 함. 데이터는 하나. 파워포인트를 열 때 여러 개의 파워포인트를 열기 위해 파워포인트앱을 여러번 클릭하진 않음. 
		} catch (Exception e) {
			System.out.println(e.getLocalizedMessage());
		}
		
		try(//인스턴스 단위에 파일에 읽어낼 수 있는 객체를 생성
				ObjectInputStream ois = new ObjectInputStream(new FileInputStream("multiobject.txt"))) {
			
			
			//기록을 할 때 List를 사용했으므로 읽어올 때 List로 읽어와야 합니다.
			ArrayList list = (ArrayList)ois.readObject();//형변환
			for(Object obj : list) {
				System.out.println(obj);
			}
			
			
		} catch (Exception e) {
			System.out.println(e.getLocalizedMessage());
		}
	}

}
DTOTestEx [num=1, name=아담, birthday=Thu Oct 27 18:34:36 KST 2022]
DTOTestEx [num=2, name=강진축구, birthday=Thu Oct 27 18:34:36 KST 2022]

multiobject.txt파일에 깨져있는 어떤 글로 기록되어 있다. ObjectOutputStream으로 기록하고, ObjectInputStream으로 읽는 것.