JAVA 웹개발 과정 국비 26일차 정리

26일차

※ 배우는 과정이므로 정확하지 않을 수 있습니다.
잘못된 점은 알려주시면 수정하도록 하겠습니다!


메뉴 관리 시스템 예제에 어제 배운 날짜 기능을 추가시키는 연습을 했다.
날짜 하나만 추가한 건데도 많이 어려웠다.

1. Date 클래스

날짜를 입력받아 DB에 추가하기

1) import java.sql.Date

MenuDTO에 메뉴 등록일 멤버필드를 추가하려고 한다.
private Date reg_date; 를 쓰고 자동 import를 누르니 Date 클래스가 두개가 보인다.

  1. java.util.Date
  2. java.sql.Date

MenuDTO는 DB에 쿼리를 날려서 데이터를 저장해야하는 클래스이므로 sql.Date 클래스로 import를 해준다.

import java.sql.Date;

public class MenuDTO {
	private int id;
	private String name;
	private int price;
	private Date reg_date;
}

2. 입력 날짜를 Date 타입으로 바꾸기

날짜 멤버필드가 생겼으므로, 등록된 메뉴의 등록 날짜를 입력받아 날짜를 수정하려고 한다.
기존에 해줬던 대로 날짜를 입력받아 생성자에 넣어준다.

// Main Class
System.out.print("수정할 메뉴 ID : ");
int id = Integer.parseInt(sc.nextLine());
System.out.print("수정할 메뉴 이름 : ");
String name = sc.nextLine();
System.out.print("수정할 메뉴 가격 : ");
int price = Integer.parseInt(sc.nextLine());
System.out.print("수정할 메뉴 등록일 (yyyy/MM/dd) : ");
String reg_date = sc.nextLine();

int result = dao.update(new MenuDTO(id, name, price, reg_date));

그러나 new 부터 끝까지 빨간 줄로 쭉 에러가 생긴다. 이유는 아래와 같이 타입이 맞지 않기 때문이다.

  • MenuDTO의 reg_date : Date 타입
  • 입력값 : String 타입

따라서 SimpleDateFormat 클래스의 parse 메소드를 사용하여 String 값을 Date 타입으로 바꿔주어야 한다.
그리고 Date 타입을 import 해준다.
여기서는 어떤 Date 클래스를 import 해주어야할까?
parse 메소드가 util.Date타입으로 리턴해주기 때문에 java.util.Date 를 import 해준다.

// Main Class
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
Date date = sdf.parse(reg_date);

int result = dao.update(new MenuDTO(id, name, price, reg_date));

3) util.Date 타입을 sql.Date 타입으로 바꾸기

그러나 아래 new MenuDTO(id, name, price, reg_date) 부분이 또 빨간줄이 그어지며 에러가 생긴다. 마찬가지로 타입이 맞지 않는다.

  • MenuDTO의 reg_date : sql.Date 타입
  • 입력값 : String 타입 -> util.Date 타입

모든 Date 타입 가운데에는 Timestamp가 있다!
여기서 Timestamp를 배운 이유가 나온다. 바로 Timestamp를 이용하여 Date 타입을 변환할 수 있다.

Date sqlDate = new Date(date.getTime());

4) 클래스 이름이 겹친다면

그런데, 코드를 작성하고 나니 어떤 Date가 어떤 Date 타입인지 구별이 가지 않는다.
이럴 때는 import 하지 않은 클래스를 전체 경로를 써줘야한다.

java.sql.Date sqlDate = new java.sql.Date(date.getTime());

이렇게 하면 에러 없이 동작하는 코드를 만들 수 있다.

2. utils.DataUtils

범용성을 띄는, 예를 들면 위에서와 같이 문자열을 sql.Date로 만들어서 내보내는 코드들은 여러곳에서 사용될 수 있기 때문에 한 곳에 모아서 관리해주는 것이 좋다.

utils 패키지에 DateUtils 클래스를 만들어 준 뒤, 아래와 같이 메소드를 만들고 static을 붙여주면 더욱 편한 코딩을 할 수 있다.

package utils;

import java.sql.Date;

public class DateUtils {
	public static Date stringToSQLDate(String str, String format) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return new Date(sdf.parse(str).getTime());
	}
}

3. New가 쓰이는 변수와 안쓰이는 변수

문제를 풀다가 막혔던 부분이 있다.

Date utilDate = sdf.parse(visitDate);  // 1

Date sqlDate = new Date(utilDate.getTime());  // 2

같은 Date 타입인데 1번 코드는 new를 쓰지 않고, 2번 코드는 new를 써서 인스턴스를 생성하는 것이다.
처음에는 위의 Date 타입은 util.Date이고 아래는 sql.Date이기때문에 다른 건가.. 싶었는데 말이 되지 않았다.

강사님께 질문을 했더니, 아래와 같은 힌트를 하나 더 주셨다.

Connection con = DriverManager.getConnection();  // 1

Scanner sc = new Scanner(System.in);  // 2

위의 두가지 코드가 다른 것과 같은 이유라고 하셨는데, 열심히 고민해본 결과 나의 답은 1번 코드는 똑같은 자료형이고 2번 코드는 Scanner 자료형으로 만들어줘야해서..?? 라고 했는데
아니었다 ㅋㅋㅋㅋ

답은 메소드에 있었다!
1번 코드는 parse메소드와 getConnection메소드가 각각 Date 객체와 Connection 객체를 반환하기 때문에 new를 써서 내가 객체를 생성해주지 않아도 되는 것이고,
2번 코드는 그러한 메소드가 없기 때문에 직접 new를 써서 객체를 생성해주어야 하는 것이다.

객체를 생성하지 않는 변수와 객체를 생성하는 변수는 따로 있지 않다.
숨어있냐 아니냐로 구분하는 것이다! 모든 객체는 다 생성을 해줘야한다!!!
이것 때문에 골머리를 앓았는데 앓던 이가 빠진 기분이였다 ㅠㅠ
강사님께 정말 감사했다..!

댓글남기기