一起养成写作习惯!这是我参与「掘金日新计划 · 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查看运行中的容器
可以看到已经在运行了。 我们可以在本地安装一个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中查看
已经有记录了 通过修改方法将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的框架整合开发验证已经完成了。