본문 바로가기

Server Oriented/DB-Oracle

LongRaw 와 Blob 은 getBinaryStream() 로 추출해서 루프를 통해 byte[] 단위로 스트림 아웃 하세욤..


어떤 프레임 웍을 사용하든 기본은 DB 작업과 파일 작업.
만약 ResultSet 에 담긴 정보를 사용할때 프레임 웍에 따라 다른 클래스나 메소드에서 작업하면서,
DB 작업에서 사용한 (Prepared)Statement 나 Connection 을 ResultSet 작업 전에 닫아 버리지 않도록 주의.
LongRaw 로 된 사진 이미지도 Blob 과 동일하게 getBinaryStream() 메소드로 추출.
SQLInjection 을 예방하려면 Statement 는 포기하고 PreparedStatement 를 사용.

아래 코드는 스프링 프레임 웍에서 필요한 부분만 따왔어요.
첫번째 메소드는 DB 쪽과 바로 닿아 있는 DAO 이고,
두번째 메소드는 DAO 에서 데이타를 읽어서 비즈니스 로직을 구현하는 부분.


 /**
  * DB LongRaw 사진 정보 추출 <br />
  * ResultSet 에 담아서 ServiceImpl 에 던지려면 Connection 과 PreparedStatement 도
  * ServiceImpl 에서 close 해야 하므로 여기서 데이타 처리
  * @param Vo to 작업 조건
  * @return InputStream 작업 결과
  * @throws DataAccessException 예외처리
  */
 public InputStream getPhotoInfo(Vo vo) throws DataAccessException {

  Connection            con    = null;
  PreparedStatement  ps      = null;
  InputStream            result  = null; // BuffredInputStream 을 하나더 사용할 수도 있겠죠.
  
  try{
   
   StringBuffer query  = new StringBuffer();
   query.append("select photo ... \n"); // 사진 정보 없으면 생성 없음.. 이미지는 한 건씩 작업..
      
   con = getDataSource().getConnection();
   ps   = con.prepareStatement(query.toString());
   ps.setString(1, vo.getUnique_seq());
   ResultSet  rs   = ps.executeQuery();
         
   if(rs==null || !rs.isBeforeFirst() || !rs.next()) return null; // 결과집합(ResultSet) 에 담김 내용이 없으면 무효.
   result = rs.getBinaryStream(1);     // getBytes 는 사용을 자제해 주세용.. ~.~
        
  }catch(Exception e){
   StringBuffer sb = new StringBuffer();
   sb.append("---.com.dao.Dao4Oracle.getPhotoInfo\n");
   sb.append("---.Exception:"+e.toString()+"..\n");
   sb.append("---.vo       :"+vo+"..\n");
   System.out.println(sb.toString());
  }finally{ // InputStream 에 담았기 때문에 여기서 InputStream 을 닫으면 데이타가 전달되지 않음
   if(rs!=null) try{ rs.close(); }catch(Exception e){ }finally{ rs = null; }
   if(ps!=null) try{ ps.close(); }catch(Exception e){ }finally{ ps = null; }
   if(con!=null) try{ con.close(); }catch(Exception e){ }finally{ con = null; }
  }
  
  return result;
 }





 /**
  * DB LongRaw 사진 정보 추출
  * @param Vo to 작업 조건
  * @return boolean 작업 성공 여부
  * @throws void
  */
 public boolean getPhotoInfo(Vo vo){
  
  InputStream               is      = null;
  FileOutputStream        fos     = null;
  BufferedOutputStream bos    = null;
  boolean                    result  = false;

  try{

   String    _rurl  = ""+request.getRequestURL();
   String    fp   = "/usr/local/ws/web/images/photo/"; // 서버 경로
   if(_rurl.indexOf("127.0.0.1")>-1 ||               // 로컬
    _rurl.indexOf("localhost")>-1 ||              // 로컬
    _rurl.indexOf("10.4.x.x")>-1)                // 로컬
    fp       = "D:\\dev\\m\\web\\images\\photo\\"; // 로컬 PC 경로

   String fs = fp+ vo.getUnique_seq()+ ".jpg"; // 사진은 아직 JPG 가 대세
   File    fo = new File(fs);
   if(fo.exists()) return true;            // #1/. 사진 파일 존재여부 체크
   
   Service if = (Service)ServiceHelper.getBeans("if");
   is        = if.getPhotoInfo(vo);
   if(is==null)     return false;

   fos  = new FileOutputStream(fo);
   bos = new BufferedOutputStream(fos);
   
   while(true){
    byte[]   buff  = new byte[1024];
    int    rCount  = is.read(buff);
    bos.write(buff, 0, buff.length); // 버퍼를 정해놓고 InputStream 에서 읽었는데, BuffredOutputStream 에 바로 전달 가능
    if(rCount==-1) break;
   }

   bos.flush();              // 버퍼 처리, 이거 잊어 버리는 사람 은근히 많음.
   result = true;              // 결과 처리

  }catch(Exception e){
   StringBuffer sb = new StringBuffer();
   sb.append("---.com.action.Action.getPhotoInfo\n");
   sb.append("---.Exception:"+e.toString()+"..\n");
   sb.append("---.vo       :"+vo+"..\n");
   System.out.println(sb.toString());
  }finally{
   if(is!=null) try{ is.close(); }catch(Exception ig){ }finally{ is=null; } // InputStream 을 사용한 다음에는 닫아 주세요
   if(bos!=null) try{ bos.close(); }catch(Exception ig){ }finally{ bos=null; }
   if(fos!=null) try{ fos.close(); }catch(Exception ig){ }finally{ fos=null; }
  }
  
  return result;
 }