Spring与MongoDB集成使用

Spring与MongoDB结合

  • 前言
  • POM依赖
  • applicationContext文件
  • 使用代码

前言

公司让将一些离线数据,如交易订单、记账信息等数据存入MongoDB这样的,最像关系型的非关系型数据库中,于是我便开始研究怎样通过Spring方便地使用MongoDB,这里记录一下使用和配置的过程。
MongoDB这种可以在集合中任意增加字段的存储方式,非常适合公司多变的业务,并且其可配置为分布式的存储方式,非常适合横向扩展。MongoDB集合中的每条记录可设置索引,并且也支持聚合等运算,因此,在业务计算不是特别复杂,没有多表关联查询的场景,并且存储数据量非常庞大的场景下,可以考虑使用MongoDB作为数据存储的方式。

本文的配置及代码编写参考了Spring的官方文档 [ Spring Data MongoDB ]

POM依赖

这里说明一下,以下的配置JDK版本必须要升级至8,Spring版本需要是4。
往pom.xml文件中添加如下两个依赖。

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>2.0.0.M1</version>
</dependency>
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.3.0</version>
</dependency>

为什么依赖这两个版本呢,因为公司的仓库里只有这个版本,如果往里加的话还要申请,太麻烦了。
就先这么用着。

编写applicationContext.xml文件

这里我是通过applicationContext.xml文件来配置Spring的MongoDbTemplate的。具体的配置内容如下:

    <bean id="mongoCredential" class="com.mongodb.MongoCredential" 
            factory-method="createCredential">
        <constructor-arg value="${cashbase_balance_mongodb_username}"/>
        <constructor-arg value="admin"/>
        <constructor-arg value="${cashbase_balance_mongodb_password}"/>
    </bean>
    <bean id="userCredential" 
        class="org.springframework.data.authentication.UserCredentials">
        <constructor-arg>
            <null/>
        </constructor-arg>
        <constructor-arg>
            <null/>
        </constructor-arg>
    </bean>

    <bean id="mongoClientOptions" class="com.***.MongoClientUtils"
          factory-method="getMongoClientOptions"/>

    <bean id="mongoClient" class="com.mongodb.MongoClient">
        <constructor-arg 
            value="${cashbase_balance_mongodb_host}:${cashbase_balance_mongodb_port}"/>
        <constructor-arg>
            <list>
                <ref bean="mongoCredential"/>
            </list>
        </constructor-arg>
        <constructor-arg ref="mongoClientOptions"/>

    </bean>

    <bean id="mongoFactory" class="org.springframework.data.mongodb.core.SimpleMongoDbFactory">
        <constructor-arg ref="mongoClient"/>
        <constructor-arg value="${mongo_database}"/>
        <constructor-arg ref="userCredential"/>
    </bean>

    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg ref="mongoFactory"/>
    </bean>

从以上的配置中,可以看出,我的配置还是相当麻烦的。为什么会配得这么麻烦,因为按照官方文档给出的配置方法,可以使用mongo标签进行配置,但是我添加了相应的xmlns和xsi后,还是会提示我找不到标签之类等错误。并且标签的配置方法会造成初始化MongoDBFactory等初始化的错误,从错误信息来看是mongodb的版本和spring版本之间不兼容导致的。因此,干脆用最原始的方法来生成bean。

  • mongoTemplate

    mongoTemplate是我们用于增删改查等操作的对象,在之后的代码示例中会再解释。初始化它需要使用mongoDbFactory。

  • mongoDbFactory

    mongoDbFactory是一个提供数据库连接的工厂对象,这个接口目前只有一个实现类。它需要一个mongoClient对象,待连接的数据库名称(String对象)以及一个用户认证对象userCredential。这里比较特殊的一点是这个userCredential的用户名和密码必须为空字符串,而真正的安全性信息,需要填写在mongoCredential对象中

  • mongoClient

    这个对象需传入你的mongoDB连接地址,以及端口号,然后再传入mongoCredential这个bean,从配置文件中,可以看出,这个bean的构造方法必须传两个null,代表账号和密码。在Factory的源码中,如果你的mongoCredential对象中,账号和密码包含有非null的值,是会抛异常的。在我用的spring-data-mongodb版本中,账密的设置已经迁移到mongoCredential中了。这个对象还需提供一个ClientOption,这里可以设置你的定制化配置。我写的这个Option如下,只设置了一个超时时间:

import com.mongodb.MongoClientOptions;

public class MongoClientUtils {
    public static MongoClientOptions getMongoClientOptions() {
        MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
        builder.socketTimeout(10 * 1000);
        return builder.build();
    }
}


  • mongoCredential

mongoCredential对象可以设置客户端与MongoDB的安全通信方式,这里我使用的是默认的通信方式。此对象的构造方法需要传递连接到MongoDB的账户和密码,以及提供首选的库名,我这里写的是admin。

使用代码

上一节就是整个初始化的过程,下面说一下MongoTemplate的用法。

在我们的业务代码中,主要使用mongoTemplate进行常见的增删改查操作,代码如下。


import static org.springframework.data.mongodb.core.query.Criteria.where;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * mongoDb,从mongo中读写数据
 * Created by on 17-9-14
 */
@Component
public class MerchantMongoDAO {

    @Autowired
    private MongoTemplate mongoTemplate;

    private final Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * Insert if not Exists otherwise update
     *
     * @param merchantReportInfo merchantReportInfo
     */
    public void save(MerchantReportInfo merchantReportInfo) {
        if (Objects.isNull(merchantReportInfo)) {
            logger.info("insert object MerchantReportInfo is null");
            return;
        }
        merchantReportInfo.setId(merchantReportInfo.getReportIndex());
        String collectionName = "t_bal_merchant_monthly_summary";
        if (!mongoTemplate.collectionExists(collectionName)) {
            mongoTemplate.createCollection(collectionName);
        }
        logger.info("存入mongoDb,merchantReportInfo={}", merchantReportInfo);
        mongoTemplate.save(merchantReportInfo, collectionName);
    }

    /**
     * 通过mode和accountNo查询
     *
     * @param mode            模式
     * @param accountingMonth 商户帐号
     * @return List<MerchantReportInfo>
     */
    public List<MerchantReportInfo> query(int mode, int accountingMonth) {
        String collectionName = "t_bal_merchant_monthly_summary";
        Query query = new Query(where("month").is(accountingMonth).and("reportMode").is(mode));
        query.with(new Sort(new Sort.Order(Sort.Direction.ASC, "merchantId")));
        return mongoTemplate.find(query, MerchantReportInfo.class, collectionName);
    }
}

以上两段代码提供了插入和查询这两个操作。这个插入操作呢,就是无记录插入,有记录则更新。默认情况下mongoTemplate会以对象中的id字段作为主键。查询有Query、Where、Sort等方法,和SQL非常相近,比较好用。

1.了解Spring 2.了解NoSQL和文档数据库 3.要求 4.其他帮助资源 4.1。支持 4.1.1。社区论坛 4.1.2。专业支持 4.2。发展之后 5.新&值得注意的 5.1。Spring Data MongoDB 2.1中的新特性 5.2。Spring Data MongoDB 2.0中的新特性 5.3。Spring Data MongoDB 1.10中的新特性 5.4。Spring Data MongoDB 1.9中的新特性 5.5。Spring Data MongoDB 1.8中的新特性 5.6。Spring Data MongoDB 1.7中有什么新功能 6.依赖 6.1。Spring Boot的依赖管理 6.2。Spring框架 7.使用Spring Data Repositories 7.1。核心概念 7.2。查询方法 7.3。定义存储库接口 7.3.1。微调储存库定义 7.3.2。空处理存储库方法 7.3.3。将存储库与多个Spring Data模块一起使用 7.4。定义查询方法 7.4.1。查询查询策略 7.4.2。查询创建 7.4.3。属性表达式 7.4.4。特殊参数处理 7.4.5。限制查询结果 7.4.6。流式查询结果 7.4.7。异步查询结果 7.5。创建存储库实例 7.5.1。XML配置 7.5.2。JavaConfig 7.5.3。独立使用 7.6。Spring Data存储库的自定义实现 7.6.1。定制个人存储库 7.6.2。自定义基础存储库 7.7。从聚合根发布事件 7.8。Spring数据扩展 7.8.1。Querydsl扩展 7.8.2。Web支持 7.8.3。存储库填充程序 7.8.4。传统网络支持 参考文档 8.介绍 8.1。文档结构 9. MongoDB支持 9.1。入门 9.2。示例存储库 9.3。用Spring连接到MongoDB 9.3.1。使用基于Java的元数据注册Mongo实例 9.3.2。使用基于XML的元数据注册Mongo实例 9.3.3。MongoDbFactory接口 9.3.4。使用基于Java的元数据注册MongoDbFactory实例 9.3.5。使用基于XML的元数据注册MongoDbFactory实例 9.4。MongoTemplate简介 9.4.1。实例化MongoTemplate 9.4.2。WriteResultChecking策略 9.4.3。WriteConcern 9.4.4。WriteConcernResolver 9.5。保存,更新和删除文档 9.5.1。如何_id在映射图层中处理该字段 9.5.2。类型映射 9.5.3。保存和插入文件的方法 9.5.4。更新集合中的文档 9.5.5。在集合中插入文档 9.5.6。在集合中查找和插入文档 9.5.7。删除文件的方法 9.5.8。乐观锁定 9.6。查询文件 9.6.1。查询集合中的文档 9.6.2。查询文件的方法 9.6.3。查询不同的值 9.6.4。地理空间查询 9.6.5。GeoJSON支持 9.6.6。全文查询 9.6.7。排序规则 9.6.8。JSON模式 9.6.9。流利的模板API 9.7。按实例查询 9.7.1。介绍 9.7.2。用法 9.7.3。示例匹配器 9.7.4。执行一个例子 9.7.5。无类型示例 9.8。减少地图操作 9.8.1。使用示例 9.9。脚本操作 9.9.1。使用示例 9.10。集团运营 9.10.1。使用示例 9.11。聚合框架支持 9.11.1。基本概念 9.11.2。支持的聚合操作 9.11.3。投影表达式 9.11.4。分面分类 9.12。用自定义转换器覆盖默认映射 9.12.1。使用已注册的Spring Converter进行保存 9.12.2。使用Spring转换器读取 9.12.3。使用MongoConverter注册Spring转换器 9.12.4。转换器消除歧义 9.13。索引和集合管理 9.13.1。创建索引的方法 9.13.2。访问索引信息 9.13.3。使用集合的方法 9.14。执行命令 9.14.1。执行命令的方法 9.15。生命周期事件 9.16。例外翻译 9.17。执行回调 9.18。GridFS支持 9.19。更改流 9.19.1。使用MessageListener更改流 9.19.2。更改流 - 无效 10.反应性的MongoDB支持 10.1。入门 10.2。使用Spring和Reactive Streams Driver连接到MongoDB 10.2.1。使用基于Java的元数据注册MongoClient实例 10.2.2。ReactiveMongoDatabaseFactory接口 10.2.3。使用基于
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值