부트캠프/프로젝트

[부트캠프] NBCStudentManager 2일차

Cocori_ 2024. 8. 9. 19:51

프로젝트 명 NBCStudentManager 

프로젝트 종료 KPT작성 후에 이 글을 올리는게 맞을까 생각이 들었지만,

내가 개발한 내용을 회고하는 느낌으로 작성해보려 한다.

 

2일차에 내가 맡은 역할

이 프로젝트는 작은 관점에서 보면 데이터를 저장하고 출력하는 작은 프로젝트 같지만,

큰 관점에서 보면 학생의 데이터를 저장하는 데이터베이스 프로그램을 설계하고 개발하는 프로젝트다.

 

프로그램을 실행/디버깅 하면서 느꼈던 점이,

'데이터베이스가 껏다 킬 때마다 데이터가 삭제 된다면, 데이터베이스를 쓰는 이유가 있을까?'였다.

 

그래서 나는 학생 정보가 들어올 경우에 Json형태로 데이터를 저장하면 어떨까 싶어 개발을 시작했다.

 

기능 구현

우선, 이 프로젝트에서 저장해야할 데이터는 Student, Score에 대한 정보였다.

두 타입이 서로 다르지만 1개의 Class를 통해 저장됐으면 싶어 DataManager 클래스를 Generic Class로 선언했다.

 

다음은 Generic형태로 들어온 데이터를 어떻게 구분하고 Json형태로 구현할 수 있을까에 대해 고민했다.

그렇게 조사해본 결과 Gson이라는 라이브러리를 알게 됐다. 

 

Gson은 reflection을 사용해 Class의 구조를 직렬/역직렬화가 가능하다는 장점이 있어

Generic Type에도 유동적으로 사용할 수 있었고, json 저장기능 개발 시간을 유의미할 정도로 단축시킬 수 있었다.

 

문제점

파일 생성, 읽기 관련 문제

그 다음은 File을 불러오고 세이브하는 기능을 구현해야 했는데,

이 과정에서 조금 오래 걸렸다.

 

Save할 파일이 존재하지 않는 상황에서 File.Write함수를 사용할 경우 자동으로 파일이 생성되고 저장되는 줄 알았지만,

파일이 생성되어있어야 FileWriter 객체를 생성할 수 있었기에 파일이 실존하는지 확인하는 과정을 거쳐야 했다.

 

최종적으로 플로우는 다음과 같았다.

  • 디렉토리가 있는지 확인한다 
  • 디렉토리가 없으면 생성한다.
  • .json파일이 있는지 확인한다.
  • .json파일이 없으면 생성한다.
  • Class를 Gson을 통해 .json형태의 문자열로 변환한다.
  • 불러온 .json에 저장한다.

 

Json 불러오기 관련 문제

Json파일을 저장할 경우에는 Gson.toJson 함수에 컨테이너를 넣어주면 해당 컨테이너 + 타입에 맞는

Json형태의 문자열이 생성되었다.

 

하지만, 불러오는 과정은 저장과는 달랐다.

파일을 JsonParser를 통해 JsonElement타입으로 불러오면 해당 JsonElement를 gson.fromJson을 통해

컨테이너 + 타입으로 변환하면 끝 같지만,

 

Generic Type을 사용할 경우 TypeToken을 통해 해당 Generic Type에 대한 정보를 불러와

Type을 지정해줘야만 해당 정상적으로 불러올 수 있었다.

 

 

최종 코드

더보기
public class DataManager<T> {
    Gson gson;
    final String DIRECTORY = "Database";
    final String FILE_PATH = "\\";
    final String FILE_EXTENSION = ".json";

    public DataManager() {
        gson = new Gson();
    }

    public void directoryInitialize() {
        File folder = new File(DIRECTORY);

        if(!folder.exists()) {
            folder.mkdir();
        }
    }

    // File을 생성 함수( File이 존재하지 않을 경우 생성 )
    public File openFile(String fileName) throws Exception {
        File file = new File(DIRECTORY + FILE_PATH + fileName + FILE_EXTENSION);

        if(!file.exists()) {
            file.createNewFile();
        }

        return file;
    }
    // .json 파일을 읽어와서 FileReader로 생성하는 함수 ( 없을시 파일 생성 )
    public Reader loadFileReader(String fileName) throws Exception {
        File file = openFile(fileName);
        return new FileReader(file);
    }

    // .json 파일을 읽어와서 FileReader로 생성하는 함수 ( 없을시 파일 생성 )
    public Writer writeFileReader(String fileName) throws Exception {
        File file = openFile(fileName);
        return new FileWriter(file);
    }

    public void saveDatas(String fileName, List<T> lists) throws Exception {
        String jsonData = gson.toJson(lists);
        Writer reader = writeFileReader(fileName);

        reader.write(jsonData);
        reader.close();

        System.out.println(jsonData);
    }

    public List<T> loadDatas(String fileName, Class<T> myType) throws Exception  {
        Reader reader = loadFileReader(fileName);
        JsonElement jsonObject = JsonParser.parseReader(reader);

        System.out.println(jsonObject.toString());

        Type listType = TypeToken.getParameterized(List.class, myType).getType();

        reader.close();
        return gson.fromJson(jsonObject, listType);
    }
}

 

결과물

[ 저장된 학생 정보 ]