config.properties

#mongodbsettingmongo.host=127.0.0.1mongo.port=27017mongo.connectionsPerHost=100mongo.threadsAllowedToBlockForConnectionMultiplier=50mongo.connectTimeout=1000mongo.maxWaitTime=1500mongo.autoConnectRetry=truemongo.socketKeepAlive=truemongo.socketTimeout=0mongo.slaveOk=true


spring_mongo.xml

<!--引入配置属性文件--><context:property-placeholderlocation="classpath:db.properties"/><!--mongodb配置--><mongo:mongoid="mongo"replica-set="${mongo.replica-set}"write-concern="SAFE"><mongo:optionsconnections-per-host="${mongo.connectionsPerHost}"threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"connect-timeout="${mongo.connectTimeout}"max-wait-time="${mongo.maxWaitTime}"auto-connect-retry="${mongo.autoConnectRetry}"socket-keep-alive="${mongo.socketKeepAlive}"socket-timeout="${mongo.socketTimeout}"slave-ok="${mongo.slaveOk}"write-number="1"write-timeout="0"write-fsync="true"/></mongo:mongo><!--mongo的工厂,通过它来取得mongo实例,dbname为mongodb的数据库名,没有的话会自动创建--><mongo:db-factoryid="mongoDbFactory"dbname="uba"mongo-ref="mongo"/><!--读写分离级别配置--><!--首选主节点,大多情况下读操作在主节点,如果主节点不可用,如故障转移,读操作在从节点。--><beanid="primaryPreferredReadPreference"class="com.mongodb.TaggableReadPreference.PrimaryPreferredReadPreference"></bean><!--最邻近节点,读操作在最邻近的成员,可能是主节点或者从节点。--><beanid="nearestReadPreference"class="com.mongodb.TaggableReadPreference.NearestReadPreference"></bean><!--从节点,读操作只在从节点,如果从节点不可用,报错或者抛出异常。存在的问题是secondary节点的数据会比primary节点数据旧。--><beanid="secondaryReadPreference"class="com.mongodb.TaggableReadPreference.SecondaryReadPreference"></bean><!--优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据--><beanid="secondaryPreferredReadPreference"class="com.mongodb.TaggableReadPreference.SecondaryPreferredReadPreference"></bean><!--mongodb的主要操作对象,所有对mongodb的增删改查的操作都是通过它完成--><beanid="mongoTemplate"class="org.springframework.data.mongodb.core.MongoTemplate"><constructor-argname="mongoDbFactory"ref="mongoDbFactory"/><propertyname="readPreference"ref="primaryPreferredReadPreference"/></bean><!--映射转换器,扫描back-package目录下的文件,根据注释,把它们作为mongodb的一个collection的映射--><mongo:mapping-converterbase-package="dev.lzq.uba.mongo.model"/><!--mongodbbean的仓库目录,会自动扫描扩展了MongoRepository接口的接口进行注入--><mongo:repositoriesbase-package="dev.lzq.uba.mongo.dao"/>


entity

@Document(collection="user")publicclassUser{@Idprivateintid;privateStringname;privateintage;privateStringcity;privateStringmote;publicintgetId(){returnid;}publicvoidsetId(intid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.age=age;}publicStringgetCity(){returncity;}publicvoidsetCity(Stringcity){this.city=city;}publicStringgetMote(){returnmote;}publicvoidsetMote(Stringmote){this.mote=mote;}}


dao配置

publicinterfaceMGUserDaoextendsMongoRepository<User,ObjectId>{/***方法名的严格遵守规定*@paramage*@parampage*@return*/publicPage<User>findByAgeGreaterThan(intage,Pageablepage);/***有@Query声明查询,方法名不需要严格遵守规定*@paramname*@paramageFrom*@paramageTo*@parampageable*@return*/@Query("{'name':{'$regex':?0},'age':{'$gte':?1,'$lte':?2}}")publicPage<User>findByNameAndAgeRange(Stringname,intageFrom,intageTo,Pageablepageable);@Query("{?0:?1}")publicList<User>findByAttribute(Stringkey,Stringvalue);}


dao层的使用

MongoRepository实现了的只是最基本的增删改查的功能,要想增加额外的查询方法,可以按照以下规则定义接口的方法。自定义查询方法,格式为“findBy+字段名+方法后缀”,方法传进的参数即字段的值,此外还支持分页查询,通过传进一个Pageable对象,返回Page集合。例如:

//查询大于age的数据publicPage<Product>findByAgeGreaterThan(intage,Pageablepage);

下面是支持的查询类型,每三条数据分别对应:(方法后缀,方法例子,mongodb原生查询语句)

GreaterThan(大于)findByAgeGreaterThan(intage){"age":{"$gt":age}}LessThan(小于)findByAgeLessThan(intage){"age":{"$lt":age}}Between(在...之间)findByAgeBetween(intfrom,intto){"age":{"$gt":from,"$lt":to}}IsNotNull,NotNull(是否非空)findByFirstnameNotNull(){"age":{"$ne":null}}IsNull,Null(是否为空)findByFirstnameNull(){"age":null}Like(模糊查询)findByFirstnameLike(Stringname){"age":age}(ageasregex)(Nokeyword)findByFirstname(Stringname){"age":name}Not(不包含)findByFirstnameNot(Stringname){"age":{"$ne":name}}Near(查询地理位置相近的)findByLocationNear(Pointpoint){"location":{"$near":[x,y]}}Within(在地理位置范围内的)findByLocationWithin(Circlecircle){"location":{"$within":{"$center":[[x,y],distance]}}}Within(在地理位置范围内的)findByLocationWithin(Boxbox){"location":{"$within":{"$box":[[x1,y1],x2,y2]}}}


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

例一:在原接口中加入,注释Query里面的就是mongodb原来的查询语法,我们可以定义传进来的查询参数,通过坐标定义方法的参数。

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

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

@Query(value="{'name':{'$regex':?2,'$options':'i'},sales':{'$gte':?1,'$lte':?2}}",fields="{'name':1,'age':1}")publicPage<Product>findByNameAndAgeRange(Stringname,doubleageFrom,doubleageTo,Pageablepage);