GridFS---新版本java操作

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

MongoTemplate:
public MongoDatabase getDb() {
		return doGetDatabase();
	}
MongoDbFactory:
MongoDatabase getDb() throws DataAccessException;	

MongoClient:
public MongoDatabase getDatabase(final String databaseName) {
      ......
    }

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 db     database 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操作_第2张图片
首先可以看到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);
        return  gridFSFile;
    }

后续:
GridFsResource resource = new GridFsResource(gridFSFile);
        GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getId());
        //创建gridFsResource,用于获取流对象
        GridFsResource resource = new GridFsResource(gridFSFile,gridFSDownloadStream);
        InputStream inputStream = resource.getInputStream();
        拿到输入流就可以自行操作了

你可能感兴趣的:(MongoDB)