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");
    }

}

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

相关推荐
Joyner201827 分钟前
【Linux】ubuntu通过远程命令行启动桌面应用
linux·服务器·ubuntu
Eric.Lee202137 分钟前
ubuntu paddle ocr 部署bug问题解决
ubuntu·ocr·paddle
御风_212 小时前
Linux——字符设备驱动控制LED
linux·ubuntu·linux驱动
明 庭10 小时前
Ubuntu下通过Docker部署NGINX服务器
服务器·ubuntu·docker
猿小蔡-Cool10 小时前
ubuntu20.04安装imwheel实现鼠标滚轮调速
ubuntu
过过过呀Glik10 小时前
在 Ubuntu 上安装 MySQL 的详细指南
mysql·ubuntu
PyAIGCMaster12 小时前
ubuntu装P104驱动
linux·运维·ubuntu
zzzhpzhpzzz12 小时前
Ubuntu如何查看硬件型号
linux·运维·ubuntu
o(╥﹏╥)13 小时前
linux(ubuntu )卡死怎么强制重启
linux·数据库·ubuntu·系统安全
娶不到胡一菲的汪大东13 小时前
Ubuntu概述
linux·运维·ubuntu