spring boot学习第九篇:操作mongo的集合和集合中的数据
1、安装好了Mongodb
参考:ubuntu安装mongod、配置用户访问、添删改查-CSDN博客
2、pom.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.hmblogs</groupId><artifactId>hmblogs</artifactId><version>0.0.1-SNAPSHOT</version><name>hmblogs</name><description>hmblogs</description><properties><java.version>8</java.version><druid.version>1.2.8</druid.version><log4jdbc.version>1.16</log4jdbc.version><es.version>7.9.2</es.version></properties><dependencies><!-- druid数据源驱动 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- mybatis --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--Mysql依赖包--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--lombok插件--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--监控sql日志--><dependency><groupId>org.bgee.log4jdbc-log4j2</groupId><artifactId>log4jdbc-log4j2-jdbc4.1</artifactId><version>${log4jdbc.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.9</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId></dependency><dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId></dependency><!-- high client--><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>${es.version}</version><exclusions><exclusion><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId></exclusion><exclusion><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId></exclusion></exclusions></dependency><!-- rest-high-level-client 依赖如下2个jar --><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>${es.version}</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>${es.version}</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
3、application.yml文件内容如下:
server:port: 8081servlet.context-path: /#配置数据源
spring:datasource:druid:db-type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpyurl: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:eladmin}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=falseusername: ${DB_USER:root}password: ${DB_PWD:密码}redis:host: localhostport: 6379password: hemingdatabase: 10data:mongodb:uri: mongodb://hmblogs:密码@43.138.0.199:27017/hmblogses:host: 43.138.0.199port: 9200scheme: http
4、UserEntity文件内容如下:
package com.hmblogs.backend.entity;import lombok.Data;import java.io.Serializable;@Data
public class UserEntity implements Serializable {private static final long serialVersionUID = -3258839839160856613L;private Long id;private String userName;private String passWord;//getter、setter省略
}
5、UserDaoImpl文件内容如下:
package com.hmblogs.backend.dao;import com.hmblogs.backend.entity.UserEntity;
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.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;@Component
public class UserDaoImpl implements UserDao {@Autowiredprivate MongoTemplate mongoTemplate;/*** 创建对象* @param user*/@Overridepublic void saveUser(UserEntity user) {mongoTemplate.save(user);}/*** 根据用户名查询对象* @param userName* @return*/@Overridepublic UserEntity findUserByUserName(String userName) {Query query=new Query(Criteria.where("userName").is(userName));UserEntity user = mongoTemplate.findOne(query , UserEntity.class);return user;}/*** 更新对象* @param user*/@Overridepublic void updateUser(UserEntity user) {Query query=new Query(Criteria.where("id").is(user.getId()));Update update= new Update().set("userName", user.getUserName()).set("passWord", user.getPassWord());//更新查询返回结果集的第一条mongoTemplate.updateFirst(query,update,UserEntity.class);//更新查询返回结果集的所有// mongoTemplate.updateMulti(query,update,UserEntity.class);}/*** 删除对象* @param id*/@Overridepublic void deleteUserById(Long id) {Query query=new Query(Criteria.where("id").is(id));mongoTemplate.remove(query,UserEntity.class);}
}
6、UserDao文件内容如下:
package com.hmblogs.backend.dao;import com.hmblogs.backend.entity.UserEntity;public interface UserDao {public void saveUser(UserEntity user);public UserEntity findUserByUserName(String userName);public void updateUser(UserEntity user);public void deleteUserById(Long id);}
7、测试验证类,内容如下:
package com.hmblogs.backend.util;import com.hmblogs.backend.dao.UserDao;
import com.hmblogs.backend.entity.UserEntity;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
public class UserDaoTest {@Autowiredprivate UserDao userDao;@Testpublic void testSaveUser() throws Exception {UserEntity user=new UserEntity();user.setId(2l);user.setUserName("小明");user.setPassWord("fffooo123");userDao.saveUser(user);}@Testpublic void findUserByUserName(){UserEntity user= userDao.findUserByUserName("小明");System.out.println("user is "+user);}@Testpublic void updateUser(){UserEntity user=new UserEntity();user.setId(2l);user.setUserName("天空");user.setPassWord("fffxxxx");userDao.updateUser(user);}@Testpublic void deleteUserById(){userDao.deleteUserById(1l);}}
7.1新增
执行报错testSaveUser()方法,执行报错:
org.springframework.data.mongodb.UncategorizedMongoDbException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='hmblogs', source='hmblogs', password=<hidden>, mechanismProperties=<hidden>}; nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='hmblogs', source='hmblogs', password=<hidden>, mechanismProperties=<hidden>}at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:140)at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2906)at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:557)at org.springframework.data.mongodb.core.MongoTemplate.saveDocument(MongoTemplate.java:1508)at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:1444)at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:1387)at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:1372)at com.hmblogs.backend.dao.UserDaoImpl.saveUser(UserDaoImpl.java:23)at com.hmblogs.backend.util.UserDaoTest.testSaveUser(UserDaoTest.java:24)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)at org.junit.runners.ParentRunner.run(ParentRunner.java:413)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='hmblogs', source='hmblogs', password=<hidden>, mechanismProperties=<hidden>}at com.mongodb.internal.connection.SaslAuthenticator.wrapException(SaslAuthenticator.java:273)at com.mongodb.internal.connection.SaslAuthenticator.getNextSaslResponse(SaslAuthenticator.java:137)at com.mongodb.internal.connection.SaslAuthenticator.access$100(SaslAuthenticator.java:48)at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:63)at com.mongodb.internal.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:57)at com.mongodb.internal.connection.SaslAuthenticator.doAsSubject(SaslAuthenticator.java:280)at com.mongodb.internal.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:57)at com.mongodb.internal.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:55)at com.mongodb.internal.connection.InternalStreamConnectionInitializer.authenticate(InternalStreamConnectionInitializer.java:207)at com.mongodb.internal.connection.InternalStreamConnectionInitializer.finishHandshake(InternalStreamConnectionInitializer.java:81)at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:185)at com.mongodb.internal.connection.UsageTrackingInternalConnection.open(UsageTrackingInternalConnection.java:54)at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.open(DefaultConnectionPool.java:538)at com.mongodb.internal.connection.DefaultConnectionPool$OpenConcurrencyLimiter.openWithConcurrencyLimit(DefaultConnectionPool.java:914)at com.mongodb.internal.connection.DefaultConnectionPool$OpenConcurrencyLimiter.openOrGetAvailable(DefaultConnectionPool.java:855)at com.mongodb.internal.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:173)at com.mongodb.internal.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:162)at com.mongodb.internal.connection.DefaultServer.getConnection(DefaultServer.java:101)at com.mongodb.internal.binding.ClusterBinding$ClusterBindingConnectionSource.getConnection(ClusterBinding.java:175)at com.mongodb.client.internal.ClientSessionBinding$SessionBindingConnectionSource.getConnection(ClientSessionBinding.java:188)at com.mongodb.internal.operation.OperationHelper.withSuppliedResource(OperationHelper.java:581)at com.mongodb.internal.operation.OperationHelper.lambda$withSourceAndConnection$3(OperationHelper.java:563)at com.mongodb.internal.operation.OperationHelper.withSuppliedResource(OperationHelper.java:589)at com.mongodb.internal.operation.OperationHelper.withSourceAndConnection(OperationHelper.java:562)at com.mongodb.internal.operation.MixedBulkWriteOperation.lambda$execute$3(MixedBulkWriteOperation.java:232)at com.mongodb.internal.async.function.RetryingSyncSupplier.get(RetryingSyncSupplier.java:65)at com.mongodb.internal.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:268)at com.mongodb.internal.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:84)at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:212)at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:1010)at com.mongodb.client.internal.MongoCollectionImpl.executeReplaceOne(MongoCollectionImpl.java:568)at com.mongodb.client.internal.MongoCollectionImpl.replaceOne(MongoCollectionImpl.java:551)at org.springframework.data.mongodb.core.MongoTemplate.lambda$saveDocument$18(MongoTemplate.java:1540)at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:555)... 39 more
Caused by: com.mongodb.MongoCommandException: Command failed with error 18 (AuthenticationFailed): 'Authentication failed.' on server 43.138.0.199:27017. The full response is {"ok": 0.0, "errmsg": "Authentication failed.", "code": 18, "codeName": "AuthenticationFailed"}at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:198)at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:418)at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:342)at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:96)at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:44)at com.mongodb.internal.connection.SaslAuthenticator.sendSaslStart(SaslAuthenticator.java:228)at com.mongodb.internal.connection.SaslAuthenticator.getNextSaslResponse(SaslAuthenticator.java:135)... 71 more
继续找下办法看怎么处理。
参考:org.springframework.data.mongodb.UncategorizedMongoDbException: Exception authenticating MongoCreden-CSDN博客
问题解决了,能正常保存了。
application.yml文件内容如下:
server:port: 8081servlet.context-path: /#配置数据源
spring:datasource:druid:db-type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpyurl: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:eladmin}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=falseusername: ${DB_USER:root}password: ${DB_PWD:密码保密}redis:host: localhostport: 6379password: hemingdatabase: 10data:mongodb:host: 43.138.0.199port: 27017username: hmblogspassword: 密码保密database: hmblogsauthentication-database: admines:host: 43.138.0.199port: 9200scheme: http
console截图如下:

在Robo 3T里面查看数据,有对应数据,集合不存在也自动创建了。

7.2查询
执行findUserByUserName(),根据查询条件查看单个数据:


7.3修改数据,
执行updateUser()方法,


在Robo 3T中查看数据,如下所示:

7.4删除数据,


查看数据,还是保留了id为2的数据。要删id为2的数据,则参数改成2

然后查看数据,该集合已经变成空的了。

7.5排序分页,用添加数据的方法执行5条数据后,分页查询数据以及根据查询条件分页查询数据,对数据排序,如下:
大于&&排序:
public List<UserEntity> findUserByCriteria(UserEntity user) {Query query=new Query(Criteria.where("id").gt(user.getId()));List<UserEntity> users = mongoTemplate.find(query , UserEntity.class);users.sort(new Comparator<UserEntity>() {@Overridepublic int compare(UserEntity o1, UserEntity o2) {return o1.getId().intValue()-o2.getId().intValue();}});return users;}
结果如下:

只查出了id>2的数据,且按id升序排序。
下面再看看,根据查询条件分页查询数据,id大于2,且查出第2页数据,每页2条记录,那就查出id=5和id=7的记录,同时要查出总数,便于页面分页。对分页之后得到的结果排序意义不大。
执行结果如下:

现贴出有新增和修改的代码,
新增了PageQuery代码如下:
package com.hmblogs.backend.dao;import lombok.Data;@Data
public class PageQuery<T> {private int pageNum;private int pageSize;private T criteria;
}
新增了PageResult代码如下:
package com.hmblogs.backend.dao;import lombok.Data;import java.util.List;@Data
public class PageResult<T> {private long totalRecord;private List<T> list;
}
UserDao类追加代码如下:
package com.hmblogs.backend.dao;import com.hmblogs.backend.entity.UserEntity;public interface UserDao {public void saveUser(UserEntity user);public UserEntity findUserByUserName(String userName);public void updateUser(UserEntity user);public void deleteUserById(Long id);public PageResult<UserEntity> findUserByCriteria(PageQuery<UserEntity> pageQuery);}
UserDaoImpl类追加代码如下,import块有改动,所以贴出该类的代码:
package com.hmblogs.backend.dao;import com.hmblogs.backend.entity.UserEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
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.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;import java.util.Comparator;
import java.util.List;@Component
public class UserDaoImpl implements UserDao {@Autowiredprivate MongoTemplate mongoTemplate;/*** 创建对象* @param user*/@Overridepublic void saveUser(UserEntity user) {mongoTemplate.save(user);}/*** 根据用户名查询对象* @param userName* @return*/@Overridepublic UserEntity findUserByUserName(String userName) {Query query=new Query(Criteria.where("userName").is(userName));UserEntity user = mongoTemplate.findOne(query , UserEntity.class);return user;}/*** 更新对象* @param user*/@Overridepublic void updateUser(UserEntity user) {Query query=new Query(Criteria.where("id").is(user.getId()));Update update= new Update().set("userName", user.getUserName()).set("passWord", user.getPassWord());//更新查询返回结果集的第一条mongoTemplate.updateFirst(query,update,UserEntity.class);//更新查询返回结果集的所有// mongoTemplate.updateMulti(query,update,UserEntity.class);}/*** 删除对象* @param id*/@Overridepublic void deleteUserById(Long id) {Query query=new Query(Criteria.where("id").is(id));mongoTemplate.remove(query,UserEntity.class);}@Overridepublic PageResult<UserEntity> findUserByCriteria(PageQuery<UserEntity> pageQuery) {int pageNum = pageQuery.getPageNum();int pageSize = pageQuery.getPageSize();UserEntity userEntityQuery = pageQuery.getCriteria();Query query = new Query(Criteria.where("id").gt(userEntityQuery.getId()));long count = mongoTemplate.count(query, UserEntity.class);Query queryList = query.skip((pageNum-1)*pageSize).limit(pageSize);List<UserEntity> users = mongoTemplate.find(queryList , UserEntity.class);PageResult<UserEntity> pageResult = new PageResult<UserEntity>();pageResult.setList(users);pageResult.setTotalRecord(count);return pageResult;}
}
UserDaoTest代码如下:
package com.hmblogs.backend.util;import com.hmblogs.backend.dao.PageQuery;
import com.hmblogs.backend.dao.PageResult;
import com.hmblogs.backend.dao.UserDao;
import com.hmblogs.backend.entity.UserEntity;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.util.List;@RunWith(SpringRunner.class)
@SpringBootTest
public class UserDaoTest {@Autowiredprivate UserDao userDao;@Testpublic void testSaveUser() throws Exception {UserEntity user=new UserEntity();user.setId(4l);user.setUserName("aa");user.setPassWord("bb");userDao.saveUser(user);}@Testpublic void findUserByUserName(){UserEntity user= userDao.findUserByUserName("小明");System.out.println("user is "+user);}@Testpublic void updateUser(){UserEntity user=new UserEntity();user.setId(2l);user.setUserName("天空");user.setPassWord("fffxxxx");userDao.updateUser(user);}@Testpublic void deleteUserById(){userDao.deleteUserById(2l);}@Testpublic void findUsersByCriteria(){UserEntity userQuery = new UserEntity();userQuery.setId(2l);PageQuery<UserEntity> pageQuery = new PageQuery<UserEntity>();pageQuery.setCriteria(userQuery);pageQuery.setPageNum(2);pageQuery.setPageSize(2);PageResult<UserEntity> user= userDao.findUserByCriteria(pageQuery);System.out.println("user is "+user);}
}
根据查询条件筛选数据、分页、查出符合查询条件的总数,都做到了,如果还要再加上要根据最后修改时间降序排序,最后修改的数据要放在第1页,很早之前修改的数据放在最后一页,这里可以理解为根据id降序排序,id值越大的说明越晚产生的,那就是查出id为3、4的记录了,而不是id为5、7的记录。
数据以及需求如下图所示:

但是mongoTemplate的API,没看到有sort的API,怎么办呢?搜资料发现,如下代码可以实现:
public PageResult<UserEntity> findUserByCriteria(PageQuery<UserEntity> pageQuery) {int pageNum = pageQuery.getPageNum();int pageSize = pageQuery.getPageSize();UserEntity userEntityQuery = pageQuery.getCriteria();Query query = new Query(Criteria.where("id").gt(userEntityQuery.getId()));long count = mongoTemplate.count(query, UserEntity.class);// 10. 分页// 11. 排序query.with(PageRequest.of(pageNum-1, pageSize,Sort.by(Sort.Order.desc("id"))));List<UserEntity> users = mongoTemplate.find(query , UserEntity.class);PageResult<UserEntity> pageResult = new PageResult<UserEntity>();pageResult.setList(users);pageResult.setTotalRecord(count);return pageResult;}
执行结果如下:

7.6模糊查询
public void querys() {String name = "a";String regex = String.format("%s%s%s", "^.*", name, ".*$");//采用正则表达式进行匹配Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);Query query = new Query(Criteria.where("userName").regex(pattern));List<UserEntity> users = mongoTemplate.find(query , UserEntity.class);System.out.println("user is "+users);}

7.7多条件一起查询
public void querys() {String name = "a";String regex = String.format("%s%s%s", "^.*", name, ".*$");//采用正则表达式进行匹配Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);Criteria criteria = Criteria.where("userName").regex(pattern);Query query = new Query(); //条件构建部分query.addCriteria(criteria);query.addCriteria(Criteria.where("passWord").is("bb"));List<UserEntity> users = mongoTemplate.find(query , UserEntity.class);System.out.println("user is "+users);}
userName包含a的,且passWord是bb的。

7.8 聚合
Student类代码如下:
package com.hmblogs.backend.entity;import lombok.Data;/*** mongo集合对应的类*/
@Data
public class Student {private Long id;private String name;private int age;private String sex;//getter、setter省略
}
StudentGroupResult代码如下:
package com.hmblogs.backend.entity;import lombok.Data;/*** 通过聚合查询的结果对应的类*/
@Data
public class StudentGroupResult {private String id;private int ageTotal;private String nameMax;
}
UserDao追加代码:
public void aggregate();
UserDaoImpl代码如下,所有的import(包含之前方法用到的import),和测试聚合的方法代码,如下:
package com.hmblogs.backend.dao;import com.hmblogs.backend.entity.Student;
import com.hmblogs.backend.entity.StudentGroupResult;
import com.hmblogs.backend.entity.UserEntity;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregationOptions;
@Component
public class UserDaoImpl implements UserDao {@Autowiredprivate MongoTemplate mongoTemplate;@Overridepublic void aggregate() {List<AggregationOperation> operations = Lists.newArrayList();Criteria criteria = new Criteria();// todo 增加过滤条件operations.add(Aggregation.match(criteria));GroupOperation groupOperation = new GroupOperation(Fields.fields("sex")).sum("age").as("ageTotal").max("name").as("nameMax");operations.add(groupOperation);Aggregation aggregation = Aggregation.newAggregation(operations).withOptions(newAggregationOptions().allowDiskUse(true).build());AggregationResults<StudentGroupResult> aggregationResults =mongoTemplate.aggregate(aggregation, "Student", StudentGroupResult.class);System.out.println(aggregationResults.getMappedResults());}
}
UserDaoTest追加代码如下:
@Testpublic void aggregate(){userDao.aggregate();}
运行效果如下:

7.9upsert
UserDaoImpl追加如下代码:
@Overridepublic void upsert() {Query query=new Query(Criteria.where("id").is(6));Update update= new Update().set("userName", "wangwu66").set("passWord", "pp66");//更新查询返回结果集的第一条mongoTemplate.upsert(query,update,"Student");}
这里的is(4)、is(6)分别表示修改、新增数据。
UserDao追加如下代码:
public void upsert();
UserDaoTest追加如下代码:
@Testpublic void upsert(){userDao.upsert();}
结果如下截图:

7.10根据二级属性值查询
7.10.1二级属性在JSONObject对象中的
db.userEntity.find({"comments.advantage":"人品不差"})

7.10.2二级属性在JSONArray数组中的情况
只是根据数组中的一个属性查询,可以像下面这样:
db.userEntity.find({"xueli":{"shuoshi":"qinghuadaxue"}})
但是如果2个属性一起查,这样就不行了。
那怎么写呢,2个属性一起查
db.userEntity.find({"xueli":{"$elemMatch":{"shuoshi":"qinghuadaxue","benke": "zhongnanlinyekejidaxue"}}})
网上说是这样,但是没达到效果

8、基于MongoRepository开发CRUD
User类代码如下所示:
package com.hmblogs.backend.entity;import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;/*** @author :heming* @description:TODO* @date :2024-02-04 14:26*/
@Data
@Document("User")
public class User {@Idprivate String id;private String name;private Integer age;private String email;private String createDate;}
UserRepository代码如下所示:
package com.hmblogs.backend.dao;import com.hmblogs.backend.entity.User;
import org.springframework.data.mongodb.repository.MongoRepository;//实现Mongodb的增删改查方法
public interface UserRepository extends MongoRepository<User,String> {
}
测试类代码如下所示:
package com.hmblogs.backend.util;import com.hmblogs.backend.dao.UserRepository;
import com.hmblogs.backend.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.*;import java.util.List;/*** @author :程序员徐大大* @description:TODO* @date :2022-04-08 20:16*/
@SpringBootTest
public class MongodbTest {//注入mongoTemplate@Autowiredprivate UserRepository userRepository;//添加@Testpublic void createUser() {User user = new User();user.setAge(20);user.setName("张三");user.setEmail("3332200@qq.com");User user1 = userRepository.save(user);}//查询所有@Testpublic void findUser() {List<User> userList = userRepository.findAll();System.out.println(userList);}//id查询@Testpublic void getById() {User user = userRepository.findById("65bf3089425b826e2b08cc4b").get();System.out.println(user);}//条件查询@Testpublic void findUserList() {User user = new User();user.setName("张三");user.setAge(20);Example<User> userExample = Example.of(user); //构建条件List<User> userList = userRepository.findAll(userExample);System.out.println(userList);}//模糊查询@Testpublic void findUsersLikeName() {//创建匹配器,即如何使用查询条件ExampleMatcher matcher = ExampleMatcher.matching() //构建对象.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改变默认字符串匹配方式:模糊查询.withIgnoreCase(true); //改变默认大小写忽略方式:忽略大小写User user = new User();user.setName("三");Example<User> userExample = Example.of(user, matcher);List<User> userList = userRepository.findAll(userExample);System.out.println(userList);}//分页查询@Testpublic void findUsersPage() {Sort sort = Sort.by(Sort.Direction.DESC, "age");
//0为第一页Pageable pageable = PageRequest.of(0, 10, sort);
//创建匹配器,即如何使用查询条件ExampleMatcher matcher = ExampleMatcher.matching() //构建对象.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改变默认字符串匹配方式:模糊查询.withIgnoreCase(true); //改变默认大小写忽略方式:忽略大小写User user = new User();user.setName("三");Example<User> userExample = Example.of(user, matcher);
//创建实例Example<User> example = Example.of(user, matcher);Page<User> pages = userRepository.findAll(example, pageable);System.out.println(pages);}//修改@Testpublic void updateUser() {User user = userRepository.findById("65bf3089425b826e2b08cc4b").get();user.setName("张三_1");user.setAge(25);user.setEmail("883220990@qq.com");user.setCreateDate("2024-02-04 14:42:00");User save = userRepository.save(user);System.out.println(save);}//删除@Testpublic void delete() {userRepository.deleteById("65bf3089425b826e2b08cc4b");}}
经过实际验证,都符合期望。
相关文章:
spring boot学习第九篇:操作mongo的集合和集合中的数据
1、安装好了Mongodb 参考:ubuntu安装mongod、配置用户访问、添删改查-CSDN博客 2、pom.xml文件内容如下: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns…...
momentJs推导日历组件
实现效果: 代码: 引入momentjs然后封装两个函数构建出基本数据结构 import moment from moment;// 某月有多少天 export const getEndDay (m) > m.daysInMonth();/*** description 获取本月空值数据* param { Date } year { } 年度* param { Number } month …...
Linux C/C++ 原始套接字:打造链路层ping实现
在C/C中,我们可以使用socket函数来创建套接字。我们需要指定地址族为AF_PACKET,协议为htons(ETH_P_ALL)来捕获所有传入和传出的数据包。 可以使用sendto和recvfrom函数来发送和接收数据包。我们需要构建一个合法的链路层数据包,在数据包的头…...
TCP 粘包/拆包
文章目录 概述粘包拆包发生场景解决TCP粘包和拆包问题的常见方法Netty对粘包和拆包问题的处理小结 概述 TCP的粘包和拆包问题往往出现在基于TCP协议的通讯中,比如RPC框架、Netty等 TCP 粘包/拆包 就是你基于 TCP 发送数据的时候,出现了多个字符串“粘”…...
【Spring Boot 3】应用启动执行特定逻辑
【Spring Boot 3】应用启动执行特定逻辑 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花…...
设计模式(行为型模式)观察者模式
目录 一、简介二、观察者模式2.1、事件接口及其实现2.2、观察者接口及其实现2.3、主题接口及其实现2.4、使用 三、优点与缺点 一、简介 观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象…...
Windows 版Oracle 数据库(安装)详细过程
首先到官网上去下载oracle64位的安装程序 第一步:将两个datebase文件夹解压到同一目录中。 当下载完成后,它里面是两个文件夹 win64_11gR2_database_1of2, win64_11gR2_database_2of2,我们需要把其中的一个database文件夹整合在一起(复制一个database文件夹到另一…...
编程实例分享,计费系统一定要安装灯光控制吗?佳易王计时计费管理系统软件V18.0教程说明
编程实例分享,计费系统一定要安装灯光控制吗?佳易王计时计费管理系统软件V18.0教程说明 一、前言 以下教程以 佳易王计时计费软件V18.0为例说明 1、该软件既可以接灯控,也可以不接灯控,如果接灯控,则点击开始计时的时…...
【webpack】优化提升
webpack优化提升 安装webpack相关内容向下兼容游览器-babel/polyfill进一步优化babel/polyfill模块联邦-共享模块如何提升构建性能通用环境下1,webpack更新到最新版本2,将loader应用于最少数量的必要模块3,引导(每个额外的loader/…...
视频无损放大修复工具Topaz Video AI 新手入门教程
想要自学Topaz Video AI ?Topaz Video AI 如何使用?这里给大家带来了视频无损放大修复工具Topaz Video AI 新手入门教程,快来看看吧! 下载:Topaz Video AI for mac 导入您的文件 有两种方法可以将文件导入 Topaz Vid…...
《向量数据库指南》——Milvus Cloud 「部署」:简化部署一直在路上
“docker-compose 能部署分布式吗?”"单机部署为什么还依赖这么多组件?"“大家 Milvus Cloud 集群部署有没有实践过比较好的方案?” 作为一个开源数据库,是否能够进行快速部署,是所有工作的前提。在简化部署的道路上,社区从来没有停止过脚步。2023 年,社区推…...
使用x86架构+Nvidia消费显卡12G显存,搭建智能终端,将大模型本地化部署,说不定是未来方向,开源交互机器人设计
1,大模型本地部署 视频说明地址: https://www.bilibili.com/video/BV1BF4m1u769/ 【创新思考】(1):使用x86架构Nvidia消费显卡12G显存,搭建智能终端,将大模型本地化部署,语音交互机…...
关于RabbitMQ面试题汇总
什么是消息队列?消息队列有什么用? 消息队列是一种在应用程序之间传递消息的通信机制。它是一种典型的生产者-消费者模型,其中生产者负责生成消息并将其发送到队列中,而消费者则从队列中获取消息并进行处理。消息队列的主要目的是…...
GoogleTest 单元测试
假设我们有两个函数 complexFunction 和 helperFunction,其中 complexFunction 调用了 helperFunction。我们将编写测试 complexFunction 的单元测试,并在调用 helperFunction 的地方打桩。 // 复杂函数示例 int helperFunction(int x) {return x * 2; …...
Mac利用brew安装mysql并设置初始密码
前言 之前一直是在windows上开发后段程序,所以只在windows上装mysql。(我记得linux只需要适应yum之类的命令即可) 另外, linux的移步 linux安装mysql (详细步骤,初次初始化,sql小例子,可视化操作客户端推荐) 好家伙,我佛了,写完当天网上发…...
R语言入门笔记2.2
ifelse语句 结构:ifelse(条件,表达式1,表达式2) #满足条件,则进入表达式1,否则为表达式2 例1: > a1 > ifelse(a<0,"a小于0",ifelse(a0,0,"a大于0")) [1] "a大于0"a1 - 这行代码给变量a…...
一般系统的请求认证授权思路【gateway网关+jwt+redis+请求头httpheader】
gateway:网关,我们都知道网关的作用就是对系统的所有请求,网关都会进行拦截,然后做一些操作(例如:设置每个请求的请求头httpHeader,身份认证等等)此时一般会使用到网关过滤器&#x…...
c# 正则表达式 帮助类
public class RegexHelper { /// <summary> /// 验证输入字符串是否与模式字符串匹配,匹配返回true /// </summary> /// <param name"input">输入字符串</param> /// <param nam…...
告别mPDF迎来TCPDF和中文打印遇到的问题
mPDF是一个用PHP编写的开源PDF生成库。它最初由Claus Holler创建,于2004年发布。原来用开源软件打印中文没有问题,最近发现新的软件包中mPDF被TCPDF代替了,当然如果只用西文的PDF是没有发现问题,但要打印中文就有点抓瞎了如图1&am…...
mysql 多数据源
依赖 <dependencies><!--mysql连接--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--多数据源--><dependency><g…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
