개인/정리

220713 file -> db -> json

jumphare 2022. 7. 13. 13:32

 

자잘한 유효성 검사나 예외처리 같은 건 제외하고 주요 구현 기능

 

1. file 입력 -> DB 저장

조건

파일의 한 줄=DB의 1row. 구분자를 기준으로 나눠 집어넣을 것.

에러 발생 시 다음 줄로 넘어가 계속 처리하고, 에러 발생한 줄은 따로 실패 결과에 출력할 것.

1. 여러 줄로 되어있는 파일을 줄 단위로 분리할 필요가 있음 -> BufferedReader 사용
List<String> list1=new ArrayList<>();   //여기 저장

try (BufferedReader br = new BufferedReader(new InputStreamReader(mf.getInputStream()));) {
  // try with resources 이용 --> 장점 : finally 에서 close 안 해줘도 알아서 닫아줌
   while ((line = br.readLine()) != null)     //파일 전부 읽어서 줄 단위로 리스트에 저장
      list1.add(line);

} catch (IOException e) {
   e.printStackTrace();
}
2. 분리된 줄마다 구분자로 나눠 dto에 저장
List<DTO> list2=new ArrayList<>();   //여기 저장
String[] str;   // split() 함수를 이용하면 저장되는 데이터형이 스트링 배열임


for (int i = 0; i < li1.size(); i++) {
   str = list1.get(i).split("/", -1);    //도중에 공백이 있어도 끝까지 읽으라고 -1 달아줌 (줄 끝까지 가면 -1 리턴됨 원래)
   DTO dto = set.setdto(str);   // 구분자로 분리돼 저장된 값을 dto에 셋팅
   list2.add(dto);    //셋팅된 dto는 list에 추가
}

※ 여기서 만약 구분자가 더 존재하거나 덜 존재한다면 dto에 셋팅하는 과정에서 오류가 발생할 수 있다!
1. dto의 기본생성자로 모든 필드의 default 값이 null이 되도록 설정한다 (객체 생성 시 자동으로 null 값이 셋팅되게 됨)
2. 구분자 분리된 배열의 길이(length)가 dto의 필드 개수(DTO.class.getDeclaredFields().length)와 같지 않다면 셋팅을 진행하지 않도록 함
    ---> 해당 줄은 null이 들어간 dto가 리턴되어 list에 추가됨 --> DB 저장 시 에러 처리되고 해당 줄 따로 뽑아낼 수 있음!
3. 마찬가지로 String -> Char, Timestamp로 형변환해야할 때 변환 조건에 맞지 않으면 셋팅되지 않게 처리 -> 에러 처리 가능!

3. dto 값을 DB에 저장
HashMap<Integer, String> map = new HashMap<>();     //저장 실패한 줄의 번호와 해당 텍스트를 출력하기 위해 맵 선언

int ss = 0;   //성공 시 카운트
int ff = 0;   //실패 시 카운트
for (DTO dto : list2) {  //dto 단위로 반복문 돌리기
   try {
      insert(dto);   // db 넣기
      ss += 1; // 성공하면 ss 카운트가 올라감
   } catch (Exception e) {
      ff += 1; // 예외 발생 시 ff 카운트 올라감
      map.put(ss + ff, list1.get(ss + ff - 1));   //실패한 줄 번호(ss+ff)와 해당 텍스트(String으로 저장된 list1에서 가져옴) map에 저장
      continue;   // 다음 줄로 넘어가 입력처리 반복
   }
}
4. 성공 ss 건, 실패 ff 건
그리고 실패 목록을 출력할 때는 map의 key와 value를 둘 다 내보내면 끝!



2. DB -> 표로 출력

조건

ajax에서 json형식으로 가져올 것

Timestamp의 출력 형식은 yyyy년 MM월 dd일 HH:mm:ss

1. jsp 페이지에서 ajax를 이용해 컨트롤러로 json 데이터 요청
   $.ajax({
      url: "컨트롤러 요청 주소",
      type: "get",
      cache: "false",
      datatype: "json",
      success: function(data) {
         성공 시 로직
      }
   });
2. DB 데이터를 json 형식으로 파싱
List<DTO> dto=dao.select();  //db에서 데이터 가져와 리스트에 저장

SimpleDateFormat df = new SimpleDateFormat("yyyy년 MM월 dd일 HH:mm:ss");   //Timestamp형 데이터 출력형식 지정
ObjectMapper mapper = new ObjectMapper();   //Jackson에서 제공하는 ObjectMapper 클래스 이용할 것
mapper.setDateFormat(df);   //날짜 포맷 셋팅

String obj=mapper.writeValueAsString(dto);   //dto 리스트를 json 형태의 String으로 저장

※ @ResponseBody를 붙이고 return obj; 을 하면 obj 값을 ajax로 넘겨줄 수 있음! (다른 자료형도 가능)

3. json 데이터 출력
success: function(data) {
   var keys = Object.keys(data[0]);    //json key값 추출
   $("#selectlist").html("");    // 출력할 곳 초기화
   var tb="<table class='tb'><tr>";

   for(var i=0; i<keys.length; i++)   // 키 값을 컬럼명으로 지정
      tb+="<th>"+keys[i]+"</th>";

   tb+="</tr></table>";

   $("#selectlist").append(tb);    //추가해줌

   $.each(data, function(index, item){    //json 배열의 개수(index)만큼 반복문을 돌려 출력 ($.each)

      tb="<tr><td>"+item.aa+"</td>";
      tb+="<td>"+item.bb+"</td>";
      tb+="<td>"+item.cc+"</td>";
      tb+="<td>"+item.dd+"</td>";
      tb+="<td>"+item.reg_date+"</td></tr>";

      $('table').append(tb);   //추가해줌
   });
}