springcloud(java)+spring-data-mongo 集成 mongodb 副本集集群

本贴最后更新于 2506 天前,其中的信息可能已经时移世易

springcloud(java)+spring-data-mongo 集成 mongodb 副本集集群

环境

springcloud版本Dalston.SR1 springboot版本1.5.2.RELEASE mongodb3.4.14 3台3分片
  1. 在 pomx.ml 引入 spring-boot-starter-data-mongodb
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>

2.在 yml 里配置

spring: data: mongodb: uri: mongodb://admin:123456@192.168.31.1:20000,192.168.31.2:20000,192.168.31.3:20000/testdb?authSource=admin&connect=replicaSet&readPreference=secondaryPreferred&safe=true&authMechanism=SCRAM-SHA-1&maxPoolSize=500&minPoolSize=10
  1. uri 参数说明
  • uri 格式
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
  • mongodb:// 这是固定的格式,必须要指定。
  • username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登陆这个数据库
  • host1 必须的指定至少一个 host, host1 是这个 URI 唯一要填写的。它指定了要连接服务器的地址。如果要连接复制集,请指定多个主机地址。
  • portX 可选的指定端口,如果不填,默认为 27017
  • /database 如果指定 username:password@,连接并验证登陆指定数据库。若不指定,默认打开 test 数据库。
  • ?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对 name=value,键值对之间通过&或;(分号)隔开

标准的连接格式包含了多个选项(options),如下所示:

选项 描述
replicaSet=name 验证 replica set 的名称。 Impliesconnect=replicaSet.
safe=true|false true:在执行更新操作之后,驱动都会发送 getLastError 命令来确保更新成功。(还要参考 wtimeoutMS).false: 在每次更新之后,驱动不会发送 getLastError 来确保更新成功。
w=n 驱动添加 { w : n } 到 getLastError 命令. 应用于 safe=true。
wtimeoutMS=ms 驱动添加 { wtimeout : ms } 到 getlasterror 命令. 应用于 safe=true.
fsync=true|false true: 驱动添加 { fsync : true } 到 getlasterror 命令.应用于 safe=true
journal=true|false 如果设置为 true, 同步到 journal (在提交到数据库前写入到实体中). 应用于 safe=true
connectTimeoutMS=ms 可以打开连接的时间。
socketTimeoutMS=ms 发送和接受 sockets 的时间。

跟多参数参考:mongodb 官方文档

  1. 建立通用 model
    MongoOpenDoorLog.java
import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.index.CompoundIndex; import org.springframework.data.mongodb.core.index.CompoundIndexes; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; import java.io.Serializable; @Document(collection="open_door_log") @CompoundIndexes({ @CompoundIndex(name = "id_1_user_id_1_open_time_1", def = "{'user_id': 1, 'open_time': 1}"), @CompoundIndex(name = "door_id_1_community_id_1_build_id_1_cell_id_1", def = "{'door_id': 1, 'community_id': 1,'build_id':1,'cell_id':1}") }) public class MongoOpenDoorLog implements Serializable{ @Id private String id; private String tid; @Field("log_time") private long logTime; @Field("door_id") private String doorId; @Field("user_id") private String userId; @Field("user_type") private String userType; @Field("device_type") private String deviceType; @Field("device_sys") private String deviceSys; @Field("open_time") private long openTime; @Field("lock_type") private int lockType; @Field("open_type") private int openType; @Field("open_info") private String openInfo; @Field("area_id") private String areaId; private String area; @Field("community_id") private String communityId; @Field("community_name") private String communityName; @Field("build_id") private String buildId; @Field("build_name") private String buildName; @Field("build_num") private String buildNum; @Field("cell_id") private String cellId; @Field("cell_name") private String cellName; @Field("cell_num") private String cellNum; private int feedback; @Field("feedback_time") private long feedbackTime; private String img; private boolean deletec; /** * 创建时间 */ @Field("create_time") private long createTime; /** * 更新时间 */ @Field("update_time") private long updateTime; public void setId(String id){ this.id = id; } public String getId(){ return this.id; } public void setLogTime(long logTime){ this.logTime = logTime; } public long getLogTime(){ return this.logTime; } public void setDoorId(String doorId){ this.doorId = doorId; } public String getDoorId(){ return this.doorId; } public void setDeviceType(String deviceType){ this.deviceType = deviceType; } public String getDeviceType(){ return this.deviceType; } public void setDeviceSys(String deviceSys){ this.deviceSys = deviceSys; } public String getDeviceSys(){ return this.deviceSys; } public void setOpenTime(long openTime){ this.openTime = openTime; } public long getOpenTime(){ return this.openTime; } public void setLockType(int lockType){ this.lockType = lockType; } public int getLockType(){ return this.lockType; } public void setOpenType(int openType){ this.openType = openType; } public int getOpenType(){ return this.openType; } public void setOpenInfo(String openInfo){ this.openInfo = openInfo; } public String getOpenInfo(){ return this.openInfo; } public void setAreaId(String areaId){ this.areaId = areaId; } public String getAreaId(){ return this.areaId; } public void setArea(String area){ this.area = area; } public String getArea(){ return this.area; } public void setCommunityId(String communityId){ this.communityId = communityId; } public String getCommunityId(){ return this.communityId; } public void setCommunityName(String communityName){ this.communityName = communityName; } public String getCommunityName(){ return this.communityName; } public void setBuildId(String buildId){ this.buildId = buildId; } public String getBuildId(){ return this.buildId; } public void setBuildName(String buildName){ this.buildName = buildName; } public String getBuildName(){ return this.buildName; } public void setBuildNum(String buildNum){ this.buildNum = buildNum; } public String getBuildNum(){ return this.buildNum; } public void setCellId(String cellId){ this.cellId = cellId; } public String getCellId(){ return this.cellId; } public void setCellName(String cellName){ this.cellName = cellName; } public String getCellName(){ return this.cellName; } public void setCellNum(String cellNum){ this.cellNum = cellNum; } public String getCellNum(){ return this.cellNum; } public void setFeedback(int feedback){ this.feedback = feedback; } public int getFeedback(){ return this.feedback; } public void setFeedbackTime(long feedbackTime){ this.feedbackTime = feedbackTime; } public long getFeedbackTime(){ return this.feedbackTime; } public void setImg(String img){ this.img = img; } public String getImg(){ return this.img; } public boolean isDeletec() { return deletec; } public void setDeletec(boolean deletec) { this.deletec = deletec; } public long getCreateTime() { return createTime; } public void setCreateTime(long createTime) { this.createTime = createTime; } public long getUpdateTime() { return updateTime; } public void setUpdateTime(long updateTime) { this.updateTime = updateTime; } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserType() { return userType; } public void setUserType(String userType) { this.userType = userType; } public String getTid() { return tid; } public void setTid(String tid) { this.tid = tid; } }
  1. 建立通用 dao
    MongoBaseDao.java
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import java.util.List; public interface MongoBaseDao<T> { //保存一个对象到mongodb public T save(T bean); // 根据id删除对象 public void deleteById(T t); // 根据对象的属性删除 public void deleteByCondition(T t); // 通过条件查询更新数据 public void update(Query query, Update update); // 根据id进行更新 public void updateById(String id, T t); // 通过条件查询实体(集合) public List<T> find(Query query); public List<T> findByCondition(T t); // 通过一定的条件查询一个实体 public T findOne(Query query); // 通过ID获取记录 public T get(String id); // 通过ID获取记录,并且指定了集合名(表的意思) public T get(String id, String collectionName); public MongoTemplate getMongoTemplate(); }
  1. 建立通用 daosuport
    MongoDaoSupport.java
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; 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 java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.util.List; public abstract class MongoDaoSupport<T extends Serializable> implements MongoBaseDao<T> { @Autowired @Qualifier("mongoTemplate") protected MongoTemplate mongoTemplate; //保存一个对象到mongodb public T save(T bean) { mongoTemplate.save(bean); return bean; } // 根据id删除对象 public void deleteById(T t) { mongoTemplate.remove(t); } // 根据对象的属性删除 public void deleteByCondition(T t) { Query query = buildBaseQuery(t); mongoTemplate.remove(query, getEntityClass()); } // 通过条件查询更新数据 public void update(Query query, Update update) { mongoTemplate.updateMulti(query, update, this.getEntityClass()); } // 根据id进行更新 public void updateById(String id, T t) { Query query = new Query(); query.addCriteria(Criteria.where("id").is(id)); Update update = buildBaseUpdate(t); update(query, update); } // 通过条件查询实体(集合) public List<T> find(Query query) { return mongoTemplate.find(query, this.getEntityClass()); } public List<T> findByCondition(T t) { Query query = buildBaseQuery(t); return mongoTemplate.find(query, getEntityClass()); } // 通过一定的条件查询一个实体 public T findOne(Query query) { return mongoTemplate.findOne(query, this.getEntityClass()); } // 通过ID获取记录 public T get(String id) { return mongoTemplate.findById(id, this.getEntityClass()); } // 通过ID获取记录,并且指定了集合名(表的意思) public T get(String id, String collectionName) { return mongoTemplate.findById(id, this.getEntityClass(), collectionName); } // 根据vo构建查询条件Query private Query buildBaseQuery(T t) { Query query = new Query(); Field[] fields = t.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); try { Object value = field.get(t); if (value != null) { org.springframework.data.mongodb.core.mapping.Field queryField = field.getAnnotation(org.springframework.data.mongodb.core.mapping.Field.class); if (queryField != null) { query.addCriteria(Criteria.where(queryField.value()).is(value)); }else{ query.addCriteria(Criteria.where(field.getName()).is(value)); } } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return query; } private Update buildBaseUpdate(T t) { Update update = new Update(); Field[] fields = t.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); try { Object value = field.get(t); if (value != null) { update.set(field.getName(), value); } } catch (Exception e) { e.printStackTrace(); } } return update; } // 获取需要操作的实体类class @SuppressWarnings("unchecked") protected Class<T> getEntityClass() { return ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]); } public MongoTemplate getMongoTemplate() { return mongoTemplate; } }

8.建立 service 接口
MongoOpenDoorLogService.java

public interface MongoOpenDoorLogService extends MongoBaseDao<MongoOpenDoorLog> { }
  1. 建立 service 实现类
    MongoOpenDoorLogServiceImpl.java
import org.springframework.stereotype.Service; @Service("mongoOpenDoorLogServiceImpl") public class MongoOpenDoorLogServiceImpl extends MongoDaoSupport<MongoOpenDoorLog> implements MongoOpenDoorLogService{ }
  1. 暴露接口
    RequestObject.java
import com.zzwtec.common.validation.constraint.ZNotBlank; import com.zzwtec.common.validation.constraint.ZNotNullWithStr; import javax.validation.Valid; public class RequestObject<T> { @ZNotBlank private String requestId; @Valid @ZNotNullWithStr private T data; public RequestObject() { this.requestId = RequestIdContext.get(); } public RequestObject(T data) { this(); this.data = data; } public RequestObject(String requestId, T data) { this.requestId = requestId; this.data = data; } public String getRequestId() { return requestId; } public RequestObject<T> setRequestId(String requestId) { this.requestId = requestId; return this; } public T getData() { return data; } public RequestObject<T> setData(T data) { this.data = data; return this; } public static <T> RequestObject<T> build(T data) { return new RequestObject<T>(data); } public static <T> RequestObject<T> build(T data,String requestId) { return new RequestObject<T>(requestId,data); } public static <T> RequestObject<T> build(String requestId,T data) { return new RequestObject<T>(requestId,data); } @Override public String toString() { return "RequestObject [requestId=" + requestId + ", data=" + data + "]"; } }

ResultObject.java

public class ResultObject<T> { public static final String SUCCESS_CODE = "0"; public static final String SUCCESS_MSG = "success"; public static final String ERROR_CODE = "1"; public static final String ERROR_MSG = "error"; private String requestId; /** * 返回码 */ private String code; /** * 返回描述 */ private String msg; /** * 请求数据 */ private T data; public ResultObject() { } public ResultObject(String requestId) { this.requestId = requestId; } @SuppressWarnings("rawtypes") public ResultObject(RequestObject request) { this(request.getRequestId()); } @SuppressWarnings("rawtypes") public ResultObject(RequestObject request, String code, String msg) { this(request); this.code = code; this.msg = msg; } @SuppressWarnings("rawtypes") public ResultObject(RequestObject request, String code, String msg, T data) { this(request, code, msg); this.data = data; } public String getRequestId() { return requestId; } public ResultObject<T> setRequestId(String requestId) { this.requestId = requestId; return this; } public String getCode() { return code; } public ResultObject<T> setCode(String code) { this.code = code; return this; } public String getMsg() { return msg; } public ResultObject<T> setMsg(String msg) { this.msg = msg; return this; } public T getData() { return data; } public ResultObject<T> setData(T data) { this.data = data; return this; } public boolean isSuccess() { return SUCCESS_CODE.equals(code); } @Override public String toString() { return "ResultObject [requestId=" + requestId + ", code=" + code + ", msg=" + msg + ", data=" + data + "]"; } }

OpenDoorLogService.java

import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @FeignClient(name = "a", fallback = OpenDoorLogServiceFallback.class) @RequestMapping("odls") @Api(value="OpenDoorLogService", description="mongodb开门日志操作外部服务接口", consumes = "application/json", produces = "application/json", protocols = "http") public interface OpenDoorLogService { /** * 添加单条开门日志 * @param request * @return */ @ApiOperation(value="add", notes="添加单条开门日志") @ApiImplicitParam(name = "request", required = true, dataType = "RequestObject<MongoOpenDoorLog>", paramType = "body") @RequestMapping(value = "add", method = RequestMethod.POST) public ResultObject<Void> saveOpenDoorLog(@GroupsValid({Add.class}) @RequestBody RequestObject<MongoOpenDoorLog> request); }

OpenDoorLogServiceController.java

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class OpenDoorLogServiceController implements OpenDoorLogService { @Autowired private MongoOpenDoorLogService mongoOpenDoorLogService; @Override public ResultObject<Void> saveOpenDoorLog(@GroupsValid({Add.class}) @RequestBody RequestObject<MongoOpenDoorLog> request){ MongoOpenDoorLog t = request.getData(); mongoOpenDoorLogService.save(t); return ResultBuilder.success(request); } }
  1. 其它辅助类
    GroupsValid.java
import java.lang.annotation.*; @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface GroupsValid { Class<?>[] value() default {}; }
Add.java public interface Add { } Delete.java public interface Delete { } Query.java public interface Query { } Update.java public interface Update { }
  • 集群
    29 引用 • 65 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖
  • Anytype
    3 引用 • 31 回帖 • 28 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 831 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 397 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖 • 1 关注
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 523 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    346 引用 • 760 回帖 • 1 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖 • 2 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    591 引用 • 3528 回帖 • 2 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 391 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 44 关注
  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 233 回帖 • 1 关注
  • 印象笔记
    3 引用 • 16 回帖
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    118 引用 • 54 回帖 • 5 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 281 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖 • 6 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    37 引用 • 157 回帖
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 824 关注
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 76 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    948 引用 • 1460 回帖 • 1 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    211 引用 • 358 回帖
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖 • 4 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 160 关注
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖