Java实战操作MongoDB集群(副本集)
2017-10-31 09:23
435 查看
pring提供了MongoDB操作的工具:MongoTemplate,使得在Spring环境下对MongoDB的操作更为便利,本章我们就来学一下如何用MongoTemplate对MongoDB的集群环境(副本集)做操作;
本次实战,Web工程和MongoDB都运行在Docker环境的容器中,这么做是为了快速搭建环境,不要在环境上花费太多时间,更聚焦Java开发;
本次实战的java工程的源码我已经上传到github了,地址是:git@github.com:zq2599/blog_demos.git,里面有多个工程,本次实战的工程是mongodbreplicationdemo,如下图红框所示:
本次实战的环境是一个Tomcat server和Mongodb集群(副本集),我们将在Docker下部署这些server,所以一共要运行以下四个容器:
相互关系如下图:
本次实战我们用Maven创建一个java web工程,然后在线部署到Docker上去,Tomcat的镜像请用bolingcavalry/online_deploy_tomcat:0.0.1,关于在线部署的详情请参照文章《实战docker,编写Dockerfile定制tomcat镜像,实现web应用在线部署》
搭建MongoDB副本集的集群环境不是本章的重点,这篇文章详细的记录了如何搭建集群环境,您可以作为实战参考:《Docker下,实战mongodb副本集(Replication)》
由于要启动四个容器:Mongodb集群和Tomcat Server,所以用docker-compose批量管理比较方便,docker-compose.yml内容如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
如上述yml脚本所示,m0、m1、m2这三个容器组成了副本集集群,tomcat001容器配置的link属性中包含了其他三个容器,所以原本需要直接使用IP地址的地方都可以用mongodb0、mongodb1、mongodb2来代替了;
在docker-compose.yml文件所在目录下,执行命令docker-compose up -d批量启动所有容器,再进入m0容器把集群环境配置好,配置方法非常简单,请参考《Docker下,实战mongodb副本集(Replication)》
终于,准备工作已经完成,咱们可以开始编码了;
在我们的pom.xml中,除了常规的spring依赖,还要加入本次用到的MongoDB操作的依赖:
2
3
4
5
另外为了更方便的查看数据,我们把fastjson的依赖也引进来:
2
3
4
5
工程用到的资源文件一共四个,如下图:
config.properties
放的是MongoDB集群的所有机器地址和端口,以及要连接的数据库:
2
如上所示,机器地址并没有用IP,而是link参数中的alias:mongodb0,mongodb1,mongodb2;
2. logback.xml
日志配置,不细说了;
3. spring-extends.xml
这里面存放的是操作MongoDB所需的配置信息,mongoTemplate这个bean负责提供操作MongoDB的服务,请注意更改xmlns:mongo和xsi:schemaLocation的配置,负责会导致xml解析失败:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
在业务代码中通过AutoWire引入mongoTemplate,就能操作MongoDB了;
5. spring-mvc.xml
Spring环境的常规配置,不用多说了;
此外还有web.xml文件也要注意,要将spring-extends.xml引入:
2
3
4
代码结构如下图所示,我们通过浏览器发起的增删改查操作都会由MongodbController来处理,它会调用StudentService接口的服务,和数据库有关的实体类是Student:
实体类没什么好说的,主要是注意Document注解,说明了该类是student集合对应的实体类:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
下面是通过提供的API对MongoDB进行增删改查的代码:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
此处Controller的作用是受到web请求后直接调用Service提供的API来完成数据库操作:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
代码写好了,pom.xml所在目录下执行mvn clean package -U -Dmaven.test.skip=true tomcat7:redeploy在线部署到Tomcat server,然后一起来验证一下吧;
在浏览器输入http://localhost:8080/mongodbreplicationdemo/findall查看所有数据,会看到以下结果,表明查处的结果为空:
新增一条记录试试,输入http://localhost:8080/mongodbreplicationdemo/insert?name=Tom&age=11,提示操作成功:
再查看就有数据了:
执行这个请求更新Tom的年龄:http://localhost:8080/mongodbreplicationdemo/update?name=Tom&age=33
再看看年龄已经更新成功了:
最后是删除操作:http://localhost:8080/mongodbreplicationdemo/delete?name=Tom
本次实战的java工程的源码我已经上传到github了,地址是:git@github.com:zq2599/blog_demos.git,里面有多个工程,本次实战的工程是mongodbreplicationdemo,如下图红框所示:
至此,Java操作MongoDB的实战就结束了,我们对MongoTemplate算是有了初步的认识,更多的功能应该是配合着MongoDB的功能以及实际场景的需求逐渐浮出水面,大家一起尝试和探索吧。
实战环境选用Docker
本次实战,Web工程和MongoDB都运行在Docker环境的容器中,这么做是为了快速搭建环境,不要在环境上花费太多时间,更聚焦Java开发;
Java源码
本次实战的java工程的源码我已经上传到github了,地址是:git@github.com:zq2599/blog_demos.git,里面有多个工程,本次实战的工程是mongodbreplicationdemo,如下图红框所示:
环境规划
本次实战的环境是一个Tomcat server和Mongodb集群(副本集),我们将在Docker下部署这些server,所以一共要运行以下四个容器:容器名 | ip | 备注 |
---|---|---|
m0 | 172.18.0.2 | MongoDB Primary |
m1 | 172.18.0.3 | MongoDB Secondary1 |
m2 | 172.18.0.4 | MongoDB Secondary2 |
tomcat001 | 172.18.0.5 | Tomcat server |
关于Tomcat server环境
本次实战我们用Maven创建一个java web工程,然后在线部署到Docker上去,Tomcat的镜像请用bolingcavalry/online_deploy_tomcat:0.0.1,关于在线部署的详情请参照文章《实战docker,编写Dockerfile定制tomcat镜像,实现web应用在线部署》
关于MongoDB集群环境
搭建MongoDB副本集的集群环境不是本章的重点,这篇文章详细的记录了如何搭建集群环境,您可以作为实战参考:《Docker下,实战mongodb副本集(Replication)》
docker-compose.yml配置
由于要启动四个容器:Mongodb集群和Tomcat Server,所以用docker-compose批量管理比较方便,docker-compose.yml内容如下:version: '2' services: m0: image: bolingcavalry/ubuntu16-mongodb349:0.0.1 container_name: m0 command: /bin/sh -c 'mongod --replSet replset0' restart: always m1: image: bolingcavalry/ubuntu16-mongodb349:0.0.1 container_name: m1 depends_on: - m0 command: /bin/sh -c 'mongod --replSet replset0' restart: always m2: image: bolingcavalry/ubuntu16-mongodb349:0.0.1 container_name: m2 depends_on: - m1 command: /bin/sh -c 'mongod --replSet replset0' restart: always tomcat001: image: bolingcavalry/online_deploy_tomcat:0.0.1 container_name: tomcat001 ports: - "8080:8080" links: - m0:mongodb0 - m1:mongodb1 - m2:mongodb2 restart: always1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
如上述yml脚本所示,m0、m1、m2这三个容器组成了副本集集群,tomcat001容器配置的link属性中包含了其他三个容器,所以原本需要直接使用IP地址的地方都可以用mongodb0、mongodb1、mongodb2来代替了;
启动容器,把集群环境配置好
在docker-compose.yml文件所在目录下,执行命令docker-compose up -d批量启动所有容器,再进入m0容器把集群环境配置好,配置方法非常简单,请参考《Docker下,实战mongodb副本集(Replication)》终于,准备工作已经完成,咱们可以开始编码了;
依赖库
在我们的pom.xml中,除了常规的spring依赖,还要加入本次用到的MongoDB操作的依赖:<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>1.2.0.RELEASE</version> </dependency>1
2
3
4
5
另外为了更方便的查看数据,我们把fastjson的依赖也引进来:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.39</version> </dependency>1
2
3
4
5
资源文件
工程用到的资源文件一共四个,如下图:config.properties
放的是MongoDB集群的所有机器地址和端口,以及要连接的数据库:
mongodb.host=mongodb0:27017,mongodb1:27017,mongodb2:27017 mongodb.dataname=school1
2
如上所示,机器地址并没有用IP,而是link参数中的alias:mongodb0,mongodb1,mongodb2;
2. logback.xml
日志配置,不细说了;
3. spring-extends.xml
这里面存放的是操作MongoDB所需的配置信息,mongoTemplate这个bean负责提供操作MongoDB的服务,请注意更改xmlns:mongo和xsi:schemaLocation的配置,负责会导致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:mongo="http://www.springframework.org/schema/data/mongo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- 自动扫描 --> <context:component-scan base-package="com.bolingcavalry" /> <!-- mongodb配置 --> <context:property-placeholder location="classpath:config.properties"/> <!--集群--> <mongo:mongo id="replicaSetMongo" replica-set="${mongodb.host}"> <!-- 每个IP的连接数--> <mongo:options connections-per-host="10" threads-allowed-to-block-for-connection-multiplier="5" auto-connect-retry="true"/> </mongo:mongo> <!--给应用用到的--> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongo" ref="replicaSetMongo" /> <!--mongo的数据库名称--> <constructor-arg name="databaseName" value="${mongodb.dataname}" /> </bean> </beans>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
在业务代码中通过AutoWire引入mongoTemplate,就能操作MongoDB了;
5. spring-mvc.xml
Spring环境的常规配置,不用多说了;
此外还有web.xml文件也要注意,要将spring-extends.xml引入:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-extends.xml</param-value> </context-param>1
2
3
4
代码结构
代码结构如下图所示,我们通过浏览器发起的增删改查操作都会由MongodbController来处理,它会调用StudentService接口的服务,和数据库有关的实体类是Student:
Student实体类
实体类没什么好说的,主要是注意Document注解,说明了该类是student集合对应的实体类:@Document(collection = "student") public class Student { /** * 学号 */ private String id; /** * 姓名 */ private String name; /** * 年龄 */ private int age; ......1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
服务实现类,操作MongoDB的核心代码
下面是通过提供的API对MongoDB进行增删改查的代码:@Autowired MongoTemplate mongoTemplate; /** * 新增一个文档 * @param student * @return */ public String insert(Student student) { LOGGER.info("start insert : {}", JSON.toJSONString(student)); mongoTemplate.insert(student); LOGGER.info("finish insert"); return null; } /** * 根据名称删除文档 * @param name * @return */ public String deleteByName(String name) { LOGGER.info("start delete [{}]", name); Query query = new Query(); Criteria criteria = new Criteria(); criteria.and("name").is(name); query.addCriteria(criteria); mongoTemplate.findAndRemove(query, Student.class); return null; } /** * 根据名称修改student文档的年龄字段 * @param student * @return */ public String updateByName(Student student) { LOGGER.info("start update [{}]", JSON.toJSONString(student)); //构造查询信息 Query query = buildNameQuery(student.getName()); //构造更新信息 Update update = new Update(); update.set("age", student.getAge()); //执行更新 mongoTemplate.updateFirst(query, update, Student.class); return null; } /** * 查找student集合的所有文档 * @return */ public List<Student> findAll() { return mongoTemplate.findAll(Student.class); } /** * 创建一个根据名字查询的Query对象 * @param name * @return */ private Query buildNameQuery(String name){ Query query = new Query(); Criteria criteria = new Criteria(); criteria.and("name").is(name); query.addCriteria(criteria); return query; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Controller对Service的调用
此处Controller的作用是受到web请求后直接调用Service提供的API来完成数据库操作:@Autowired StudentService studentService; @RequestMapping("/insert") public String insert(HttpServletRequest request, Model model) { String errorStr = studentService.insert(buildStudent(request)); LOGGER.info("student insert service response [{}]", errorStr); return StringUtils.isEmpty(errorStr) ? "success" : buileFilePageInfo(errorStr, model); } @RequestMapping("/delete") public String delete(HttpServletRequest request, Model model) { String name = get(request, "name"); String errorStr = studentService.deleteByName(name); LOGGER.info("student deleteByName service response [{}]", errorStr); return StringUtils.isEmpty(errorStr) ? "success" : buileFilePageInfo(errorStr, model); } @RequestMapping("/update") public String update(HttpServletRequest request, Model model) { String errorStr = studentService.updateByName(buildStudent(request)); LOGGER.info("student updateByName service response [{}]", errorStr); return StringUtils.isEmpty(errorStr) ? "success" : buileFilePageInfo(errorStr, model); } @RequestMapping("/findall") @ResponseBody public String findAll(HttpServletRequest request, Model model) { List<Student> list = studentService.findAll(); return (null!=list && !list.isEmpty()) ? JSON.toJSONString(list) : "empty"; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
部署
代码写好了,pom.xml所在目录下执行mvn clean package -U -Dmaven.test.skip=true tomcat7:redeploy在线部署到Tomcat server,然后一起来验证一下吧;
验证
在浏览器输入http://localhost:8080/mongodbreplicationdemo/findall查看所有数据,会看到以下结果,表明查处的结果为空:新增一条记录试试,输入http://localhost:8080/mongodbreplicationdemo/insert?name=Tom&age=11,提示操作成功:
再查看就有数据了:
执行这个请求更新Tom的年龄:http://localhost:8080/mongodbreplicationdemo/update?name=Tom&age=33
再看看年龄已经更新成功了:
最后是删除操作:http://localhost:8080/mongodbreplicationdemo/delete?name=Tom
本次实战的java工程的源码我已经上传到github了,地址是:git@github.com:zq2599/blog_demos.git,里面有多个工程,本次实战的工程是mongodbreplicationdemo,如下图红框所示:
至此,Java操作MongoDB的实战就结束了,我们对MongoTemplate算是有了初步的认识,更多的功能应该是配合着MongoDB的功能以及实际场景的需求逐渐浮出水面,大家一起尝试和探索吧。
相关文章推荐
- Java实战操作MongoDB集群(副本集)
- mongodb集群分片+副本模式操作+javaCode
- Java实现对MongoDB的AND、OR和IN操作
- Mongodb笔记之(Java中操作Mongodb)
- mongodb基础系列——java操作mongodb实现CURD
- Mongodb快速入门之使用Java操作Mongodb
- Java操作Redis集群
- MongoDB分片实战(一):集群搭建
- java 操作MongoDB—Hello World
- Java操作MongoDB
- Java操作MongoDB采用MongoRepository仓库进行条件查询
- mongodb基本命令和Java操作API示例
- mongodb java常用操作记录
- MongoDB在java中的操作-添,删,查 基本数据 文件存储 可使用
- java客户端操作fastdfs集群
- java及spark2.X连接mongodb3.X单机或集群的方法(带认证及不带认证)
- 【NoSQL】Mongodb高可用架构—Replica Set 集群实战 推荐
- java对mongodb的and, in, or 经常使用操作
- 实战Java高并发程序设计-07原子操作
- java操作mongodb(连接池)(转)