GridFS в Spring Data MongoDB
1. обзор
В этом руководстве будет изучен один изcore features of Spring Data MongoDB: interacting with*GridFS*.
Спецификация хранилища GridFS в основном используется для работы с файлами, размер которых превышает ограничение на размерBSON-документа, равное 16 МБ. А Spring Data предоставляет интерфейсGridFsOperations и его реализацию– GridFsTemplate - для простого взаимодействия с этой файловой системой.
2. конфигурация
2.1. Конфигурация XML
Начнем с простой конфигурации XML дляGridFsTemplate:
Аргументы конструктора дляGridFsTemplate включают ссылки bean-компонентов наmongoDbFactory, который создает базу данных Mongo, иmongoConverter, который преобразует типы Java и MongoDB. Их определения бинов приведены ниже.
2.2. Конфигурация Java
Давайте создадим аналогичную конфигурацию, только на Java:
@Bean
public GridFsTemplate gridFsTemplate() throws Exception {
return new GridFsTemplate(mongoDbFactory(), mappingMongoConverter());
}
Для этой конфигурации мы использовалиmongoDbFactory иmappingMongoConverter изorg.springframework.data.mongodb.config.AbstractMongoConfiguration.
3. GridFsTemplate Основные методы
3.1. storeс
Методstore сохраняет файл в MongoDB.
Предположим, у нас есть пустая база данных и мы хотим сохранить в ней файл:
InputStream inputStream = new FileInputStream("src/main/resources/test.png");
gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).toString();
Обратите внимание, что мы можем сохранить дополнительные метаданные вместе с файлом, передавDBObject методуstore. В нашем примереDBObject может выглядеть примерно так:
DBObject metaData = new BasicDBObject();
metaData.put("user", "alex");
GridFS использует две коллекции для хранения метаданных файла и его содержимого. Метаданные файла хранятся в коллекцииfiles, а содержимое файла хранится в коллекцииchunks. Обе коллекции имеют префиксfs.
Если мы выполним команду MongoDBdb[‘fs.files'].find(), мы увидим коллекциюfs.files:
{
"_id" : ObjectId("5602de6e5d8bba0d6f2e45e4"),
"metadata" : {
"user" : "alex"
},
"filename" : "test.png",
"aliases" : null,
"chunkSize" : NumberLong(261120),
"uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
"length" : NumberLong(855),
"contentType" : "image/png",
"md5" : "27c915db9aa031f1b27bb05021b695c6"
}
Командаdb[‘fs.chunks'].find() извлекает содержимое файла:
{
"_id" : ObjectId("5602de6e5d8bba0d6f2e45e4"),
"files_id" : ObjectId("5602de6e5d8bba0d6f2e45e4"),
"n" : 0,
"data" :
{
"$binary" : "/9j/4AAQSkZJRgABAQAAAQABAAD/4QAqRXhpZgAASUkqAAgAAAABADEBAgAHAAAAGgAAAAAAAABHb29nbGUAAP/bAIQAAwICAwICAwMDAwQDAwQFCAUFBAQFCgcHBggM
CgwMCwoLCw0OEhANDhEOCwsQFhARExQVFRUMDxcYFhQYEhQVFAEDBAQGBQUJBgYKDw4MDhQUFA8RDQwMEA0QDA8VDA0NDw0MDw4MDA0ODxAMDQ0MDAwODA8MDQ4NDA0NDAwNDAwQ/8AA
EQgAHAAcAwERAAIRAQMRAf/EABgAAQEBAQEAAAAAAAAAAAAAAAgGBwUE/8QALBAAAgEDAgQFAwUAAAAAAAAAAQIDBAURBiEABwgSIjFBYXEyUYETFEKhw
f/EABoBAAIDAQEAAAAAAAAAAAAAAAMEAQIFBgD/xAAiEQACAgEDBAMAAAAAAAAAAAAAAQIRAyIx8BJRYYETIUH/2gAMAwEAAhEDEQA/AHDyq1Bb6GjFPMAszLkZHHCTi1I6O
cXOFRZ1ZqoX6aqzRClkhb9MGVh2SsNyVI/hjG5389tuGcUaLK1GmFfpn5r3rnXpfV82pGtS3a0XmaGOO3zguKV1SWDwBQDH2uUWTOWMZzuM8bS0VQtJKRb2li9LL3l+4VNQPEfQTOB/WO
G1K0JtUzwad1eZaYBiqzL4S2N8cZUsa7DqlRGdWvMq5aX6b9Tvb5pIZbggt7VcU3YacSkDbfuLNuu3lkk+98GNfIrLt2gK9K/NWl5Z87Ldebj3R0NTa2tVVKhOI0KoQ5AG4DRqSPk+gHGn
khUPYNOx92vW9PcrdDW0FUJqOp7po5ETIYMxOdyOAK0qAvcgKPWa0oMTo7SEYDKPp98/5wPoJsx3rZ1wLhojS9iinLD9w9W47iSwVe0Z3wfrPoce2eC4I6rCX9MxrpUpWqudNunUosNLR1EkiyIGDqUKF
fyZB+AeG80riueQdVfObC/tN1pLdaLfSxMiRQ08aIg2CjtGAB9uEyCSqSWujICUXwghT57A5+ePEoMvUdc5a3XlSsgUhZGjGM/TGAqjz+SfuT7DDmGC6WzzeyOv0+2amOrr3KylzTUwjjDeWGbJJ9/COI
yvRFFv1iRsVGDaqYGWVsIoBZydsDhQGf/Z",
"$type" : "00"
}
}
3.2. findOneс
findOne возвращает ровно один документ, удовлетворяющий указанным критериям запроса.
String id = "5602de6e5d8bba0d6f2e45e4";
GridFSFile gridFsFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id)));
Код выше вернет запись результата, которая была добавлена в примере выше. Если база данных содержит более одной записи, которая соответствует запросу, она вернет только один документ. Конкретная возвращаемая запись будет выбрана в соответствии с естественным порядком (порядок, в котором документы были сохранены в базе данных).
3.3. findс
find выбирает документы из коллекции и возвращает курсор к выбранным документам.
Предположим, у нас есть следующая база данных, содержащая 2 записи:
[
{
"_id" : ObjectId("5602de6e5d8bba0d6f2e45e4"),
"metadata" : {
"user" : "alex"
},
"filename" : "test.png",
"aliases" : null,
"chunkSize" : NumberLong(261120),
"uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
"length" : NumberLong(855),
"contentType" : "image/png",
"md5" : "27c915db9aa031f1b27bb05021b695c6"
},
{
"_id" : ObjectId("5702deyu6d8bba0d6f2e45e4"),
"metadata" : {
"user" : "david"
},
"filename" : "test.png",
"aliases" : null,
"chunkSize" : NumberLong(261120),
"uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
"length" : NumberLong(855),
"contentType" : "image/png",
"md5" : "27c915db9aa031f1b27bb05021b695c6"
}
]
Если мы используемGridFsTemplate для выполнения следующего запроса:
List fileList = new ArrayList();
gridFsTemplate.find(new Query()).into(fileList);
Полученный список должен содержать две записи, поскольку мы не указали никаких критериев.
Мы, конечно, можем предоставить некоторые критерии для методаfind. Например, если мы хотим получить файлы, метаданные которых содержат пользователей с именемalex,, код будет следующим:
List gridFSFiles = new ArrayList();
gridFsTemplate.find(new Query(Criteria.where("metadata.user").is("alex"))).into(gridFSFiles);
Полученный список будет содержать только одну запись.
3.4. deleteс
delete удаляет документы из коллекции.
Используя базу данных из предыдущего примера, предположим, что у нас есть код:
String id = "5702deyu6d8bba0d6f2e45e4";
gridFsTemplate.delete(new Query(Criteria.where("_id").is(id)));
После выполненияdelete в базе данных остается только одна запись:
{
"_id" : ObjectId("5702deyu6d8bba0d6f2e45e4"),
"metadata" : {
"user" : "alex"
},
"filename" : "test.png",
"aliases" : null,
"chunkSize" : NumberLong(261120),
"uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
"length" : NumberLong(855),
"contentType" : "image/png",
"md5" : "27c915db9aa031f1b27bb05021b695c6"
}
с кусками:
{
"_id" : ObjectId("5702deyu6d8bba0d6f2e45e4"),
"files_id" : ObjectId("5702deyu6d8bba0d6f2e45e4"),
"n" : 0,
"data" :
{
"$binary" : "/9j/4AAQSkZJRgABAQAAAQABAAD/4QAqRXhpZgAASUkqAAgAAAABADEBAgAHAAAAGgAAAAAAAABHb29nbGUAAP/bAIQAAwICAwICAwMDAwQDAwQFCAUFBAQFCgcHBggM
CgwMCwoLCw0OEhANDhEOCwsQFhARExQVFRUMDxcYFhQYEhQVFAEDBAQGBQUJBgYKDw4MDhQUFA8RDQwMEA0QDA8VDA0NDw0MDw4MDA0ODxAMDQ0MDAwODA8MDQ4NDA0NDAwNDAwQ/8AA
EQgAHAAcAwERAAIRAQMRAf/EABgAAQEBAQEAAAAAAAAAAAAAAAgGBwUE/8QALBAAAgEDAgQFAwUAAAAAAAAAAQIDBAURBiEABwgSIjFBYXEyUYETFEKhw
f/EABoBAAIDAQEAAAAAAAAAAAAAAAMEAQIFBgD/xAAiEQACAgEDBAMAAAAAAAAAAAAAAQIRAyIx8BJRYYETIUH/2gAMAwEAAhEDEQA/AHDyq1Bb6GjFPMAszLkZHHCTi1I6O
cXOFRZ1ZqoX6aqzRClkhb9MGVh2SsNyVI/hjG5389tuGcUaLK1GmFfpn5r3rnXpfV82pGtS3a0XmaGOO3zguKV1SWDwBQDH2uUWTOWMZzuM8bS0VQtJKRb2li9LL3l+4VNQPEfQTOB/WO
G1K0JtUzwad1eZaYBiqzL4S2N8cZUsa7DqlRGdWvMq5aX6b9Tvb5pIZbggt7VcU3YacSkDbfuLNuu3lkk+98GNfIrLt2gK9K/NWl5Z87Ldebj3R0NTa2tVVKhOI0KoQ5AG4DRqSPk+gHGn
khUPYNOx92vW9PcrdDW0FUJqOp7po5ETIYMxOdyOAK0qAvcgKPWa0oMTo7SEYDKPp98/5wPoJsx3rZ1wLhojS9iinLD9w9W47iSwVe0Z3wfrPoce2eC4I6rCX9MxrpUpWqudNunUosNLR1EkiyIGDqUKF
fyZB+AeG80riueQdVfObC/tN1pLdaLfSxMiRQ08aIg2CjtGAB9uEyCSqSWujICUXwghT57A5+ePEoMvUdc5a3XlSsgUhZGjGM/TGAqjz+SfuT7DDmGC6WzzeyOv0+2amOrr3KylzTUwjjDeWGbJJ9/COI
yvRFFv1iRsVGDaqYGWVsIoBZydsDhQGf/Z",
"$type" : "00"
}
}
3.5. getResourcesс
getResources возвращает всеGridFsResource с заданным шаблоном имени файла.
Предположим, у нас есть следующие записи в базе данных:
[
{
"_id" : ObjectId("5602de6e5d8bba0d6f2e45e4"),
"metadata" : {
"user" : "alex"
},
"filename" : "test.png",
"aliases" : null,
"chunkSize" : NumberLong(261120),
"uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
"length" : NumberLong(855),
"contentType" : "image/png",
"md5" : "27c915db9aa031f1b27bb05021b695c6"
},
{
"_id" : ObjectId("5505de6e5d8bba0d6f8e4574"),
"metadata" : {
"user" : "david"
},
"filename" : "test.png",
"aliases" : null,
"chunkSize" : NumberLong(261120),
"uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
"length" : NumberLong(855),
"contentType" : "image/png",
"md5" : "27c915db9aa031f1b27bb05021b695c6"
},
{
"_id" : ObjectId("5777de6e5d8bba0d6f8e4574"),
"metadata" : {
"user" : "eugen"
},
"filename" : "example.png",
"aliases" : null,
"chunkSize" : NumberLong(261120),
"uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
"length" : NumberLong(855),
"contentType" : "image/png",
"md5" : "27c915db9aa031f1b27bb05021b695c6"
}
]
Теперь давайте выполнимgetResources, используя шаблон файла:
GridFsResource[] gridFsResource = gridFsTemplate.getResources("test*");
Это вернет две записи, имена файлов которых начинаются с «test» (в данном случае они обе имеют имяtest.png).
4. GridFSFile Основные методы
APIGridFSFile тоже довольно прост:
-
getFilename - получает имя файла
-
getMetaData - получает метаданные для данного файла
-
containsField - определяет, содержит ли документ поле с заданным именем
-
get - получает поле от объекта по имени
-
getId - получает идентификатор объекта файла
-
keySet - получает имена полей объекта
5. Заключение
В этой статье мы рассмотрели возможности MongoDBGridFS и способы взаимодействия с ними с помощью Spring Data MongoDB.
Реализация всех этих примеров и фрагментов кодаcan be found inmy github project - это проект на основе Eclipse, поэтому его должно быть легко импортировать и запускать как есть.