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: 8081
  servlet.context-path: /

#配置数据源
spring:
  datasource:
    druid:
      db-type: com.alibaba.druid.pool.DruidDataSource
      driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
      url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:eladmin}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
      username: ${DB_USER:root}
      password: ${DB_PWD:密码}
  redis:
    host: localhost
    port: 6379
    password: heming
    database: 10
  data:
    mongodb:
      uri: mongodb://hmblogs:密码@43.138.0.199:27017/hmblogs

es:
  host: 43.138.0.199
  port: 9200
  scheme: 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 {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 创建对象
     * @param user
     */
    @Override
    public void saveUser(UserEntity user) {
        mongoTemplate.save(user);
    }

    /**
     * 根据用户名查询对象
     * @param userName
     * @return
     */
    @Override
    public UserEntity findUserByUserName(String userName) {
        Query query=new Query(Criteria.where("userName").is(userName));
        UserEntity user =  mongoTemplate.findOne(query , UserEntity.class);
        return user;
    }

    /**
     * 更新对象
     * @param user
     */
    @Override
    public 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
     */
    @Override
    public 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 {

    @Autowired
    private UserDao userDao;

    @Test
    public void testSaveUser() throws Exception {
        UserEntity user=new UserEntity();
        user.setId(2l);
        user.setUserName("小明");
        user.setPassWord("fffooo123");
        userDao.saveUser(user);
    }

    @Test
    public void findUserByUserName(){
        UserEntity user= userDao.findUserByUserName("小明");
        System.out.println("user is "+user);
    }

    @Test
    public void updateUser(){
        UserEntity user=new UserEntity();
        user.setId(2l);
        user.setUserName("天空");
        user.setPassWord("fffxxxx");
        userDao.updateUser(user);
    }

    @Test
    public 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: 8081
  servlet.context-path: /

#配置数据源
spring:
  datasource:
    druid:
      db-type: com.alibaba.druid.pool.DruidDataSource
      driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
      url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:eladmin}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
      username: ${DB_USER:root}
      password: ${DB_PWD:密码保密}
  redis:
    host: localhost
    port: 6379
    password: heming
    database: 10
  data:
    mongodb:
      host: 43.138.0.199
      port: 27017
      username: hmblogs
      password: 密码保密
      database: hmblogs
      authentication-database: admin

es:
  host: 43.138.0.199
  port: 9200
  scheme: 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>() {
            @Override
            public 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 {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 创建对象
     * @param user
     */
    @Override
    public void saveUser(UserEntity user) {
        mongoTemplate.save(user);
    }

    /**
     * 根据用户名查询对象
     * @param userName
     * @return
     */
    @Override
    public UserEntity findUserByUserName(String userName) {
        Query query=new Query(Criteria.where("userName").is(userName));
        UserEntity user =  mongoTemplate.findOne(query , UserEntity.class);
        return user;
    }

    /**
     * 更新对象
     * @param user
     */
    @Override
    public 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
     */
    @Override
    public void deleteUserById(Long id) {
        Query query=new Query(Criteria.where("id").is(id));
        mongoTemplate.remove(query,UserEntity.class);
    }

    @Override
    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);
        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 {

    @Autowired
    private UserDao userDao;

    @Test
    public void testSaveUser() throws Exception {
        UserEntity user=new UserEntity();
        user.setId(4l);
        user.setUserName("aa");
        user.setPassWord("bb");
        userDao.saveUser(user);
    }

    @Test
    public void findUserByUserName(){
        UserEntity user= userDao.findUserByUserName("小明");
        System.out.println("user is "+user);
    }

    @Test
    public void updateUser(){
        UserEntity user=new UserEntity();
        user.setId(2l);
        user.setUserName("天空");
        user.setPassWord("fffxxxx");
        userDao.updateUser(user);
    }

    @Test
    public void deleteUserById(){
        userDao.deleteUserById(2l);
    }

    @Test
    public 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 {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public 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追加代码如下:

复制代码
@Test
    public void aggregate(){
        userDao.aggregate();
    }

运行效果如下:

7.9upsert

UserDaoImpl追加如下代码:

复制代码
@Override
    public 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追加如下代码:

复制代码
@Test
    public 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 {
    @Id
    private 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
    @Autowired
    private UserRepository userRepository;

    //添加
    @Test
    public void createUser() {
        User user = new User();
        user.setAge(20);
        user.setName("张三");
        user.setEmail("3332200@qq.com");
        User user1 = userRepository.save(user);
    }

    //查询所有
    @Test
    public void findUser() {
        List<User> userList = userRepository.findAll();
        System.out.println(userList);
    }

    //id查询
    @Test
    public void getById() {
        User user = userRepository.findById("65bf3089425b826e2b08cc4b").get();
        System.out.println(user);
    }

    //条件查询
    @Test
    public 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);
    }

    //模糊查询
    @Test
    public 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);
    }

    //分页查询
    @Test
    public 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);
    }

    //修改
    @Test
    public 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);
    }

    //删除
    @Test
    public void delete() {
        userRepository.deleteById("65bf3089425b826e2b08cc4b");
    }

}

经过实际验证,都符合期望。

相关推荐
欧云服务器3 天前
怎么让脚本命令可以同时在centos、debian、ubuntu执行?
ubuntu·centos·debian
智渊AI3 天前
Ubuntu 20.04/22.04 下通过 NVM 安装 Node.js 22(LTS 稳定版)
ubuntu·node.js·vim
The️4 天前
Linux驱动开发之Read_Write函数
linux·运维·服务器·驱动开发·ubuntu·交互
再战300年4 天前
Samba在ubuntu上安装部署
linux·运维·ubuntu
qwfys2004 天前
How to install golang 1.26.0 to Ubuntu 24.04
ubuntu·golang·install
木尧大兄弟4 天前
Ubuntu 系统安装 OpenClaw 并接入飞书记录
linux·ubuntu·飞书·openclaw
小虾爬滑丫爬4 天前
ubuntu上设置Tomcat 开机启动
ubuntu·tomcat·开机启动
老师用之于民4 天前
【DAY25】线程与进程通信:共享内存、同步机制及实现方案
linux·c语言·ubuntu·visual studio code
小虾爬滑丫爬4 天前
Ubuntu 上设置防火墙
ubuntu·防火墙
林开落L4 天前
解决云服务器内存不足:2 分钟搞定 Ubuntu swap 交换区配置(新手友好版)
运维·服务器·ubuntu·swap交换区