spring5.x-mongodb

作者: 宇宙小神特别萌 | 来源:发表于2019-11-12 13:50 被阅读0次
spring5.x-mongodb目录.png

spring5x-mongodb 此模块是从spring5x-base 基础模块扩展过来的
spring5x-base模块是一个非常干净的spring5.x+springMVC架构
如果没有搭建spring5x-base模块,请参考 spring5x-base模块搭建

搭建项目

基于spring5x-base 基础模块 新增功能:

  • 1、spring5 mongodb 依赖及配置
  • 2、MongoTemplate 对文档操作
  • 3、GridFsTemplate 对文件操作
  • 4、演示(文件上传和在线查看)

1、spring5 mongodb 依赖及配置


pom.xml 依赖

        <!--MongoDB核心包-->
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver</artifactId>
            <version>3.6.4</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>2.0.10.RELEASE</version>
            <scope>compile</scope>
            <exclusions>
                <exclusion>
                    <artifactId>mongo-java-driver</artifactId>
                    <groupId>org.mongodb</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>jcl-over-slf4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 其它的依赖(不包含spring) -->

        <!--IOUtils工具使用-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.1</version>
        </dependency>
        <!--spring mvc的文件上传类 CommonsMultipartResolver 依赖了这个包-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>
        <!-- 使用lombok实现JavaBean的get、set、toString、hashCode、equals等方法的自动生成  -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
            <scope>provided</scope>
            <optional>true</optional>
        </dependency>

mongodb.properties

# ip
mongo.host=127.0.0.1
# 端口
mongo.port=27017
# 数据库名称. 默认是'db'
mongo.dbname=test
# 用户名
mongo.username=test
# 密码
mongo.password=123456
# 凭证:认证方式  用户:密码@数据库名称
mongo.credentials=test:123456@test

# 每个主机允许的连接数
mongo.connectionsPerHost=10
# 线程队列数,它和上面connectionsPerHost值相乘的结果就是线程队列最大值。如果连接线程排满了队列就会抛出异常
mongo.threadsAllowedToBlockForConnectionMultiplier=5
# 连接超时的毫秒 0是默认值且无限大。
mongo.connectTimeout=1000
# 最大等待连接的线程阻塞时间 默认是120000 ms (2 minutes).
mongo.maxWaitTime=1500
# 保持活动标志,控制是否有套接字保持活动超时 官方默认为true 且不建议禁用
mongo.socketKeepAlive=true
# 用于群集心跳的连接的套接字超时。
mongo.socketTimeout=1500

注意:这里虽然有用户密码,但是我没有配置,应为我的mongodb没有设置用户密码认证

spring-mongodb.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mongo="http://www.springframework.org/schema/data/mongo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/data/mongo
       http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">

    <!-- 加载mongodb的属性配置文件 -->
    <context:property-placeholder location="classpath:mongodb/mongodb.properties" ignore-unresolvable="true"/>

    <!--定义用于访问 MongoDB 的 MongoClient 实例 ,凭证:认证 credentials="${mongo.credentials}" -->
    <mongo:mongo-client id="mongoClient" host="${mongo.host}" port="${mongo.port}">
        <mongo:client-options
                connections-per-host="${mongo.connectionsPerHost}"
                threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
                connect-timeout="${mongo.connectTimeout}"
                max-wait-time="${mongo.maxWaitTime}"
                socket-keep-alive="${mongo.socketKeepAlive}"
                socket-timeout="${mongo.socketTimeout}"
        />
    </mongo:mongo-client>

    <!--- 方式一: -->
    <!--<mongo:repositories base-package="com.zja.dao.mongo"/>-->

    <!-- 方式二: -->

    <!--定义用于连接到数据库的连接工厂-->
    <mongo:db-factory dbname="${mongo.dbname}" id="mongoDbFactory" mongo-ref="mongoClient"/>

    <!--转换器-->
    <mongo:mapping-converter id="converter" db-factory-ref="mongoDbFactory"/>

    <!-- mongodb的主要操作对象,所有对mongodb的增删改查的操作都是通过它完成 -->
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
    </bean>

    <!--mongo存储文件:主要操作文件存储和下载-->
    <bean id="gridFsTemplate" class="org.springframework.data.mongodb.gridfs.GridFsTemplate">
        <constructor-arg ref="mongoDbFactory"/>
        <constructor-arg ref="converter"/>
    </bean>

</beans>

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 开启注解包扫描-->
    <context:component-scan base-package="com.zja.*"/>

    <!--使用默认的 Servlet 来响应静态文件 -->
    <mvc:default-servlet-handler/>

    <!-- 开启springMVC 注解驱动 -->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="false">
            <!-- 将StringHttpMessageConverter的默认编码设为UTF-8 ,解决返回给前端中文乱码-->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <!-- 将Jackson2HttpMessageConverter的默认格式化输出设为true -->
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="prettyPrint" value="true"/>
                <property name="supportedMediaTypes">
                    <list>
                        <!-- 优先使用该媒体类型,为了解决IE浏览器下,返回JSON数据的下载问题 -->
                        <value>application/json;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                        <value>text/json;charset=UTF-8</value>
                    </list>
                </property>
                <!-- 使用内置日期工具进行处理 -->
                <property name="objectMapper">
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                        <property name="dateFormat">
                            <bean class="java.text.SimpleDateFormat">
                                <constructor-arg type="java.lang.String" value="yyyy-MM-dd"/>
                            </bean>
                        </property>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 增加application.properties文件 -->
    <context:property-placeholder
            location="classpath:application.properties" ignore-unresolvable="true"/>

    <!--spring-mongodb.xml 配置-->
    <import resource="classpath:mongodb/spring-mongodb.xml"/>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 :/WEB-INF/jsp/和/WEB-INF/html/-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 后缀 :.jsp和.html-->
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- =================== springmvc文件上传和下载 ================== -->
    <!--配置文件上传 id值固定 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 限制文件上传总大小,不设置默认没有限制,单位为字节 200*1024*1024即200M -->
        <property name="maxUploadSize" value="209715200" />
        <!-- 设置每个上传文件的大小上限 -->
        <property name="maxUploadSizePerFile" value="1048576"/>
        <!-- 处理文件名中文乱码 -->
        <property name="defaultEncoding" value="UTF-8" />
        <!-- resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常 -->
        <property name="resolveLazily" value="true" />
    </bean>

</beans>

注:
1、spring-mongodb.xml 配置
2、multipartResolver 配置 是为了控制文件上传大小

2、MongoTemplate 对文档操作


MongoTemplateController.java

package com.zja.controller;

import com.mongodb.client.result.DeleteResult;
import com.zja.entity.UserDTO;
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.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ZhengJa
 * @description Mongo 文档数据操作
 * @data 2019/11/8
 */
@RestController
@RequestMapping("rest/mongo")
public class MongoTemplateController {

    @Autowired
    private MongoTemplate mongoTemplate;

    @GetMapping("save/data")
    public Object insert() {

        UserDTO userDTO = new UserDTO();
        userDTO.setId("1");
        userDTO.setUsername("1");
        userDTO.setAge(1);

        //userDTO 要保存文档的数据 ,users集合    由于UserDTO类上有注解:@Document(collection = "users")
        mongoTemplate.save(userDTO);

        userDTO.setId("2");
        userDTO.setUsername("2");
        userDTO.setAge(2);
        //userDTO 要保存文档的数据 ,users集合    由于UserDTO类上有注解:@Document(collection = "users")
        mongoTemplate.save(userDTO);

        //根据条件查询 注意是 _id  ,也可以用name等其它字段做条件
        Query query = new Query(Criteria.where("_id").is("2"));

        List<UserDTO> userDTOS = mongoTemplate.find(query, UserDTO.class);

        return userDTOS;
    }

    /**
     * 根据id查询users文档数据
     *
     * @param id
     * @return java.lang.Object
     */
    @RequestMapping(value = "v2/users/getUser", method = RequestMethod.GET)
    public Object getUser(@RequestParam String id) {
        //根据条件查询 注意是 _id  ,也可以用name等其它字段做条件
        Query query = new Query(Criteria.where("_id").is(id));

        List<UserDTO> userDTOS = mongoTemplate.find(query, UserDTO.class);

        return userDTOS;
    }

    /**
     * 查询所有users文档数据
     *
     * @param
     * @return java.lang.Object
     */
    @RequestMapping(value = "v2/users/getAllUser", method = RequestMethod.GET)
    public Object getAllUser() {

        List<UserDTO> userDTOS = mongoTemplate.findAll(UserDTO.class);

        return userDTOS;
    }

    /**
     * 删除单条users文档数据
     *
     * @param id
     * @return java.lang.Object
     */
    @RequestMapping(value = "v2/users/deleteUser", method = RequestMethod.DELETE)
    public Object deleteUser(@RequestParam String id) {
        //根据条件查询 注意是 _id  ,也可以用name等其它字段做条件
        Query query = new Query(Criteria.where("_id").is(id));

        DeleteResult deleteResult = mongoTemplate.remove(query, UserDTO.class);

        Map map = new HashMap();
        map.put("wasAcknowledged", deleteResult.wasAcknowledged());
        map.put("getDeletedCount", deleteResult.getDeletedCount());

        return map;
    }

    /**
     * 删除所有users文档数据
     *
     * @param
     * @return java.lang.Object
     */
    @RequestMapping(value = "v2/users/deleteAllUser", method = RequestMethod.DELETE)
    public Object deleteAllUser() {

        Map map = new HashMap();
        List<UserDTO> userDTOS = (List<UserDTO>) getAllUser();
        int count = 0;
        for (UserDTO userDTO : userDTOS) {
            Object o = deleteUser(userDTO.getId());
            map.put("删除的第几条数据-" + count, o);
            count++;
        }
        
        return map;
    }

}

对文档的增删改查

3、GridFsTemplate 对文件操作


MongodbConfig.java

package com.zja.config;

import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;

import javax.annotation.Resource;

/** Mongodb 配置类
 * @author zhengja@dist.com.cn
 * @data 2019/6/19 17:26
 */
@Configuration
public class MongodbConfig {

    @Resource
    private MongoDbFactory mongoDbFactory;

    @Bean
    public GridFSBucket getGridFSBuckets() {
        MongoDatabase db = mongoDbFactory.getDb();
        return GridFSBuckets.create(db);
    }
}

操作文件:下载和在线查看文件,需要用的打开流

GridFsTemplateController.java

package com.zja.controller;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import org.apache.commons.io.IOUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author ZhengJa
 * @description 文件存储 操作
 * @data 2019/11/12
 */
@RestController
@RequestMapping("rest/gridfs")
public class GridFsTemplateController {

    @Autowired
    private GridFsTemplate gridFsTemplate;

    @Resource
    private GridFSBucket gridFSBucket;

    /**  文件上传测试:推荐用Postman工具请求测试 参考连接:https://www.jianshu.com/p/ba899556e02a **/

    /**文件上传测试:推荐用Postman工具测试
     * 单文件上传到-mongodb
     * @param file
     * @return java.lang.String
     */
    @RequestMapping(value = "v1/save/file",method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE)
    public String saveGridfs(@RequestParam(value = "file", required = true) MultipartFile file){

        System.out.println("Saving file..");
        DBObject metaData = new BasicDBObject();
        metaData.put("createdDate", new Date());

        String fileName = UUID.randomUUID().toString();

        System.out.println("File Name: " + fileName);

        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            gridFsTemplate.store(inputStream, fileName, "image", metaData);
            System.out.println("File saved: " + fileName);
        } catch (IOException e) {
            System.out.println("IOException: " + e);
            throw new RuntimeException("System Exception while handling request");
        }
        System.out.println("File return: " + fileName);
        return fileName;
    }

    /** 文件上传到mongodb:推荐用Postman工具测试
     * 多/单文件批量上传-mongodb :文件默认是上传到数据中的fs.files和fs.chunks中,files是用来存储文件的信息,文件名,md5,文件大小,还有刚刚的metadata,上传时间等等数据
     * @param multipartFiles
     * @return java.lang.Object
     */
    @RequestMapping(value = "v1/save/Manyfile", method = RequestMethod.POST)
    public Object uploadManyFile1(@RequestParam(value = "file") MultipartFile[] multipartFiles) throws Exception {
        Map map = new HashMap();
        System.out.println("multipartFiles.length " + multipartFiles.length);
        if (multipartFiles != null && multipartFiles.length > 0) {
            int count = 0;
            for (MultipartFile multipartFile : multipartFiles) {
                // 获得提交的文件名
                String fileName = multipartFile.getOriginalFilename();
                // 获得文件输入流
                InputStream ins = multipartFile.getInputStream();
                // 获得文件类型
                String contentType = multipartFile.getContentType();
                //存储文件的额外信息,比如用户ID,后面要查询某个用户的所有文件时就可以直接查询,可以不传
                DBObject metadata = new BasicDBObject("userId", "1001");

                // 将文件存储到mongodb中,mongodb 将会返回这个文件的具体信息
                ObjectId objectId = gridFsTemplate.store(ins, fileName, contentType);

                // 将文件存储到mongodb中,mongodb 将会返回这个文件的具体信息
                // ObjectId objectId = gridFsTemplate.store(ins, fileName, contentType, metadata);

                String fileInfo = "文件名称:\n"+fileName+"\n"+"fileId:"+"\n"+objectId.toString()+"\n"+"文件具体信息:\n"+objectId;

                map.put("fileInfo" + count,fileInfo);

                count++;
            }
        }
        return map;
    }

    /**
     * 在线查看Mongo中的文件:根据名称获取文件并在线查看
     * @param fileName
     * @param response
     * @return int
     */
    @RequestMapping(value = "v1/get/file", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
    public int getGridfs(@RequestParam(value = "fileName", required = true) String fileName,
                         HttpServletResponse response) throws IOException {
        GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("filename").is(fileName)));
        if (gridFSFile==null){
            System.out.println("File not found" + fileName);
            throw new RuntimeException("No file with name: " + fileName);
        }
        GridFsResource gridFsResource = convertGridFSFileToResource(gridFSFile);
        return IOUtils.copy(gridFsResource.getInputStream(),response.getOutputStream());
    }

    /**
     * 下载Mongo文件:根据名称下载文件
     * @param fileName
     * @param response
     * @return int
     */
    @RequestMapping(value = "v1/download/file", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
    public int downloadGridfs(@RequestParam(value = "fileName", required = true) String fileName,
                              HttpServletResponse response) throws IOException {
        GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("filename").is(fileName)));
        if (gridFSFile==null){
            System.out.println("File not found" + fileName);
            throw new RuntimeException("No file with name: " + fileName);
        }
        GridFsResource gridFsResource = convertGridFSFileToResource(gridFSFile);
        OutputStream sos = response.getOutputStream();
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        return IOUtils.copy(gridFsResource.getInputStream(),response.getOutputStream());
    }
    
   /**
     * 删除Mongo中的文件:根据名称删除文件
     * @param fileName 文件名
     * @return void
     */
    @RequestMapping(value = "v1/delete/file", method = RequestMethod.DELETE)
    public void deleteGridfs(@RequestParam(value = "fileName", required = true) String fileName) {
        System.out.println("Deleting file.." + fileName);
        gridFsTemplate.delete(new Query().addCriteria(Criteria.where("filename").is(fileName)));
        System.out.println("File deleted " + fileName);
    }

    /**
     * 转换器:将GridFSFile转为GridFsResource
     * @param gridFsFile
     * @return org.springframework.data.mongodb.gridfs.GridFsResource
     */
    private GridFsResource convertGridFSFileToResource(GridFSFile gridFsFile) {
        GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFsFile.getObjectId());
        return new GridFsResource(gridFsFile, gridFSDownloadStream);
    }

}

对文件的操作:
1、上传单个文件到mongodb
2、上传多个或单个文件到mongodb
3、在线查看Mongo中的文件
4、下载Mongo文件
5、删除Mongo中的文件

4、演示(文件上传和在线查看)


文件上传: mongo_1.png
文件在线查看: mongo_2.png

github 地址:

博客地址

相关文章

  • spring5.x-mongodb

    spring5x-mongodb 此模块是从spring5x-base 基础模块扩展过来的spring5x-bas...

网友评论

    本文标题:spring5.x-mongodb

    本文链接:https://www.haomeiwen.com/subject/huafictx.html