(二)MongoDB的在SpringBoot中的应用


我来填之前MongoDB的坑了,项目中又用到MongoDB的我又想起来了,我这拖延症也是没谁了。

1、在pom.xml中引入依赖


	org.springframework.boot
	spring-boot-starter-data-mongodb

2、配置连接信息

在 application.yml 中加入以下连接信息,修改自己的mongodb的连接信息

spring:
  #mongodb
  data:
    mongodb:
      database: text
      host: 192.168.1.24
      port: 27017
#      username: manager
#      password: manager

3、创建MongoDB的配置类

@Configuration
public class MongoConfig {

    @Value("${spring.data.mongodb.database}")
    String db;

    @Bean
    public GridFSBucket getGridFSBuckets(MongoClient mongoClient) {
        MongoDatabase database = mongoClient.getDatabase(db);
        return GridFSBuckets.create(database);
    }

}

4、存储数据、文件

在MongoDB中存储文件有两种方式,分别是将文件存储在表中和GridFS数据桶中;存储在表中的时候使用BSON(Binary JSON:二进制JSON)格式来存储数据,这种方式使用BSON(Binary JSON:二进制JSON)格式来存储数据;如果要存储大于16M的文件,就要用到MongoDB GridFS,GridFS是Mongo的一个子模块,使用GridFS可以基于MongoDB来持久存储文件。并且支持分布式应用(文件分布存储和读取)。作为MongoDB中二进制数据存储在数据库中的解决方案,通常用来处理大文件。

GridFS不是MongoDB自身特性,只是一种将大型文件存储在MongoDB的文件规范,所有官方支持的驱动均实现了GridFS规范。GridFS制定大文件在数据库中如何处理,通过开发语言驱动来完成、通过API接口来存储检索大文件。

1、以BSON格式来存储

创建实体类

/**
 * @ClassName: ImageInfo
 * @Description: mongoDB数据库图片表
 * @Author: TanXJ
 * @Date: 2021/10/12 11:09
 */
@Data
@Document
public class ImageInfo {
    @Id
    private String id;

    /** 文件名 */
    private String name;

    /** 上传时间 */
    private Date createdTime;

    /** 文件内容 */
    private Binary content;

    /** 文件类型 */
    private String contentType;

    /** 文件大小 */
    private long size;

    public ImageInfo() {}

    public ImageInfo(String name, Date createdTime, Binary content, String contentType, long size) {
        this.name = name;
        this.createdTime = createdTime;
        this.content = content;
        this.contentType = contentType;
        this.size = size;
    }
}

创建工具类

点击查看代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;

import java.util.List;
/**
 * @ClassName: MongoUtils
 * @Description: Mongodb工具类(将文件存储在数据表中)
 * @Author: TanXJ
 * @Date: 2021/10/12 10:41
 */
@Component
public class MongoUtils {

    private static  MongoTemplate mongoTemplate;

    @Autowired
    public void setRedisTemplate(MongoTemplate mongoTemplate) {
        MongoUtils.mongoTemplate = mongoTemplate;
    }

    /**
     * 保存数据对象,集合为数据对象中@Document 注解所配置的collection
     * @param obj 数据对象
     */
    public static void save(Object obj) {
        mongoTemplate.save(obj);
    }

    /**
     * 指定集合保存数据对象
     * @param obj 数据对象
     * @param collectionName 集合名
     */
    public static void save(Object obj, String collectionName) {
        mongoTemplate.save(obj, collectionName);
    }

    /**
     * 根据数据对象中的id删除数据,集合为数据对象中@Document 注解所配置的collection
     * @param obj 数据对象
     */
    public static void remove(Object obj) {
        mongoTemplate.remove(obj);
    }

    /**
     * 指定集合 根据数据对象中的id删除数据
     * @param obj 数据对象
     * @param collectionName 集合名
     */
    public static void remove(Object obj, String collectionName) {
        mongoTemplate.remove(obj, collectionName);
    }

    /**
     * 根据key,value到指定集合删除数据
     * @param key 键
     * @param value 值
     * @param collectionName 集合名
     */
    public static void removeById(String key, Object value, String collectionName) {
        Query query = Query.query(Criteria.where(key).is(value));
        mongoTemplate.remove(query, collectionName);
    }

    /**
     * 指定集合 修改数据,且仅修改找到的第一条数据
     * @param accordingKey 修改条件 key
     * @param accordingValue 修改条件 value
     * @param updateKeys 修改内容 key数组
     * @param updateValues 修改内容 value数组
     * @param collectionName 集合名
     */
    public static void updateFirst(String accordingKey, Object accordingValue, String[] updateKeys, Object[] updateValues, String collectionName) {
        Criteria criteria = Criteria.where(accordingKey).is(accordingValue);
        Query query = Query.query(criteria);
        Update update = new Update();
        for (int i = 0; i < updateKeys.length; i++) {
            update.set(updateKeys[i], updateValues[i]);
        }
        mongoTemplate.updateFirst(query, update, collectionName);
    }

    /**
     * 指定集合 修改数据,且修改所找到的所有数据
     * @param accordingKey 修改条件 key
     * @param accordingValue 修改条件 value
     * @param updateKeys 修改内容 key数组
     * @param updateValues 修改内容 value数组
     * @param collectionName 集合名
     */
    public static void updateMulti(String accordingKey, Object accordingValue, String[] updateKeys, Object[] updateValues, String collectionName) {
        Criteria criteria = Criteria.where(accordingKey).is(accordingValue);
        Query query = Query.query(criteria);
        Update update = new Update();
        for (int i = 0; i < updateKeys.length; i++) {
            update.set(updateKeys[i], updateValues[i]);
        }
        mongoTemplate.updateMulti(query, update, collectionName);
    }

    /**
     * 根据条件查询出所有结果集 集合为数据对象中@Document 注解所配置的collection
     * @param obj 数据对象
     * @param findKeys 查询条件 key
     * @param findValues 查询条件 value
     * @return
     */
    public static List<? extends Object> find(Object obj, String[] findKeys, Object[] findValues) {
        Criteria criteria = null;
        for (int i = 0; i < findKeys.length; i++) {
            if (i == 0) {
                criteria = Criteria.where(findKeys[i]).is(findValues[i]);
            } else {
                criteria.and(findKeys[i]).is(findValues[i]);
            }
        }
        Query query = Query.query(criteria);
        List<? extends Object> resultList = mongoTemplate.find(query, obj.getClass());
        return resultList;
    }

    /**
     * 指定集合 根据条件查询出所有结果集
     * @param obj 数据对象
     * @param findKeys 查询条件 key
     * @param findValues 查询条件 value
     * @param collectionName 集合名
     * @return
     */
    public static List<? extends Object> find(Object obj, String[] findKeys, Object[] findValues, String collectionName) {
        Criteria criteria = null;
        for (int i = 0; i < findKeys.length; i++) {
            if (i == 0) {
                criteria = Criteria.where(findKeys[i]).is(findValues[i]);
            } else {
                criteria.and(findKeys[i]).is(findValues[i]);
            }
        }
        Query query = Query.query(criteria);
        List<? extends Object> resultList = mongoTemplate.find(query, obj.getClass(), collectionName);
        return resultList;
    }

    /**
     * 指定集合 根据条件查询出所有结果集 并排倒序
     * @param obj 数据对象
     * @param findKeys 查询条件 key
     * @param findValues 查询条件 value
     * @param collectionName 集合名
     * @param sort 排序字段
     * @return
     */
    public static List<? extends Object> find(Object obj, String[] findKeys, Object[] findValues, String collectionName ,String sort) {
        Criteria criteria = null;
        for (int i = 0; i < findKeys.length; i++) {
            if (i == 0) {
                criteria = Criteria.where(findKeys[i]).is(findValues[i]);
            } else {
                criteria.and(findKeys[i]).is(findValues[i]);
            }
        }
        Query query = Query.query(criteria);
        query.with(Sort.by(Sort.Direction.DESC, sort));
        List<? extends Object> resultList = mongoTemplate.find(query, obj.getClass(), collectionName);
        return resultList;
    }

    /**
     * 根据条件查询出符合的第一条数据 集合为数据对象中 @Document 注解所配置的collection
     * @param obj 数据对象
     * @param findKeys 查询条件 key
     * @param findValues 查询条件 value
     * @return
     */
    public static Object findOne(Object obj, String[] findKeys, Object[] findValues) {
        Criteria criteria = null;
        for (int i = 0; i < findKeys.length; i++) {
            if (i == 0) {
                criteria = Criteria.where(findKeys[i]).is(findValues[i]);
            } else {
                criteria.and(findKeys[i]).is(findValues[i]);
            }
        }
        Query query = Query.query(criteria);
        Object resultObj = mongoTemplate.findOne(query, obj.getClass());
        return resultObj;
    }

    /**
     * 指定集合 根据条件查询出符合的第一条数据
     * @param obj 数据对象
     * @param findKeys 查询条件 key
     * @param findValues 查询条件 value
     * @param collectionName 集合名
     * @return
     */
    public static Object findOne(Object obj, String[] findKeys, Object[] findValues, String collectionName) {
        Criteria criteria = null;
        for (int i = 0; i < findKeys.length; i++) {
            if (i == 0) {
                criteria = Criteria.where(findKeys[i]).is(findValues[i]);
            } else {
                criteria.and(findKeys[i]).is(findValues[i]);
            }
        }
        Query query = Query.query(criteria);
        Object resultObj = mongoTemplate.findOne(query, obj.getClass(), collectionName);
        return resultObj;
    }

    /**
     * 查询出所有结果集 集合为数据对象中 @Document 注解所配置的collection
     * @param obj 数据对象
     * @return
     */
    public static List<? extends Object> findAll(Object obj) {
        List<? extends Object> resultList = mongoTemplate.findAll(obj.getClass());
        return resultList;
    }

    /**
     * 查询出所有结果集 集合为数据对象中 @Document 注解所配置的collection
     * @param clazz
     * @param 
     * @return
     */
    public static   List findAll(Class clazz){
        List resultList = mongoTemplate.findAll(clazz);
        return resultList;
    }

    /**
     * 指定集合 查询出所有结果集
     * @param obj 数据对象
     * @param collectionName 集合名
     * @return
     */
    public static List<? extends Object> findAll(Object obj, String collectionName) {
        List<? extends Object> resultList = mongoTemplate.findAll(obj.getClass(), collectionName);
        return resultList;
    }

    /**
     * 指定集合 查询出所有结果集
     * @param clazz
     * @param collectionName
     * @param 
     * @return
     */
    public static  List findAll(Class clazz, String collectionName) {
        List resultList = mongoTemplate.findAll(clazz, collectionName);
        return resultList;
    }

}

在代码中进行使用

ImageInfo imageInfo = new ImageInfo(fileName, new Date(), binary, suffixName, file.getSize());
MongoUtils.save(imageInfo);

2、以GridFS方式存储

点击查看代码
/**
 * @ClassName: GridFsUtils
 * @Description:  Mongodb工具类(将文件存储在GridFs中)
 * @Author: TanXJ
 * @Date: 2021/10/13 14:31
 */
@Component
public class GridFsUtils {

    private static GridFsTemplate gridFsTemplate;
    private static GridFSBucket gridFSBucket;

    @Autowired
    public void setRedisTemplate(GridFsTemplate gridFsTemplate) {
        GridFsUtils.gridFsTemplate = gridFsTemplate;
    }

    @Autowired
    public void setRedisTemplate(GridFSBucket gridFSBucket) {
        GridFsUtils.gridFSBucket = gridFSBucket;
    }

    /**
     * GridFs存储文件
     * 将文件按大小256k分割存到mongodb数据库
     * 将分割后的文件分记录存到fs.files表
     * 将完整文件信息存到fs.chunks表
     *
     * @param file
     * @throws FileNotFoundException
     */
    public static String storeFilesToGridFs(MultipartFile file) throws IOException {
        // 文件名
        String name = file.getOriginalFilename();
        // 获取文件类型
        String contenType = file.getContentType();
        //将要存储的文件写入输入流
        InputStream inputStream = file.getInputStream();
        //文件开始存储
        ObjectId objectId = gridFsTemplate.store(inputStream, name, contenType);
        //获取存储的文件id
        String fileId = objectId.toString();
        return fileId;
    }


    /**
     * GridFs读取文件
     * 读取数据库中的文件,以字符形式展示
     *
     * @param id
     * @return byte[]
     * @throws IOException
     */
    public static byte[] readFile(String id) {
        byte[] bytes = null;
        try {
            //根据文件id查询文件
            GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(id)));
            //使用GridFsBucket打开一个下载流对象
            GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
            //创建GridFsResource对象,获取流
            GridFsResource gridFsResource = new GridFsResource(gridFSFile, gridFSDownloadStream);
            //从流中取数据
            InputStream inputStream = gridFsResource.getInputStream();
            bytes = ByteStreams.toByteArray(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bytes;
    }

    /**
     * GridFs删除文件
     */
    public static void deleteFile(String id){
        //根据文件id删除fs.files表和fs.chunks表中的记录
        gridFsTemplate.delete(Query.query(Criteria.where("_id").is(id)));
    }

}

*** 可能还有些不足的地方,还请多多指教 ***