SpringBoot学习笔记(九:MongoDB )

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介: SpringBoot学习笔记(九:MongoDB )

文章目录

一、MongoDB简介

MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个  行业以及各类应用程序的开源数据库。基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应  用提供可扩展的高性能数据存储解决方案。MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。

MongoDB  是专⻔为可扩展性、⾼性能和⾼可⽤性⽽设计的数据库,它可以从单服务器部署扩展到⼤型、复杂的多数据中⼼架构。利⽤内存计算的优势,MongoDB  能够提供⾼性能的数据读写操作。MongoDB 的本地复制和⾃动故障转移功能使应⽤程序具有企业级的可靠性和操作灵活性。

1、MongoDB相关概念

MongoDB 是一个面向文档存储的数据库,看一下与关系型数据库相比,MongoDB的相关概念:

SQL术语/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键

 对比关系图:

image.png

2、创建数据库

  • 查看所有数据库
show dbs
  • 创建数据库
use test
  • 为数据库创建用户
db.createUser({user:"test", pwd:"test", roles:[{role:"dbOwner", db:"test"}]})

二、整合MongoDB

Spring Boot 操作数据库的各种 Starters 都继承于 Spring Data,Spring Data 是 Spring 为了简化数据库操作⽽封装的⼀个组件包,提供了操作多种数据库的⽀持,其 API 简洁、调⽤⽅便。

spring-boot-starter-data-mongodb 是 Spring Data 的⼀个⼦模块。⽬标是为 MongoDB  提供⼀个相近的、⼀致的、基于 Spring 的编程模型。spring-boot-starter-data-mongodb 核⼼功能是映射  POJO 到 Mongo 的DBCollection 中的⽂档,并且提供 Repository ⻛格数据访问层。

使⽤ Spring Boot 进⾏ MongoDB 连接,需要使⽤ spring-boot-starter-data-mongodb  包。spring-bootstarter-data-mongodb 继承 Spring Data 的通⽤功能外,针对 MongoDB  的特性开发了很多定制的功能,让使⽤ Spring Boot 操作 MongoDB 更加简便。

Spring Boot 操作 MongoDB 有两种⽐较流⾏的使⽤⽅法:

  • 将 MongoTemplate 直接注⼊到 Dao 中使⽤
  • ⼀继承 MongoRepository,MongoRepository 内置了很多⽅法可直接使⽤。

1、MongoTemplate

MongoTemplate 提供了⾮常多的操作 MongoDB ⽅法,它是线程安全的,可以在多线程的情况下使⽤。

MongoTemplate 实现了 MongoOperations 接⼝, 此接⼝定义了众多的操作⽅法如  find、findAndModify、findOne、insert、remove、save、update and updateMulti  等。它转换 domain object 为 DBObject,并提供了 Query、Criteria and Update 等流式 API。

1.1、添加依赖

添加 spring-boot-starter-data-mongodb 包引⽤:

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

1.2、application.properties配置

在application.properties添加mongodb连接配置:

spring.data.mongodb.uri=mongodb://test:test@localhost:27017/test

如果是集群:

spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/database

密码和⽤户名如果没有设置可以不⽤添加:

spring.data.mongodb.uri=mongodb://localhost:27017/test

1.3、创建数据实体

创建数据实体类:

public class User implements Serializable {
 private static final long serialVersionUID = -3258839839160856613L;
 private Long id;
 private String userName;
 private String passWord;
 //getter、setter 省略
}

1.4、对实体进⾏增删改查操作

Repository 层实现了 User 对象的增、删、改、查功能。

  • 接口:
public interface UserRepository  {
    public void saveUser(User user);
    public User findUserByUserName(String userName);
    public long updateUser(User user);
    public void deleteUserById(Long id);
}
  • 实现类:

在实现类中使用MongoTemplate对MongoDB进行增删改查的操作。

@Component
public class UserRepositoryImpl implements UserRepository {
   //注入MongoTemplate
    @Autowired
    private MongoTemplate mongoTemplate;
    /**
     * 添加数据
     * save ⽅法中会进⾏判断,如果对象包含了 ID 信息就会进⾏更新,如果没有包含 ID 信息就⾃动保存。
     * @param user
     */
    @Override
    public void saveUser(User user) {
        mongoTemplate.save(user);
    }
    /**
     * 根据⽤户名查询对象
     * @param userName
     * @return
     */
    @Override
    public User findUserByUserName(String userName) {
        Query query=new Query(Criteria.where("userName").is(userName));
        User user = mongoTemplate.findOne(query , User.class);
        return user;
    }
    /**
     * 更新对象
     * 可以选择更新⼀条数据,或者更新多条数据
     * @param user
     * @return
     */
    @Override
    public long 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());
        //更新查询返回结果集的第⼀条
        UpdateResult result =mongoTemplate.updateFirst(query,update,User.class);
        //更新查询返回结果集的所有
        // mongoTemplate.updateMulti(query,update,UserEntity.class);
        if(result!=null)
            return result.getMatchedCount();
        else
            return 0;
    }
    /**
     * 删除对象
     * @param id
     */
    @Override
    public void deleteUserById(Long id) {
        Query query=new Query(Criteria.where("id").is(id));
        mongoTemplate.remove(query,User.class);
    }
}

1.5、测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserRepositoryTest {
    @Autowired
    private UserRepository userRepository;
    @Test
    public void testSaveUser(){
        User user =new User(2l,"zhangtiegang","gougang");
        userRepository.saveUser(user);
    }
    @Test
    public void findUserByUserName(){
        User user= userRepository.findUserByUserName("zhangtiegang");
        System.out.println("user is "+user);
    }
    @Test
    public void updateUser(){
        User user =new User(2l,"wangchunhua","chuanhua");
        userRepository.updateUser(user);
    }
    @Test
    public void testDeleteUserById(){
        userRepository.deleteUserById(2l);
    }
}

1.6、验证结果

可通过图形化工具或者命令行来查看MongoDB数据库中的数据:

  • 切换到test数据库:
use test
  • 查询 userEntity 集合数据:
db.user.find()

2、MongoRepository

MongoRepository 继承于 PagingAndSortingRepository,再往上就是  CrudRepository, MongoRepository 和JPA、Elasticsearch 的使⽤⽐较类似,都是 Spring  Data 家族的产品,最终使 ⽤⽅法也就和 JPA、ElasticSearch 的使⽤⽅式类似,可以根据⽅法名⾃动⽣成 SQL 来查询。

 MongoRepository类图

image.png

和MongoTemplate相同,有区别的只是只有 Repository 层。

2.1、UserRepository

新建 UserRepository 需要继承 MongoRepository,这样就可直接使⽤ MongoRepository 的内置⽅法

public interface UserRepository extends MongoRepository<User,Long> {
    User findByUserName(String userName);
    //分页查询
    Page<User> findAll(Pageable var1);
}

2.2、测试

使⽤ UserRepository 进⾏增、删、改、查功能。

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserRepositoryTest {
    @Autowired
    private UserRepository userRepository;
    /**
     * 测试保存
     * 循环保存多个user
     * @throws Exception
     */
    @Test
    public void testSaveUser() throws Exception {
        for (long i=0;i<100;i++) {
            User user=new User();
            user.setId(i);
            user.setUserName("san"+i);
            user.setPassWord("shisanbushier");
            userRepository.save(user);
        }
    }
    /**
     * 测试保存
     * 保存单个user
     * @throws Exception
     */
    @Test
    public void testSingleSaveUser() throws Exception {
        User user=new User(1l,"san","chuizi");
        userRepository.save(user);
    }
    /**
     * 测试查找
     */
    @Test
    public void findUserByUserName(){
        User user= userRepository.findByUserName("san");
        System.out.println("user is "+user);
    }
    @Test
    public void updateUser(){
        User user=new User();
        user.setId(1l);
        user.setUserName("er");
        user.setPassWord("shierbushisan");
        userRepository.save(user);
    }
    /**
     * 测试删除
     */
    @Test
    public void deleteUserById(){
        userRepository.deleteById(1l);
    }
    /**
     * 测试分页查看
     */
    @Test
    public void testPage(){
        Pageable pageable = PageRequest.of(2, 10);
        Page page=userRepository.findAll(pageable);
        System.out.println("users: "+page.getContent().toString());
    }
}

  • Pageable 是 Spring Data  库中定义的⼀个接⼝,该接⼝是所有分⻚相关信息的⼀个抽象,通过该接⼝,可以得到和分⻚相关所有信息(如 pageNumber、pageSize  等),这样,JPA 就能够通过 pageable 参数来得到⼀个带分⻚信息的 SQL 语句。
  • Page 类也是 Spring Data 提供的⼀个接⼝,该接⼝表示⼀部分数据的集合以及其相关的下⼀部分数据、数据总数等相关信息,通过该接⼝,可以得到数据的总体信息(数据总数、总⻚数…)以及当前数据的信息(当前数据的集合、当前⻚数等)。

2.3、验证

验证同上,可以通过可视化工具或命令行。

上面两种⽅式都可以⽅便地操作 MongoDB 数据库,MongoTemplate  模式⽐较灵活可以根据⾃⼰的使⽤情况进⾏组装,MongoRepository 的使⽤⽅式更简单,因为继承了 Spring  Data,所以默认实现了很多基础的增、删、改、查功能,业务直接拿来使⽤即可。简单⽇常的使⽤推荐  MongoRepository,简单⽅便利于项⽬快速开发,复杂多变的查询推荐使⽤ MongoTemplate ⾃⾏进⾏封装。

3、MongoDB多数据源

3.1、添加依赖

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

3.2、application.properties配置

在配置⽂件中添加不同的数据源:

mongodb.primary.uri=mongodb://localhost:27017
mongodb.primary.database=primary
mongodb.secondary.uri=mongodb://localhost:27017
mongodb.secondary.database=secondary

集群可以采用以下配置:

mongodb.xxx.uri=mongodb://192.168.0.1:27017,192.168.0.2:27017,192.168.0.3:27017
mongodb.xxx.database=xxx

3.3、配置数据源

  • 封装读取以 Mongodb 开头的两个配置文件:
@ConfigurationProperties(prefix = "mongodb")
public class MultipleMongoProperties {
 private MongoProperties primary = new MongoProperties();
 private MongoProperties secondary = new MongoProperties();
 //省略 getter、setter
}
  • 创建 MultipleMongoConfig 类分别创建两个数据源的 MongoTemplate:
Configuration
public class MultipleMongoConfig {
    @Autowired
    private MultipleMongoProperties mongoProperties;
    /**
     * 利⽤构建好的 MongoDbFactory 创建对应的 MongoTemplate
     * @return
     * @throws Exception
     */
    @Primary
    @Bean(name = "primaryMongoTemplate")
    public MongoTemplate primaryMongoTemplate() throws Exception {
        return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary()));
    }
    @Bean
    @Qualifier("secondaryMongoTemplate")
    public MongoTemplate secondaryMongoTemplate() throws Exception {
        return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary()));
    }
    /**
     * 根据配置⽂件信息构建第⼀个数据源的 MongoDbFactory
     * @param mongo
     * @return
     * @throws Exception
     */
    @Bean
    @Primary
    public MongoDbFactory primaryFactory(MongoProperties mongo) throws Exception {
        MongoClient client = new MongoClient(new MongoClientURI(mongoProperties.getPrimary().getUri()));
        return new SimpleMongoDbFactory(client, mongoProperties.getPrimary().getDatabase());
    }
    @Bean
    public MongoDbFactory secondaryFactory(MongoProperties mongo) throws Exception {
        MongoClient client = new MongoClient(new MongoClientURI(mongoProperties.getSecondary().getUri()));
        return new SimpleMongoDbFactory(client, mongoProperties.getSecondary().getDatabase());
    }
}
  • 配置不同包路径下使用不同的数据源

第一个库的封装:

@Configuration
@EnableConfigurationProperties(MultipleMongoProperties.class)
@EnableMongoRepositories(basePackages = "edu.hpu.repository.primary",
        mongoTemplateRef = "primaryMongoTemplate")
public class PrimaryMongoConfig {
}

第二个库的封装:

@Configuration
@EnableMongoRepositories(basePackages = "edu.hpu.repository.secondary",
        mongoTemplateRef = SecondaryMongoConfig.MONGO_TEMPLATE)
public class SecondaryMongoConfig {
    protected static final String MONGO_TEMPLATE = "secondaryMongoTemplate";
}

3.4、实体类

public class User implements Serializable {
 private static final long serialVersionUID = -3258839839160856613L;
 private String id;
 private String userName;
 private String passWord;
 //省略getter setter
}

3.5、Repository

在edu.hpu.repository.primary、edu.hpu.repository.secondary包下分别创建两个Repository。

public interface PrimaryRepository extends MongoRepository<User, String> {
}

public interface SecondaryRepository extends MongoRepository<User,String> {
}

3.6、测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class RepositoryTest {
    @Autowired
    private PrimaryRepository primaryRepository;
    @Autowired
    private SecondaryRepository secondaryRepository;
    @Test
    public void TestSave() {
        //分别向两个库中存入数据
        this.primaryRepository.save(new User("01","张三", "123456"));
        this.secondaryRepository.save(new User("02","李四", "654321"));
        //从第一个库中取出数据
        List<User> primaries = this.primaryRepository.findAll();
        for (User primary : primaries) {
            System.out.println(primary.toString());
        }
        //从第二个库中取出数据
        List<User> secondaries = this.secondaryRepository.findAll();
        for (User secondary : secondaries) {
            System.out.println(secondary.toString());
        }
    }
}

运行结果:

image.png

通过可视化工具或命令行同样可以在对应的库中查到数据。

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
3月前
|
安全 Java Spring
【Spring Boot 源码学习】HttpEncodingAutoConfiguration 详解
本篇带大家一起从源码了解 Spring Boot 内置的Http编码功能
65 8
【Spring Boot 源码学习】HttpEncodingAutoConfiguration 详解
|
3月前
|
NoSQL Java MongoDB
springboot整合MongoDB(简单demo实现包含注意点及踩坑)
springboot整合MongoDB(简单demo实现包含注意点及踩坑)
111 0
|
4月前
|
Java 应用服务中间件 Spring
【Spring Boot 源码学习】@Conditional 条件注解
【1月更文挑战第8天】本篇介绍 @Conditional 条件注解及其衍生注解
111 3
【Spring Boot 源码学习】@Conditional 条件注解
|
4月前
|
Java Spring
【Spring Boot 源码学习】OnWebApplicationCondition 详解
【1月更文挑战第5天】本篇同大家一起从源码角度了解 OnWebApplicationCondition
57 2
【Spring Boot 源码学习】OnWebApplicationCondition 详解
|
2月前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
191 0
|
3天前
|
存储 前端开发 Java
Spring Boot自动装配的源码学习
【4月更文挑战第8天】Spring Boot自动装配是其核心机制之一,其设计目标是在应用程序启动时,自动配置所需的各种组件,使得应用程序的开发和部署变得更加简单和高效。下面是关于Spring Boot自动装配的源码学习知识点及实战。
12 1
|
12天前
|
XML Java 数据格式
Spring学习__一篇足矣
Spring学习__一篇足矣
Spring学习__一篇足矣
|
16天前
|
Java 数据安全/隐私保护 Sentinel
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
|
17天前
|
Java Nacos 开发者
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
|
17天前
|
Dubbo Java 应用服务中间件
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架