GridFS---新版本java操作

最近使用了最新本版’spring-boot-starter-data-mongodb’, version: ‘2.2.6.RELEASE’和’mongo-java-driver’, version: '3.12.3’在使用上有了些许改动。
最重要的就是DB类的弃用:
GridFS---新版本java操作
文章图片

MongoTemplate: public MongoDatabase getDb() { return doGetDatabase(); } MongoDbFactory: MongoDatabase getDb() throws DataAccessException; MongoClient: public MongoDatabase getDatabase(final String databaseName) { ...... }

【GridFS---新版本java操作】MongoTemplate与MongoDbFactory中的getDb方法返回值都由之前的DB类型改为了MongoDatabase ,但是列入GridFs的构造方法传入参数还是DB并没有改为MongoDatabase 类型,这就直接导致我们之前很多使用到DB的地方现在不能直接使用了。
public GridFS(final DB db) { this(db, DEFAULT_BUCKET); }/** * Creates a GridFS instance for the specified bucket in the given database.Set the preferred WriteConcern on the give DB with * DB.setWriteConcern * * @param dbdatabase to work with * @param bucket bucket to use in the given database * @throws com.mongodb.MongoException if there's a failure * @see com.mongodb.WriteConcern */ public GridFS(final DB db, final String bucket) { this.database = db; this.bucketName = bucket; this.filesCollection = database.getCollection(bucketName + ".files"); this.chunksCollection = database.getCollection(bucketName + ".chunks"); // ensure standard indexes as long as collections are small try { if (filesCollection.count() < 1000) { filesCollection.createIndex(new BasicDBObject("filename", 1).append("uploadDate", 1)); } if (chunksCollection.count() < 1000) { chunksCollection.createIndex(new BasicDBObject("files_id", 1).append("n", 1), new BasicDBObject("unique", true)); } } catch (MongoException e) { //TODO: Logging }filesCollection.setObjectClass(GridFSDBFile.class); }

例如我们之前的操作方式现在完全是行不通的:
/** * 据id返回文件 */ public GridFSDBFile getById(ObjectId id){ GridFS gridFS = new GridFS(mongodbfactory.getDb()); // 这里会无法进行类型转换 return gridFS.findOne(new BasicDBObject("_id", id)); }

看注释发现可能是目前的遗留问题,还没有完全迁移过来。如果不适应可以退回旧的稳定版本等日后稳定了再用新版本。下面提供下我自己在新本中使用的方式:
GridFS---新版本java操作
文章图片

首先可以看到GridFS类中定义了默认的存储桶,如果我们不手动指定,查询和插入就都会指向这个默认创建的桶中。我们可以在配置类中手动配置自己想操作的存储桶:
/** * @author haichi * @version 1.0 * @date 2020/4/11 23:27 */ @Configuration public class MongoConfig {@Autowired MongoDbFactory mongoDbFactory; ////获取yml文件中的连接数据库 //@Value("${spring.data.mongodb.database}") String db = "filedb"; @Bean public GridFsTemplate gridFsTemplate(MongoDbFactory mongoDbFactory, MongoConverter converter) { return new GridFsTemplate(mongoDbFactory, converter, "files"); }//GridFSBucket用于打开下载流对象 @Bean public GridFSBucket getGridFSBucket(MongoClient mongoClient){ MongoDatabase database =mongoDbFactory.getDb(); System.out.println(database.getName()); GridFSBucket bucket = GridFSBuckets.create(database,"files"); return bucket; } }

存入:
public ObjectId save(File file){ try(InputStream inputStream = new FileInputStream(file); ){ ObjectId objectId = gridFsTemplate.store(inputStream,file.getName()); return objectId; } catch (Exception e){ log.error("文件写入mongo失败:" + e.getMessage()); e.printStackTrace(); } return null; }

我这里是测试用例实际生产中可以把File换为MultipartFile类型。try()这种写法可以自动关闭流。
取出文件:
public GridFSFile getById(ObjectId id) throws IOException { Query query = Query.query(Criteria.where("_id").is(id)); GridFSFile gridFSFile = gridFsTemplate.findOne(query); returngridFSFile; }后续: GridFsResource resource = new GridFsResource(gridFSFile); GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getId()); //创建gridFsResource,用于获取流对象 GridFsResource resource = new GridFsResource(gridFSFile,gridFSDownloadStream); InputStream inputStream = resource.getInputStream(); 拿到输入流就可以自行操作了

    推荐阅读