spring boot 整合 mongodb初探

145 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

目录

开发中一直使用的是mysql这种关系型数据库,对于其它类型的数据库一直不太了解。除了关系型数据库之外,其它的就是非关系数据库了。比如用的比较多的,作为缓存来使用的redis,今天想介绍的是mongodb。它属于一个分布式文件存储的数据库,是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。 之前的项目中接触过elasticsearch,虽然说elasticsearch是搜索引擎,但是它也可以存储数据,不过它存储的格式是json。mongodb里面存储文件的格式也是json,这个给存储单条记录时,字段的拓展带来了极大的便利。由于我在实际项目中还么有遇到使用mongodb的项目,所以本文重点在环境的搭建和与spring boot框架使用的整合

安装

我这里选择使用docker容器的方式来安装mongodb,这样启动停止都可以使用容器命令,同时镜像的安装也比较快捷方便。我是用dockercompose文件来创建容器镜像,下面奉上我的配置文件

version: "3.8"
services:
#服务名称
mongodb:
 #镜像
 image: mongo:4.4.10
 #容器
 container_name: mongodb
 ports:
   - "27017:27017"
 volumes:
   - /var/lib/docker/volumes/mongodb/data:/data/db
 environment:
   MONGO_INITDB_ROOT_USERNAME: mongoadmin
   MONGO_INITDB_ROOT_PASSWORD: mongoadmin
 networks:
   - nginxDefault    
networks:
nginxDefault:
 name: nginx_default
 driver: bridge

首先是指定了docker的版本, 然后定义了我们要从镜像仓库中所拉取的镜像,这里是使用4.4.10版本。我们声明容器的名称是mongodb。然后mongodb默认的端口是27017,我们宿主机和容器直接使用默认的端口映射。由于我们这次装的是数据库,避免容器删除后,数据库中的文件丢失(默认文件是存在容器中的)所以使用数据卷挂载,将宿主机的文件目录映射进容器内部。

environment是定义docker容器启动时的环境变量,这里和mysql一样,需要有个默认的账户和密码。network可以理解为容器的网络通信类型,我这里在文件的最下方是指定了一个网桥的通信类型,现在mongodb的通信类型也指定为NginxDefault,那么所有都是用这个通信类型的容器都处于同一个"局域网"内 我们在服务器上创建一个docker-compose.yml文件,然后把上面的配置拷贝进去,当然可以自行修改,退出保存后执行

docker-compose up -d

意思是后台执行docker-compose命令。然后使用docker -ps查看运行中的容器

1649423700(1).png 可以看到已经在运行了。 我们可以在本地安装一个Robo 3T(一个mongodb的客户端)这样方便我们查看数据库内部的信息。

spring boot 整合

第一步加入Maven依赖

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

然后配置我们的aplication.yml文件,我这里只配置最简单的参数

server:
  port: 8096
  servlet:
    context-path: /mongo
spring:
  application:
    name: MONGO-DB
  data:
    mongodb:
      host: 127.0.0.1
      port: 27017
      username: mongoadmin
      password: mongoadmin
      database: test
      authentication-database: admin

logging:
  level:
    log4j.category.org.springframework.data.mongodb: debug

这里主要是指定了我们数据库服务的地址端口,我们连接用的用户名密码,连接的库是哪个。其实这些和我们使用mysql配置的东西大同小异。

spring boot data将主流的各类数据库都做了封装,我们可以直接使用它们提供的模板,这个和之前使用的spring boot data jpa很相似,创建实体类映射也是正向工程的思想。所以我们创建一个实体对象

@Data
@Document(collection = "product")
public class ProductPO {

    @Id
    private String id;

    @Field(targetType = FieldType.STRING,name = "product_name")
    private String productName;

    @Field(targetType = FieldType.DECIMAL128,name = "price")
    private BigDecimal price;

    @Field(targetType = FieldType.DATE_TIME,name = "create_date")
    private LocalDateTime createDate;

    @Field(targetType = FieldType.DATE_TIME,name = "create_date")
    private LocalDateTime updateDate;
}

这个和jpa也很类似,指定表名为product,然后定义主键,定义各个字段的名称和类型。 创建完后我们启动程序, 在Robo 3T,首次创建表不会直接显示需要添加一条记录后才会出现。 我们编写一些curd的方法来验证开发环境的可行性

public interface ProductRepository extends MongoRepository<ProductPO,String>

创建一个实体接口,这样我们可以使用spring boot给我们封装好的方法,我们创建几个方法

@ApiOperation(value = "添加")
@PostMapping(value = "/add")
public WebResponse add(@RequestBody ProductPO productPO){
    productService.add(productPO);
    return WebResponse.success();
}

@ApiOperation(value = "删除")
@DeleteMapping("/{productId}")
public WebResponse delete(@PathVariable("productId")String productId){
    productService.delete(productId);
    return WebResponse.success();
}

@ApiOperation(value = "编辑")
@PutMapping(value = "/modify")
public WebResponse modify(@RequestBody ProductPO productPO){
    productService.modify(productPO);
    return WebResponse.success();
}

@ApiOperation(value = "查询")
@GetMapping(value = "/query")
public WebResponse query(@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                         @RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize){
    ProductQuery productQuery = new ProductQuery();
    productQuery.setPageNum(pageNum);
    productQuery.setPageSize(pageSize);
    PageVO<ProductVO> pageVO = productService.query(productQuery);
    return WebResponse.success(pageVO);
}

这里分别是新增,删除,获取单个的记录,更新记录,查询分页记录。 下面是内部主要的实现代码

@Override
public void addProduct(ProductPO productPO) {
    productPO.setCreateDate(LocalDateTime.now());
    productPO.setUpdateDate(LocalDateTime.now());
    productRepository.save(productPO);
    log.info(productPO.getId());
}

@Override
public ProductPO getOne(String id) {
    return productRepository.findById(id).orElse(null);
}

@Override
public void update(ProductPO productPO) {
    productRepository.save(productPO);
}

@Override
public PageVO<ProductPO> queryPage(Integer pageNum, Integer pageSize) {
    PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize);
    Page<ProductPO> all = productRepository.findAll(pageRequest);
    return PageVO.pageOf(all.getContent(),pageNum,pageSize,all.getTotalElements());
}

@Override
public void delete(String id) {
    productRepository.deleteById(id);
}

可以发现基本都是jpa data的那种封装风格 首先新增数据,完成后再Robo中查看

1649426525(1).png 已经有记录了 通过修改方法将price改为20,再次查询的时候发现已经变化了

{
    "_id" : ObjectId("62503cbe94b65c2ff6f109e4"),
    "product_name" : "书本",
    "price" : NumberDecimal("20"),
    "create_date" : ISODate("2022-04-08T14:15:02.028+08:00"),
    "update_date" : ISODate("2022-04-08T14:15:02.028+08:00"),
    "_class" : "com.zjl.spring_boot_mongodb.model.ProductPO"
}

现在有了两条记录,我们选择删除一条,可以通过id来进行删除,再次刷新可以发现只有一条了 还可以通过id获取记录的信息可以看到返回

{
  "code": "200",
  "msg": "success",
  "data": {
    "id": "62503cbe94b65c2ff6f109e4",
    "productName": "书本",
    "price": 10,
    "createDate": "2022-04-08T21:46:38.067",
    "updateDate": "2022-04-08T21:46:38.067"
  }
}

到此我们对spring boot mongodb的框架整合开发验证已经完成了。