SpringBoot系列之Spring Data MongoDB教程

x33g5p2x  于2022-02-07 转载在 Go  
字(12.6k)|赞(0)|评价(0)|浏览(281)

SpringBoot系列之Spring Data MongoDB教程

1、MongoDB下载安装

因为没有买linux服务器,所以本博客只安装window来学习,可以点击官网下载链接进行下载,安装过程略过

客户端软件可以选择比较高版本的Navicat,比如Navicat15 ,也可以下载Robo 3T,下载链接:https://robomongo.org

2、新建项目

开发环境

  • JDK 1.8

  • SpringBoot2.2.1

  • Maven 3.2+

  • 开发工具

  • IntelliJ IDEA

  • smartGit

  • Navicat15

使用阿里云提供的脚手架快速创建项目:
https://start.aliyun.com/bootstrap.html

也可以在idea里,将这个链接复制到Spring Initializr这里,然后创建项目

jdk选择8的

选择spring data MongoDB

项目自动生成正常是会加上spring-boot-starter-data-mongodb配置的

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

当然,maven基础比较好的读者也可以自己配maven

<?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>
    <groupId>com.example.mongodb</groupId>
    <artifactId>springboot-mongodb</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-mongodb</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.2.1.RELEASE</spring-boot.version>
    </properties>

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

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.11</version>
        </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>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.2.1.RELEASE</version>
                <configuration>
                    <mainClass>com.example.mongodb.SpringbootMongodbApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

3、MongoDB配置

因为是springboot项目,引入对应starter之后,starter是会进行自动配置的,所以我们可以在配置文件里,简单修改ip和数据库就行,其它的直接默认

spring:
  data:
    mongodb:
      host: 127.0.0.1
      database: test

也可以自己新建一个配置类,不写在yml配置文件里

package com.example.mongodb.configuration;

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import java.util.Collection;
import java.util.Collections;

@Configuration
@EnableMongoRepositories(basePackages = "com.example.mongodb.repository")
public class MongoConfiguration extends AbstractMongoClientConfiguration {

    private static final String DB_NAME = "test";
    private static final String IP = "127.0.0.1";
    private static final String PORT = "27017";

    @Override
    public MongoClient mongoClient() {
        ConnectionString str = new ConnectionString("mongodb://"+ IP + ":"+ PORT + "/" + getDatabaseName());
        MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
                .applyConnectionString(str)
                .build();
        return MongoClients.create(mongoClientSettings);
    }

    @Override
    public MongoTemplate mongoTemplate() throws Exception {
        return new MongoTemplate(mongoClient() , getDatabaseName());
    }

    @Override
    protected String getDatabaseName() {
        return DB_NAME;
    }

    @Override
    protected Collection<String> getMappingBasePackages() {
        return Collections.singleton("com.example.mongodb");
    }
}

4、标记Document类

MongoDB的model类,加上注解@Document

package com.example.mongodb.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoId;

import java.io.Serializable;

@Data
@SuperBuilder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Document(collection = "user")
public class User implements Serializable {
    @MongoId
    private Long id;
    private String name;
    private Integer age;
    private String email;

}

5、MongoRepository使用

mongoDB数据库查看可以借助MongoRepository或者使用MongoTemplateMongoRepository和spring data jpa的很像,所以可以很多curd的方法都不需要写了,直接调用就行,然后如果要通过一些定制的,比如通过邮箱获取用户信息,可以通过findget这些关键字,加上findByEmail就行,使用和Spring data jpa很像

package com.example.mongodb.repository;

import com.example.mongodb.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface UserRepository extends MongoRepository<User, Long> {

    @Query("{ 'email' : ?0 }")
    User findByEmail(String email);

    @Query("{'_id' : ?0 }")
    Optional<User> findById(Long id);

}

Service业务类:

package com.example.mongodb.service.impl;

import com.example.mongodb.model.User;
import com.example.mongodb.repository.UserRepository;
import com.example.mongodb.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@Transactional(
        rollbackFor = Exception.class
)
public class UserServiceImpl implements IUserService {

    @Autowired
    @Qualifier(value = "userRepository")
    private UserRepository userRepository;

    @Override
    public List<User> list() {
        return userRepository.findAll();
    }

    @Override
    public User getOneById(Long id) {
        Optional<User> optional = userRepository.findById(id);
        if (optional.isPresent()) {
            return optional.get();
        }
        return optional.orElse(null);
    }

    @Override
    public User save(User user) {
        return userRepository.insert(user);
    }

    @Override
    public void removeById(Long id) {
        userRepository.deleteById(id);
    }

    @Override
    public User updateById(User user) {
       return userRepository.save(user);
    }

    @Override
    public User findByEmail(String email) {
        return userRepository.findByEmail(email);
    }

}

6、RestFul CURD接口

先借助CommandLineRunner进行数据initialize,项目启动自动先新增测试数据:

package com.example.mongodb;

import com.example.mongodb.model.User;
import com.example.mongodb.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
public class ApplicationRunner implements CommandLineRunner {

    @Autowired
    @Qualifier(value = "userRepository")
    UserRepository userRepository;

    @Override
    public void run(String... args) throws Exception {
        this.init();
    }

    private void init() {
        userRepository.deleteAll();
        List<User> users = Stream.of(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L ,9L).map(i -> {
            User user = new User();
            user.setId(i);
            user.setName("User" + i);
            user.setAge(18);
            user.setEmail("test" + i + "@qq.com");
            return user;
        }).collect(Collectors.toList());
        userRepository.saveAll(users);
    }

}

RestFul的crud接口:

package com.example.mongodb.controller;

import cn.hutool.core.bean.BeanUtil;
import com.example.mongodb.common.rest.ResultBean;
import com.example.mongodb.model.User;
import com.example.mongodb.model.dto.UserDto;
import com.example.mongodb.model.vo.UserVo;
import com.example.mongodb.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping(value = "/api")
public class UserController {

    @Autowired
    private IUserService userService;

    @GetMapping(value = {"/user"})
    public ResultBean<List<UserVo>> users() {
        List<User> poList = userService.list();
        List<UserVo> voList = BeanUtil.copyToList(poList , UserVo.class);
        return ResultBean.ok(voList);
    }

    @GetMapping(value = {"/user/{id}"})
    public ResultBean<UserVo> user(@PathVariable("id")Long id) {
        User user = userService.getOneById(id);
        UserVo userVo = BeanUtil.copyProperties(user , UserVo.class);
        return ResultBean.ok(userVo);
    }

    @PostMapping(value = "/user")
    public ResultBean<User> save(@RequestBody UserDto userDto) {
        User user = BeanUtil.copyProperties(userDto , User.class);
        return ResultBean.ok(userService.save(user));
    }

    @DeleteMapping(value = "/user/{id}")
    public ResultBean<Long> del(@PathVariable("id") Long id) {
        userService.removeById(id);
        return ResultBean.ok(id);
    }

    @PutMapping(value = "/user")
    public ResultBean<User> update(@RequestBody UserDto userDto) {
        User user = BeanUtil.copyProperties(userDto , User.class);
        return ResultBean.ok(userService.updateById(user));
    }

}

7、MongoTemplate 用法

使用MongoTemplate也是可以的,下面列举比较常用的用法,读者可以自行验证:

package com.example.mongodb;

import com.example.mongodb.model.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.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;

@SpringBootTest
class SpringbootMongodbApplicationTests {

    @Autowired
    MongoTemplate mongoTemplate;

    @Test
    void contextLoads() {}

    @Test
    void insert() {
        User user = User.builder()
                .id(10L)
                .name("admin")
                .age(18)
                .email("123456@qq.com")
                .build();
        mongoTemplate.insert(user , "user");
    }

    @Test
    void update() {
        User user = mongoTemplate.findOne(
                Query.query(Criteria.where("_id").is(1L)), User.class);
        user.setName("testUser1");
        mongoTemplate.save(user , "user");
    }

    @Test
    void updateFirst() {
        // 多条相同的数据,只会更新第一条
        mongoTemplate.updateFirst(
                Query.query(Criteria.where("name").is("User1")),
                Update.update("name" , "James"), User.class);
    }

    @Test
    void updateMulti() {
        // 多条相同的数据,都会根据条件更新
        mongoTemplate.updateMulti(
                Query.query(Criteria.where("name").is("User1")),
                Update.update("name" , "James"), User.class);
    }

    @Test
    void findAndModify() {
        // 和updateFirst类似,不过会返回更新的数据
        User user = mongoTemplate.findAndModify(
                Query.query(Criteria.where("name").is("User1")) ,
                Update.update("name" , "James"), User.class);
        System.out.println(user);
    }

    @Test
    void upsert() {
        // 查得到数据更新,查不到会更新一条
        mongoTemplate.upsert(
                Query.query(Criteria.where("name").is("User10")) ,
                Update.update("name" , "James"), User.class);

    }

    @Test
    void remove() {
        User user = User.builder()
                .id(10L)
                .name("test")
                .email("test@qq.com")
                .build();
        mongoTemplate.remove(user);
    }

    @Test
    void count(){
        long count = mongoTemplate.count(
                Query.query(Criteria.where("name").is("User1")) ,
                User.class);
        System.out.println(count);
    }

}

8、参考资料

详细使用,读者可以参考官网进行学习:

相关文章