spring boot中使用mongodb完成基本增删改查

添加依赖:

<?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 http://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.1.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hf</groupId>
    <artifactId>mongodemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mongodemo</name>
    <description>spring boot mongo</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--mongodb依赖-->
        <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>

在application.properties中配置连接mongodb

#配置mongodb,用户名和账号为root:root,端口为默认端口:27017,连接的数据库为: runoob
spring.data.mongodb.uri=mongodb://root:root@localhost:27017/runoob

新建实体,用来作为保存到mongo中的数据

package com.hf.mongodemo.model;

import lombok.Data;
import lombok.ToString;

import java.io.Serializable;

/**
 * @Description:
 * @Date: 2019/2/15
 * @Auther: 
 */
@Data
@ToString
public class User implements Serializable {
    private Long id;
    private String userName;
    private String passWord;
}

创建操作mongodb的接口:

package com.hf.mongodemo.dao;

import com.hf.mongodemo.model.User;

/**
 * @Description:
 * @Date: 2019/2/15
 * @Auther: 
 */
public interface UserDao {
     void saveUser(User user);
     User findUserByUserName(String userName);
     void updateUser(User user);
     void deleteUserById(Long id);
}

接口实现类,主要是通过MongoTemplate来实现的;

package com.hf.mongodemo.dao.impl;

import com.hf.mongodemo.dao.UserDao;
import com.hf.mongodemo.model.User;
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.Repository;

/**
 * @Description:
 * @Date: 2019/2/15
 * @Auther: 
 */
@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void saveUser(User user) {
         /**指定文档数据保存到集合user中去**/
        mongoTemplate.save(user,"user");
        System.out.println("对象保存成功了!");
    }

    @Override
    public User findUserByUserName(String userName) {
        Query query = new Query(Criteria.where("userName").is(userName));
        User user = mongoTemplate.findOne(query, User.class);
        System.out.println(user);
        return user;
    }

    @Override
    public void updateUser(User 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,User.class);
        //更新查询返回结果集的所有
        //mongoTemplate.updateMulti(query,update,User.class);
    }

    @Override
    public void deleteUserById(Long id) {
        Query query = new Query(Criteria.where("id").is(id));
        mongoTemplate.remove(query,User.class);
    }
}

在测试类中测试:

package com.hf.mongodemo;

import com.hf.mongodemo.dao.UserDao;
import com.hf.mongodemo.model.User;
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 MongodemoApplicationTests {

    @Test
    public void contextLoads() {
    }

    @Autowired
    private UserDao userDao;

    @Test
    public void testSaveUser(){
        User user=new User();
        user.setId(1L);
        user.setUserName("小红");
        user.setPassWord("hello world");
        userDao.saveUser(user);
    }

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

    @Test
    public void updateUser(){
        User user=new User();
        user.setId(1L);
        user.setUserName("yuyuyu");
        user.setPassWord("hahah");
        userDao.updateUser(user);
    }

    @Test
    public void deleteUserById(){
        userDao.deleteUserById(1L);
    }


}

操作之前我们先查看user集合中的数据为空:(我使用的是compass来查看的,也可以通过命令行来查看)

我们执行新增操作:

可以看到执行成功了,再次查看集合中的数据:

可以看到数据新增成功了,但是发现多了一个字段 : _class,并且值为我们的实体类的全路径,这是什么原因呢??

原因是:我们使用的是spring-data来操作mongodb的,会默认在新增对象的时候添加_class属性,目的是:当我们新增的实体类继承了其他的实体类的时候,有这个_class属性就可以转换为具体的子类,如果没有这个属性,那么在转换的时候就只会转换为他的父类.

如果需要去除这个_class属性,可以使用增加配置类/xml的方式来实现,这里之写出增加配置类的方式;

新建一个配置类,如下:

package com.hf.mongodemo.config;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

/**
 * @Description:配置MappingMongoConverter,目的是去除mongo保存对象的时候,自动添加_class属性
 * @Date: 2019/2/15
 * @Auther:
 */
@Configuration
public class SpringMongoConfig {

    @Bean
    public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context, BeanFactory beanFactory) {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
        try {
            mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));
        } catch (NoSuchBeanDefinitionException ignore) {
        }
        // Don't save _class to mongo,将DefaultMongoTypeMapper中的typeKey设为null,去除自动添加_class属性到文档中去
        mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return mappingConverter;
    }
}

删除掉之前的数据,再次新增数据,得到的结果如下:

可以看到_class属性已经没有添加到文档中去了.

下面我们针对有无_class属性的测试:

新建一个实体类: Person,该类继承User

package com.hf.mongodemo.model;

import lombok.Data;
import lombok.ToString;

import java.io.Serializable;

/**
 * @Description:
 * @Date: 2019/2/15
 * @Auther: wm yu
 */
@Data
@ToString
public class Person extends User implements Serializable {
   private String name;
   private int age;
}

注释掉,去除_class的配置类,也就是注释掉:SpringMongoConfig这个类

重新修改保存的测试方法,如下:

@Test
    public void testSaveUser(){
        User user=new User();
        user.setId(1L);
        user.setUserName("小红");
        user.setPassWord("hello world");
        userDao.saveUser(user);

        Person person = new Person();
        person.setId(2L);
        person.setPassWord("111");
        person.setUserName("xixi");
        person.setAge(11);
        person.setName("zhang");
        userDao.saveUser(person);
    }

增加了person对象的保存,清空掉user集合中的文档,执行保存方法,查看数据如下:

可以看到,有_class的文档将兑现所属的类都标出来了,那么我们测试一下

执行下面的方法

  @Test
    public void findUserByUserName(){
        User user= userDao.findUserByUserName("xixi");

        System.out.println("user is "+user + ",得到的对象的类型是:" + user.getClass());
    }

结果如下:

执行下面的方法:

 @Test
    public void findUserByUserName(){
        User user= userDao.findUserByUserName("小红");

        System.out.println("user is "+user + ",得到的对象的类型是:" + user.getClass());
    }

结果如下:

可以看到,对象所属的类是正确的,这个时候,我们在配置去除_class的配置类

清空user集合中的文档,重新数据到mongodb

查看数据

没有了_class属性

执行下面代码

  @Test
    public void findUserByUserName(){
        User user= userDao.findUserByUserName("xixi");

        System.out.println("user is "+user + ",得到的对象的类型是:" + user.getClass());
    }

结果如下:

xixi查出来的对象应该是属于类Person的,但是得到的结果却是User(Person的父类),得到了和预期不同的结果

那么我们再接着测试下面的:

执行方法

 @Test
    public void findUserByUserName(){
        User user= userDao.findUserByUserName("小红");

        System.out.println("user is "+user + ",得到的对象的类型是:" + user.getClass());
    }

结果:

这个结果就是正确的.

那么得出的结论就是:当去除了_class属性后,查询出来的对象类型都是其父类,而不能具体到期真实的子类了,这就是spring-data自动添加_class属性到文档中的作用了....

猜你喜欢

转载自blog.csdn.net/qq_42151769/article/details/87364056