spring 于mongodb整合

本文介绍如何在Spring项目中配置并使用Spring Data MongoDB,包括依赖添加、配置文件设置及实体映射等,并展示了如何通过继承MongoRepository实现CRUD操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里我们用到的是spring-data中一个集成mongodb的项目,首先在maven中添加对它的依赖,这里我用的是1.0.0.M5版本
1 <!-- mongodb spring -->
2 <dependency>
3 <groupId>org.springframework.data</groupId>
4 <artifactId>spring-data-mongodb</artifactId>
5 <version>1.0.0.M5</version>
6 </dependency>

然后是配置文件

01 <?xmlversion="1.0"encoding="UTF-8"?>
02 <beansxmlns="http://www.springframework.org/schema/beans"
03 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"
04 xmlns:mongo="http://www.springframework.org/schema/data/mongo"
05 xsi:schemaLocation="http://www.springframework.org/schema/context
06 http://www.springframework.org/schema/context/spring-context-3.0.xsd
07 http://www.springframework.org/schema/data/mongo
08 http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
09 http://www.springframework.org/schema/beans
10 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
11 <context:property-placeholderlocation="classpath*:META-INF/mongodb/mongodb.properties"/>
12
13 <!-- 定义mongo对象,对应的是mongodb官方jar包中的Mongo,replica-set设置集群副本的ip地址和端口 -->
14 <mongo:mongoid="mongo"replica-set="localhost:27017">
15 <!-- 一些连接属性的设置 -->
16 <mongo:options
17 connections-per-host="${mongo.connectionsPerHost}"
18 threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
19 connect-timeout="${mongo.connectTimeout}"
20 max-wait-time="${mongo.maxWaitTime}"
21 auto-connect-retry="${mongo.autoConnectRetry}"
22 socket-keep-alive="${mongo.socketKeepAlive}"
23 socket-timeout="${mongo.socketTimeout}"
24 slave-ok="${mongo.slaveOk}"
25 write-number="1"
26 write-timeout="0"
27 write-fsync="true"/>
28 </mongo:mongo>
29
30 <!-- mongo的工厂,通过它来取得mongo实例,dbname为mongodb的数据库名,没有的话会自动创建 -->
31 <mongo:db-factorydbname="test"mongo-ref="mongo"/>
32
33 <!-- mongodb的主要操作对象,所有对mongodb的增删改查的操作都是通过它完成 -->
34 <beanid="mongoTemplate"class="org.springframework.data.mongodb.core.MongoTemplate">
35 <constructor-argname="mongoDbFactory"ref="mongoDbFactory"/>
36 </bean>
37
38 <!-- 映射转换器,扫描back-package目录下的文件,根据注释,把它们作为mongodb的一个collection的映射 -->
39 <mongo:mapping-converterbase-package="com.xxx.xxx.domain"/>
40
41 <!-- mongodb bean的仓库目录,会自动扫描扩展了MongoRepository接口的接口进行注入 -->
42 <mongo:repositoriesbase-package="com.xxx.xxx.persist.mongodb"/>
43
44 <!-- To translate any MongoExceptions thrown in @Repository annotated classes -->
45 <context:annotation-config/>
46
47 </beans>
这样基本配置就完成了


spring-data-mongodb中的实体映射是通过

MongoMappingConverter这个类实现的。它可以通过注释把

java类转换为mongodb的文档。
它有以下几种注释:
@Id - 文档的唯一标识,在mongodb中为ObjectId,它是唯一的,通过时间戳+机器标识+进程ID+自增计数器(确保同一秒内产生的Id不会冲突)构成。

@Document - 把一个java类声明为mongodb的文档,可以通

过collection参数指定这个类对应的文档。

@DBRef - 声明类似于关系数据库的关联关系。ps:暂不支持级联的保存功能,当你在本实例中修改了DERef对象里面的值时,单独保存本实例并不能保存DERef引用的对象,它要另外保存,如下面例子的Person和Account。

@Indexed - 声明该字段需要索引,建索引可以大大的提高查询效率。

@CompoundIndex - 复合索引的声明,建复合索引可以有效地提高多字段的查询效率。

@GeoSpatialIndexed - 声明该字段为地理信息的索引。

@Transient - 映射忽略的字段,该字段不会保存到

mongodb。

@PersistenceConstructor - 声明构造函数,作用是把从数据库取出的数据实例化为对象。该构造函数传入的值为从DBObject中取出的数据。

以下引用一个官方文档的例子:

Person类

01 @Document(collection="person")
02 @CompoundIndexes({
03 @CompoundIndex(name ="age_idx", def ="{'lastName': 1, 'age': -1}")
04 })
05 publicclassPerson<TextendsAddress> {
06
07 @Id
08 privateString id;
09 @Indexed(unique =true)
10 privateInteger ssn;
11 privateString firstName;
12 @Indexed
13 privateString lastName;
14 privateInteger age;
15 @Transient
16 privateInteger accountTotal;
17 @DBRef
18 privateList<Account> accounts;
19 privateT address;
20
21
22 publicPerson(Integer ssn) {
23 this.ssn = ssn;
24 }
25
26 @PersistenceConstructor
27 publicPerson(Integer ssn, String firstName, String lastName, Integer age, T address) {
28 this.ssn = ssn;
29 this.firstName = firstName;
30 this.lastName = lastName;
31 this.age = age;
32 this.address = address;
33 }
Account类
1 @Document
2 publicclassAccount {
3
4 @Id
5 privateObjectId id;
6 privateFloat total;
7
8 }

与HibernateRepository类似,通过继承MongoRepository接口,我们可以非常方便地实现对一个对象的增删改查,要使用Repository的功能,先继承MongoRepository<T, TD>接口,其中T为仓库保存的bean类,TD为该bean的唯一标识的类型,一般为ObjectId。之后在service中注入该接口就可以使用,无需实现里面的方法,spring会根据定义的规则自动生成。

例:

1 publicinterfacePersonRepositoryextends
2
3 MongoRepository<Person, ObjectId>{
4 //这里可以添加额外的查询方法
5
但是MongoRepository实现了的只是最基本的增删改查的功能,要想增加额外的查询方法,可以按照以下规则定义接口的方法。自定义查询方法,格式为“findBy+字段名+方法后缀”,方法传进的参数即字段的值,此外还支持分页查询,通过传进一个Pageable对象,返回Page集合。

例:

1 publicinterfacePersonRepositoryextends
2
3 MongoRepository<Person, ObjectId>{
4 //查询大于age的数据
5 publicPage<Product> findByAgeGreaterThan(intage,Pageable page) ;
6
下面是支持的查询类型,每三条数据分别对应:(方法后缀,方法例子,mongodb原生查询语句)

GreaterThan(大于)
findByAgeGreaterThan(int age)
{"age" : {"$gt" : age}}

LessThan(小于)
findByAgeLessThan(int age)
{"age" : {"$lt" : age}}

Between(在...之间)
findByAgeBetween(int from, int to)
{"age" : {"$gt" : from, "$lt" : to}}

IsNotNull, NotNull(是否非空)
findByFirstnameNotNull()
{"age" : {"$ne" : null}}

IsNull, Null(是否为空)
findByFirstnameNull()
{"age" : null}

Like(模糊查询)
findByFirstnameLike(String name)
{"age" : age} ( age as regex)

(No keyword) findByFirstname(String name)
{"age" : name}

Not(不包含)
findByFirstnameNot(String name)
{"age" : {"$ne" : name}}

Near(查询地理位置相近的)
findByLocationNear(Point point)
{"location" : {"$near" : [x,y]}}

Within(在地理位置范围内的)
findByLocationWithin(Circle circle)
{"location" : {"$within" : {"$center" : [ [x, y], distance]}}}

Within(在地理位置范围内的)
findByLocationWithin(Box box)
{"location" : {"$within" : {"$box" : [ [x1, y1], x2, y2]}}}

尽管以上查询功能已经很丰富,但如果还不能满足使用情况的话可以用一下方法---基于mongodb原本查询语句的查询方式。
例:在原接口中加入

1 @Query("{ 'name':{'$regex':?2,'$options':'i'}, sales': {'$gte':?1,'$lte':?2}}")
2 publicPage<Product> findByNameAndAgeRange(String name,doubleageFrom,doubleageTo,Pageable page);

注释Query里面的就是mongodb原来的查询语法,我们可以定义传进来的查询参数,通过坐标定义方法的参数。

还可以在后面指定要返回的数据字段,如上面的例子修改如下,则只通过person表里面的name和age字段构建person对象。

1 @Query(value="{ 'name':{'$regex':?2,'$options':'i'}, sales':{'$gte':?1,'$lte':?2}}",fields="{ 'name' : 1, 'age' : 1}")
2 publicPage<Product> findByNameAndAgeRange(String name,doubleageFrom,doubleageTo,Pageable page);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值