Java에서 몽고DB에 파일을 등록하는 방법 입니다.
몽고DB에서는 다른 데이터베이스와 마찬가지로 파일을 업로드 할 수 있게 해 주고 있습니다.
파일형태는 바이너리로 변환하여 컬렉션에 저장이 되며, 다른 정보도 포함하여 저장 할 수 있습니다.
대용량 파일 저장은 아쉽게도 지원하지 않으며 16메가바이트 이하의 파일을 업로드 할 것을 권장하고 있습니다.
파일 업로드 하는 방법입니다.
GridFSBucket클래스와 GridFSUploadOptions클래스를 사용 하였습니다.
private void insertFile() throws Exception{
Document doc = new Document("type","image");
doc.append("content_type", "image/png");
doc.append("my_id", "abcd_1234_5678");
doc.append("desc", "한글 입력입니다.");
doc.append("date", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) );
InputStream inStream = new FileInputStream(new File("E:/test.png"));
GridFSBucket gridBucket = GridFSBuckets.create(template.getDb()); //mongoClient.getDatabase("이름")
GridFSUploadOptions uploadOptions = new GridFSUploadOptions().chunkSizeBytes(1024).metadata(doc);
ObjectId fileId = null;
fileId = gridBucket.uploadFromStream("re_name.png", inStream, uploadOptions); //바꿀파일명을 넣어주세요.
System.out.println("fileId : " + fileId);
inStream.close();
}
코드 내용은 매우 직관적이라 어렵지 않습니다.
template 객체는 MongoTemplate 클래스 입니다.
만약 몽고클라이언트를 사용한다면 주석친 부분의 내용으로 변경하여 create 메소드에 파라미터로 넣어주면 됩니다.
파일에서 InputStream을 겨저 온 뒤에 uploadFromStream 이라는 메소드를 통해서 등록하여 주었습니다.
Document 클래스는 metadata 라는 속성에 저장이 되며 key, value 형식의 데이터를 넣어주게됩니다.
이렇게 데이터를 등록하면 컬렉션이 2개가 생성(없다면) 됩니다.
fs.chunks라는 컬렉션과 fs.files라는 컬렉션 입니다.
fs.chunks에는 파일에 관한 바이너리 데이터를 모아두는 곳 이며, fs.files 컬렉션은 사용자가 직접 조회할 수 있는 정보를 담은 컬렉션 입니다.
실제 컬렉션에서도 어렵지 않게 내용을 확인 할 수 있습니다.
사실 fs.chunks 컬렉션을 직접적으로 관리할 일은 없습니다. 대부분 fs.files 컬렉션을 관리 합니다.
그러면 이제 조회하는 기능을 한번 확인하여 보겠습니다.
private void getFile() throws Exception{
GridFSBucket gridBucket = GridFSBuckets.create(template.getDb());
Document query = new Document();
query.append("metadata.my_id", new Document("$eq", "abcd_1234_5678"));
query.append("metadata.date", new Document("$gte", "2020-07-01 00:00:00"));
query.append("metadata.date", new Document("$lte", "2020-07-05 23:59:59"));
GridFSFindIterable itor = gridBucket.find(query);
int i = 0;
for (GridFSFile file : itor) {
System.out.println(file.getFilename() + " : " + file.getMetadata());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
gridBucket.downloadToStream(file.getId(), baos);
OutputStream outputStream = new FileOutputStream("E:/DDOWN/down"+i+".png"); //받을 디렉토리+파일명
baos.writeTo(outputStream);
try {
baos.close();
} catch (Exception e) {
}
try {
outputStream.close();
} catch (Exception e) {
}
i++;
}
}
마찬가지로 어렵지 않는 코드 입니다.
재미있는 점은 질의를 위한 부분입니다. 통상적으로 사용했던 Query 클래스를 사용하지 않고 Document 클래스를 사용하였습니다.
입력한 데이터인 metadata에 접근하여 조회를 하는 모습입니다.
조회를 하고 난 뒤에는 각종 등록 정보를 가져왔으며, downloadToStream 메소드를 통해서 파일을 Byte스트림에 담아두었습니다.
GridFSBucket 클래스에서 fs.find를 통해서 나온 데이터는 n개이므로 반복문을 활용하여 정보를 가져오도록 합니다.
다음으로 파일을 삭제하는 부분 입니다.
private void deleteFile() throws Exception{
GridFSBucket gridBucket = GridFSBuckets.create(template.getDb());
Bson filter = Filters.regex("metadata.web_id", "abcd_1234_5678");
GridFSFindIterable itor = gridBucket.find(filter);
for (GridFSFile file : itor) {
System.out.println(file.getFilename());
System.out.println(file.getMetadata());
gridBucket.delete(file.getId());
}
}
delete라는 메소드를 호출하였습니다.
위 예제처럼 Bson이라는 클래스를 활용하면 아주 간단한 질의를 할 수 있습니다.
삭제를 하게되면 fs.chunks와 fs.files 컬렉션 둘 다 내용이 제거됩니다.
fs.files 컬렉션은 다른 컬렉션과 마찬가지로 인덱스를 지원합니다.
물론 fs.chunks 컬렉션도 지원합니다만 일반적으로 조회를 하지는 않습니다.
그 외에도 rename이라는 메소드를 통해 파일 이름을 이름을 바꿀 수 있으며 fs.files 컬렉션 drop으로 전부 제거를 할 수 있습니다.
아쉽게도 update에 대한 내용은 GridFSBucket 컬렉션에서 확인하지를 못하였습니다. (제가 못 찾았겠지요..ㅠ)
metadata(메타정보)를 바꾸려면 몽고DB에서 일반 업데이트를 사용하듯이 해 주어야 합니다.
아래는 일반 Update 기능을 통해서 컬렉션의 meta정보를 바꾸어준 모습 입니다.
이제 사용한 소스코드 전체를 살펴보겠습니다.
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.MongoTemplate;
import com.mongodb.ConnectionString;
import com.mongodb.client.MongoClients;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.GridFSFindIterable;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.mongodb.client.gridfs.model.GridFSUploadOptions;
import com.mongodb.client.model.Filters;
import com.mongodb.client.MongoClient;
import com.mongodb.MongoClientSettings;
public class TestMainClass {
public MongoClient mongoClient = null;
public MongoTemplate template = null;
public static void main(String args[]){
}
//등록
private void insertFile() throws Exception{
Document doc = new Document("type","image");
doc.append("content_type", "image/png");
doc.append("my_id", "abcd_1234_5678");
doc.append("desc", "한글 입력입니다.");
doc.append("date", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) );
InputStream inStream = new FileInputStream(new File("가저올경로/파일이름.png"));
GridFSBucket gridBucket = GridFSBuckets.create(template.getDb()); //mongoClient.getDatabase("이름")
GridFSUploadOptions uploadOptions = new GridFSUploadOptions().chunkSizeBytes(1024).metadata(doc);
ObjectId fileId = null;
fileId = gridBucket.uploadFromStream("바꿀이름.png", inStream, uploadOptions);
System.out.println("fileId : " + fileId);
inStream.close();
}
//가져오기
private void getFile() throws Exception{
GridFSBucket gridBucket = GridFSBuckets.create(template.getDb());
Document query = new Document();
query.append("metadata.my_id", new Document("$eq", "abcd_1234_5678"));
query.append("metadata.date", new Document("$gte", "2020-07-01 00:00:00"));
query.append("metadata.date", new Document("$lte", "2020-07-05 23:59:59"));
GridFSFindIterable itor = gridBucket.find(query);
for (GridFSFile file : itor) {
System.out.println(file.getFilename() + " : " + file.getMetadata());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
gridBucket.downloadToStream(file.getId(), baos);
OutputStream outputStream = new FileOutputStream("다운로드 경로/다운받을 파일명");
baos.writeTo(outputStream);
try {
baos.close();
} catch (Exception e) {
}
try {
outputStream.close();
} catch (Exception e) {
}
}
}
//삭제
private void deleteFile() throws Exception{
GridFSBucket gridBucket = GridFSBuckets.create(template.getDb());
Bson filter = Filters.regex("metadata.web_id", "abcd_1234_5678");
GridFSFindIterable itor = gridBucket.find(filter);
for (GridFSFile file : itor) {
System.out.println(file.getFilename());
System.out.println(file.getMetadata());
gridBucket.delete(file.getId());
}
}
//접속
public void init() {
try {
final String combineUrl = "mongodb://주소/testerdb";
ConnectionString connString = new ConnectionString(combineUrl);
MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(connString)
.retryWrites(true)
.build();
mongoClient = MongoClients.create(settings);
template = new MongoTemplate(mongoClient, "testerdb");
} catch (Exception e) {
e.printStackTrace();
}
}
//종료
public void close(){
try {
template = null;
mongoClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
위 내용에 사용된 몽고db 버전입니다.
* maven 기준입니다.
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.11.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.1.17.RELEASE</version>
</dependency>
이상으로 몽고db에서 파일을 저장 및 가져오기, 삭제하기 방법에 대해서 살펴 보았습니다.
궁굼하거나 틀린부분은 언제든 연락주세요!
'몽고DB > Java 몽고DB' 카테고리의 다른 글
몽고DB Aggregate 를 병렬 동작 처럼(Mongodb aggregate facet) (0) | 2020.11.03 |
---|---|
몽고 db에서의 특수문자 검색(Mongodb 특수문자)시 유의사항 (0) | 2020.07.29 |
MongoTemplate or연산자를 통한 질의문 만들기(MongoTemplate or query) (0) | 2020.06.18 |
Mongotemplate에서 MongoDB 증감 연산자 사용과 기타 다른 update 연산자 (0) | 2020.05.14 |
Mongotemplate에서 배열값 관리 (Mongotemplate push, pull) (0) | 2020.05.13 |
댓글