spring5.2.17+mongodb4.4+spring-data-mongo2.x
前言
最近用spring5.2.17+mongodb4.4整合框架,搞了三天,终于好了,现在把过程记录下来。
环境要求
1、JDK-1.8
2、spring-5.2.17
3、mongodb4.4
4、spring-data-mongo-2.2.13
5、mongo-java-driver-3.12.10
6、spring-data-commons-2.2.13
7、tomcat9.0
8、slf4j-api-1.7.32
首先,我用的是spring-data-mongo-2.x。为什么不用spring-data-mongo-3.x呢?因为官网说了3.x需要spring5.3.10及其以后,而且3.x不能无密码访问MongoDB数据库,必须要设置密码。其次,spring-data-mongo和spring-data-commons最好是相同版本号,不然会报类找不到错误o(╥﹏╥)o(我掉这个坑里好久了),用pom的最好也手动指定版本号。最后,spring-data-mongo-2.x对应的mongo-java-driver是3.x版本,这两个也一定要对应,不然又报类找不到错误。
注意,一定要引入 spring-data-commons,不然会报类找不到错误(RepositoryConfigurationExtension),但是现在网上的教程都是不引入 spring-data-commons,都可以使用,我也不知道为啥。。。
正式开搞
搭建完环境,现在可以编写代码测试了,老规矩,先写一个test工程,看看效果。
工程目录如下:
1、xml相关配置
(1)web.xml配置
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
(2)mongodb-config.properties配置
#mongo db的配置,如果不启用则不需要配置
mongo.host=192.168.1.3
mongo.port=27017
# 数据库名称. 默认是'db'.
mongo.dbname=test
# 每个主机允许的连接数。线程池允许的最大连接数
mongo.connectionsPerHost=20
# 线程池空闲时保持的最小连接数
mongo.minConnectionsPerHost=10
# 线程队列数,它和上面connectionsPerHost值相乘的结果就是线程队列最大值。如果连接线程排满了队列就会抛出异常
mongo.threadsAllowedToBlockForConnectionMultiplier=50
# 连接超时的毫秒 0是默认值且无限大。
mongo.connectTimeout=120000
# 最大等待连接的线程阻塞时间 默认是120000 ms (2 minutes).
mongo.maxWaitTime=120000
# 保持活动标志,控制是否有套接字保持活动超时 官方默认为true 且不建议禁用
mongo.socketKeepAlive=true
# 用于群集心跳的连接的套接字超时。
mongo.heartbeatConnectTimeout=120000
# socket超时时间
mongo.heartbeatSocketTimeout=120000
# 设置服务器选择超时(以毫秒为单位),它定义驱动程序在抛出异常之前等待服务器选择成功的时间。值为0表示如果没有可用的服务器,它将立即超时。负值意味着无限期等待
mongo.serverSelectionTimeout=120000
(3)springmvc.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-2.2.xsd">
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />
<context:component-scan base-package="test" annotation-config="true"></context:component-scan>
<context:property-placeholder location="resources/properties/mongodb-config.properties" />
<!--定义用于访问 MongoDB 的 MongoClient 实例-->
<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}"
heartbeat-connect-timeout="${mongo.heartbeatConnectTimeout}"
heartbeat-socket-timeout="${mongo.heartbeatSocketTimeout}"
server-selection-timeout="${mongo.serverSelectionTimeout}"
min-connections-per-host="${mongo.minConnectionsPerHost}"
/>
</mongo:mongo-client>
<!--定义用于连接到数据库的连接工厂-->
<mongo:db-factory id="mongoDbFactory" dbname="${mongo.dbname}" mongo-ref="mongoClient"/>
<!--实际操作 mongodb 的 template,在代码中注入。注意如果此处id不叫mongoTemplate。可能会导致使用Repositry的时候找不到,需要特殊映射-->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix">
<value>/resources/views/</value>
</property>
<!-- 后缀 -->
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
注①:properties文件放在了webapp下的resources文件夹里,之前开头加了classpath,怎么都读不到,去掉classpath就好了。
注②:mongo:定义这块,其实也可以用bean:定义,但是里面的属性参数不知道怎么写,具体可看这个博主的:
https://blog.csdn.net/richie12/article/details/89678888
注③:
mongo:options - 用于配置一些数据库连接设置信息
mongo:db-factory - 相当于Hibernate中的SessionFactory
mongoTemplate - 非常重要,整个与数据库的交互操作全是靠他,相当于Hibernate的HibernateTemplate
注④:如果要读取多个properties,需要加ignore-unresolvable=“true”
注⑤:2.x和3.x版本XML好多不一样,如下图。另外,spring-mongo-2.2.xsd一定要指定2.x,不然会默认用3.x的,这样使用xml元素会报错(奇葩的错误,我也搞不懂,不写好像是默认用3.2.2最新版本的)。
2、java代码
(1)TestController.java代码
package test;
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.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/testController")
public class TestController {
@Autowired
public ITestService testService;
@RequestMapping(value = "/helloWorld", method = RequestMethod.GET)
public String helloWorld() {
Query query=Query.query(Criteria.where("by").is("ggh"));
System.out.println(mongoTemplate.find(query,Test.class).get(0));
return "welcome";
}
//我们将MongoTemplate注入到MongoOperations ,因为MongoTemplate是MongoOperations 实现类,使用接口注入是一个好的做法
@Autowired
public MongoOperations mongoTemplate;
}
按道理有服务层和数据层代码,懒得写了,只是测试。。。
(1)Test.java代码
package test;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "ok")
public class Test {
@Id
private String id;
private String title;
private String description;
private String by;
private String url;
private String tags;
private String likes;
--省略get和set方法--
}
@Id - 用于字段级别,标记这个字段是一个主键,默认生成的名称是“_id”
@Document - 用于类,以表示这个类需要映射到数据库,您也可以使用collection指定映射到数据库的集合名称
@Field - 用于字段,并描述字段的名称,因为它将在MongoDB BSON文档中表示,允许名称与该类的字段名不同。
@Transient - 默认情况下所有的私有字段都映射到文档,该注解标识的字段从存储在数据库中的字段列中排除(即该字段不保存到 mongodb)
3、jsp代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
啊啊啊啊啊啊
</body>
</html>
遇到的坑
1、首先最大的坑就是需要 spring-data-commons.jar和slf4j-api.jar,网上教程基本是spring4.x和MongoDB整合的,很少spring5的,不知道为啥spring4.x不需要这两个jar包都可以跑起来。
2、第二坑就是spring-data-mongo和mongo-java-driver版本需要一一对应,不然报类找不到错误,这个搞了我好久
3、第三个坑就是mongo的xml配置,网上都是2.x和3.x的元素混在一起使用的,他们竟然不报错,还可以跑起来!!??真是不可思议。。。
总结
总算可以用了,应该是spring5.x太新,还没什么人用吧,网上资料不太全。。。
参考链接
[1] spring5整合mongodb4:https://blog.csdn.net/richie12/article/details/89678888
[2] mongodb-config.properties配置参数参考:https://www.cnblogs.com/jycboy/p/10077080.html
[3] 实体类注解说明:https://www.cnblogs.com/muxi0407/p/11750435.html
[4] spring-data-mongo官网:https://docs.spring.io/spring-data/mongodb
[5] maven搜索官网:https://search.maven.org/
[6] spring集成mongodb及基础使用:https://blog.csdn.net/u013190145/article/details/110847118