Springboot连接和操作mongoDB方式
作者:南熏门前一只喵
Spring boot是对Spring的进一步封装,旨在简化Spring的安装和配置过程。
我们知道使用Spring搭建项目环境,往往需要引用很多jar包,并随着业务的逐渐复杂,创建出很多的xml文件。
Spring boot封装了Spring集成的很多服务组件,并自动创建这些对象的实例,你只用将所需使用的服务组件的jar包引入即可快速构建开发环境。
Spring boot所集成的服务组件,可在官网找到,你可以勾选所使用的服务组件,并把相应maven 项目下载到本地。
Spring boot同样集成了对MongoDB等Nosql的支持,下面介绍通过Spring boot连接和操作MongoDB。
创建Spring boot项目
本文使用的IDE是idea,其Spring initializr是创建Spring Boot项目的快速可视化组件,当然你也可以构建maven项目,然后在Spring boot官网将相关pom引入。
新建Spring boot项目,输入spring boot组件自动配置网址,点击next。
输入maven项目的的相关信息,并选择jdk版本。
选择需要的服务组件。
创建出的Spring boot的项目是个空的maven项目,pom内包含需要的jar包。
Spring boot连接mongoDB
Spring data提供了操作多种数据库的支持,其api简洁,调用方便。我们使用Spring data进行MongoDB连接。
在此介绍两种连接mongodb的方式。
Spring boot有意简化甚至消除原生Spring框架的xml配置,所以spring boot项目推崇尽量不使用xml配置文件进行bean的管理。
第一种方式是使用properties进行mongoDB的连接配置
在application.properties中进行mongoDB连接字符串配置,org.springframework.boot.autoconfigure.mongo提供了对mongoDB连接字符串的配置支持。我们对指定属性进行配置即可。
注意mongo 2.4以上版本已经不支持如下配置了。
spring.data.mongodb.host=127.0.0.1 spring.data.mongodb.port=27017 spring.data.mongodb.username=root spring.data.mongodb.password=root spring.data.mongodb.database=gis
2.4以上版本使用如下连接配置:
spring.data.mongodb.uri=mongodb://root(userName):root(password)@localhost(ip地址):27017(端口号)/gis(collections/数据库)
注意:
如果连接时mongo报错ASL SCRAM-SHA-1 authentication failed for XXXX on xxx from client xxxx ; UserNotFound: Could not find user xxx 或者java后台报类似错误com.mongodb.MongoCommandException: Command failed with error 18 (AuthenticationFailed): 'Authentication failed.'
原因有可能是用户名密码错误,或者需要更改配置通过系统授权数据库区进行授权然后再去访问需要操作的数据库。
添加配置如下:
spring.data.mongodb.database=gis(访问的目标数据库) spring.data.mongodb.authentication-database=admin(mongo自己的管理用户账号的数据库)
yml配置文件内容如下:
spring: data: mongodb: database: gis authentication-database: admin uri: mongodb://root(userName):root(password)@localhost(ip地址):27017(端口号)
创建数据库操作测试类。
@Component public class DBDaoTest { @Autowired private MongoTemplate mongoTemplate; public void save(Polygon polygon){ mongoTemplate.save(polygon); } public void saveRegions(List<GisRegion> gisRegionList){ mongoTemplate.insert(gisRegionList,GisRegion.class); } public <T> T findById(Class<T> entityClass, String id) { return mongoTemplate.findById(id, entityClass); } public <T> List<T> findAll(Class<T> entityClass) { return mongoTemplate.findAll(entityClass); } public <T> void remove(T entity) { mongoTemplate.remove(entity); } public <T> void add(T entity) { mongoTemplate.insert(entity); } public <T> void addAll(List<T> entity) { mongoTemplate.insertAll(entity); } public <T> void saveOrUpdate(T entity) { mongoTemplate.save(entity); } public <T> T findOne(Class<T> entityClass) { return mongoTemplate.findOne(new Query(), entityClass); } public List<Polygon> findIntersective(GeoJson geoJson){ Query query=new Query(Criteria.where("geometry").intersects(geoJson)); List<Polygon> list=mongoTemplate.find(query,Polygon.class); return list; } public boolean isExistIntersective(GeoJson geoJson){ Query query=new Query(Criteria.where("geometry").intersects(geoJson).and("_id").is(100000)); boolean res=mongoTemplate.exists(query,GisRegion.class); return res; } }
org.springframework.data.mongodb.core包的MongoTemplate类提供对mongodb的所有操作方法,并且会自动装配连接数据库的MongoDbFactory类对象,我们在application.properties中定义了MongoDbFactory对象所需要的参数,Spring boot会自动帮我们创建该对象供MongoTemplate使用,如果我们没有指定连接字符串,Spring boot在@Autowired自动装配MongoTemplate对象时,会默认使用127.0.0.1:27017地址、test数据库和无密码访问方式。
更多数据库操作方式,请查看MongoTemplate类的具体内容。
第二种方式是创建配置类进行mongoDB的连接配置
在maven resource文件夹下新建database.properties文件,定义数据库连接字符串。
mongodb.uri=127.0.0.1:27017 mongodb.username=root mongodb.password=root mongodb.schema=gis
考虑在项目实际开发过程中经常会切换环境,所以可以采用引用外部配置参数的办法,Spring boot在propertis文件中使用@…@占位符指定外部参数。
在pom文件profile中定义外部参数,供propertis文件引用。
pom.xml的profile文件配置如下:
<project> ... <profiles> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <db.mongo.server>127.0.0.1:27017</db.mongo.server> <db.mongo.schema>gis</db.mongo.schema> <db.mongo.user>root</db.mongo.user> <db.mongo.password>root</db.mongo.password> </properties> </profile> </profiles> </project>
database.properties文件:
#mongodb.uri=@db.mongo.server@ #mongodb.username=@db.mongo.user@ #mongodb.password=@db.mongo.password@ #mongodb.schema=@db.mongo.schema@
创建MongoDBConfig类,实例化MongoDbFactory bean:
@Configuration //等价于XML中配置bean @PropertySource(value = "classpath:database.properties",ignoreResourceNotFound = true) public class MongoDBConfig { @Value("${mongodb.schema}") private String databaseName; @Value("${mongodb.uri}") private String uri; @Value("${mongodb.username}") private String userName; @Value("${mongodb.password}") private String password; @Bean public MongoDbFactory mongoDbFactory() throws UnknownHostException { String uriStr="mongodb://"+userName+":"+password+"@"+uri+"/"+databaseName; System.out.println(uriStr); MongoClientURI mongoClientURI=new MongoClientURI(uriStr); MongoDbFactory mongoDbFactory=new SimpleMongoDbFactory(mongoClientURI); return mongoDbFactory; } }
Spring框架会在@Autowired自动装配MongoTemplate时,使用该MongoDbFactory bean。
spring boot操作mongo时添加日志查看mongodb执行语句
spring boot通过spring data项目与mongo的交互,提供了很多函数封装,方便用户执行操作,故不需再去写很多原生js代码段操作mongo。
由于进行封装,导致我们无法在mongo的执行日志下看到转义的js执行语句,导致复杂的查询无法对语句的性能和执行细节进行分析,对于不熟悉spring data api的用户,编写的交互代码往往会浪费性能甚至无法得到正确结果。对此在程序执行时,添加日志详情是必要的。
spring boot自身集成了logback的日志支持,只需在相应properties或yml进行配置即可。开启spring data操作mongo的日志支持,
yml示例如下:
logging: level: org.springframework.data.mongodb.core: DEBUG
properties示例如下:
logging.level.org.springframework.data.mongodb.core = DEBUG
可看到执行mongo操作时日志详情示例
如下所示:
2019-07-08 19:46:56.663 INFO 32616 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=consumer-2, groupId=group1] Discovered group coordinator 172.28.15.45:9092 (id: 2147483647 rack: null)
2019-07-08 19:46:56.665 INFO 32616 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=consumer-2, groupId=group1] Revoking previously assigned partitions []
2019-07-08 19:46:56.666 INFO 32616 --- [ntainer#0-0-C-1] o.s.k.l.KafkaMessageListenerContainer : partitions revoked: []
2019-07-08 19:46:56.666 INFO 32616 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=consumer-2, groupId=group1] (Re-)joining group
2019-07-08 19:46:56.668 DEBUG 32616 --- [ main] o.s.data.mongodb.core.MongoTemplate : Executing aggregation: [ { "$match" : { "$or" : [ { "type" : ""} , { "type" : null }]}} , { "$group" : { "_id" : "$_id" , "count" : { "$sum" : 1}}} , { "$group" : { "_id" : "$count" , "sum" : { "$sum" : "$count"}}}] in collection osgiSample
2019-07-08 19:46:56.691 INFO 32616 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=consumer-2, groupId=group1] Successfully joined group with generation 143
2019-07-08 19:46:56.692 INFO 32616 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=consumer-2, groupId=group1] Setting newly assigned partitions [group1Topic-0]
2019-07-08 19:46:56.700 INFO 32616 --- [ntainer#0-0-C-1] o.s.k.l.KafkaMessageListenerContainer : partitions assigned: [group1Topic-0]
2019-07-08 19:46:56.774 INFO 32616 --- [ main] org.mongodb.driver.connection : Opened connection [connectionId{localValue:2, serverValue:24498}] to 172.28.13.215:20036
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。