一、首先使用docker安装mongodb
1,拉取镜像
docker pull mongo:4.0.3
2.创建mongodb容器(不需验证方式)
docker create --name mongodb -p 27017:27017 -v /data/mongodb:/data/db mongo:4.0.3
3.启动容器
docker start mongodb
进入容器
docker exec -it mongodb /bin/bash
然后再输入mongo命令,进入mongodb客户端
输入exit退出客户端;
使用docker ps查看容器进程
4.或者使用下边的命令方式直接进入容器及mongodb客户端,初始化admin库的管理员账号
# docker exec -it <容器名> <mongo命令> <数据库名>
docker exec -it mongodb mongo admin
创建系统内部数据库admin库最高权限(root权限)用户
db.createUser({ user: 'admin', pwd: 'adminpwd', roles: [ { role: "root", db: "admin" } ] });
user:用户名admin
- pwd:密码adminpwd
- role:角色root
- db:授权使用admin库
exit退出mongodb命令行及docker容器;
创建好了最高权限用户之后(这个容器进入mongodb不需要验证)
接下来创建一个需要验证的mongodb的docker容器,
第二种,创建需要用户名和密码验证的mongodb镜像(掌握第二种)
首先停止之前创建的镜像容器,并删除该镜像容器
# 停止名为mongodb的镜像容器
docker stop mongodb;
#删除名为mongodb的镜像容器
docker rm mongodb;
# 查看docker容器的进程状况
docker ps
接下来创建一个新的mongodb镜像容器,带验证
docker run --name mymongo -p 27017:27017 -v /mongo/data:/data/db -d mongo:4.0.3 --auth
然后进入容器:
docker exec -it mymongo mongo admin
初始化admin系统库管理员用户
db.createUser({ user: 'admin', pwd: 'adminpwd', roles: [ { role: "root", db: "admin" } ] });
# 权限认证
# 返回 1 证明成功, 返回 0 证明失败
db.auth("admin","adminpwd");
# 权限说明
1.数据库用户角色:read、readWrite;
2.数据库管理角色:dbAdmin、dbOwner、userAdmin;
3.集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
4.备份恢复角色:backup、restore
5.所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
6.超级用户角色:root
然后创建一个可用账号,并删除
db.createUser({ user: 'testadmin', pwd: 'testadmin123', roles: [ { role: "root", db: "admin" } ] });
防火墙开启27017端口,阿里云服务器,需要到阿里云管理页面添加27017端口的对外开放规则
firewall-cmd --zone=public --add-port=27017/tcp --permanent
firewall-cmd --reload
firewall-cmd --query-port=27017/tcp
然后navicat premium中连接查看
因为第二种启动时候开启了验证,并且创建了验证账号,所以navicat连接时候是需要认证的,再验证那里选择password认证方式
用户名输入刚才创建的 admin ,密码是 adminpwd,然后测试连接,会提示连接成功,如果验证方式选择none,则会提示认证失败
如果是最开始创建的那种方式,启动没有加--auth选项的,则验证选择none,可以直接连接成功的
navicat premium中连接mongodb,默认情况下不显示mongodb的系统库(有三个,admin,local和config),只显示了我自己创建的一个visit的数据库,这时候需要在navicat的查看菜单中,勾选上显示隐藏项目
二,整合spring data mongodb操作数据
在项目测试之前,我们需要新创建一个测试数据库(不要用系统自带的那3个数据库)
# 进入docker容器以及mongo客户端admin库
docker exec -it mymongo mongo admin
#进行 验证
db.auth("admin","adminpwd");
# 查询所有数据库
show dbs;
# mongodb中没有创建数据库的语句,创建数据库时,需要使用use语句切换到想建的数据库名字
use test;
#use test;之后,还没有创建test数据库,需要在插入collection中数据时,会自动创建test数据库
# 下边这条语句,会自动创建test数据库,名字为article的collection,并插入一条数据
db.article.insert({author:'余华',title:'活着'});
# 然后再次查询所有数据库 show dbs;
# 查询collections,两种命令都可以
show tables;
或者
show collections;
然后再切回admin系统库,给test数据库创建一个用户,并赋予readwrite权限
给test数据库创建root角色会报错的,所以创建了readwrite角色
然后再次到navicat中验证一下test数据库
注意事项:上边我们创建test用户的时候,虽然指定的db是test,但是我们是在use admin后切换到admin数据库创建的用户,所以即使指定了test,创建的test用户仍然作用于admin,数据表中数据可以看出,所以要给test库创建test用户,还需要切换到test库进行创建
然后再到navicat中查看
然后在用navicat验证test数据库连接
然后把所有的库都勾选上
1.集成spring data mongodb,在项目Pom文件中引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2.application.yml配置连接
org.springframework.boot.autoconfigure.mongo.MongoProperties 负责加载MonoDB配置
27017是MongoDB默认的端口,test是内置的数据库。如果MongoDB使用了--auth选项启动,则需要使用用户登录,则使用如下方式链接
spring:
data:
mongodb:
# 不使用admin库了
# uri: mongodb://admin:adminpwd@yourip:27017/admin
uri: mongodb://test:123456@yourip:27017/test
上边是单机配置,如果是集群参考
单机模式:mongodb://name:pwd@ip:port/database
集群模式:mongodb://name:pwd@ip1:port1,ip2:port2/database
在项目入口启动类上面加一个注解@EnableMongoAuditing。开启Mongodb审计功能.
接下来就可以写crud了
首先创建实体类
package com.xiaomifeng1010.mongo.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2022/5/8 20:58
* @Description
*/
//集合名
@Document(collection="article")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Article implements Serializable {
private static final long serialVersionUID = 7398406496506855960L;
@Id
private String id;
@Indexed
private String author;
private String title;
@Field("msgContent")
private String content;
@CreatedDate
private Date createTime;
private List<Reader> reader;
}
package com.xiaomifeng1010.mongo.entity;
import lombok.Data;
@Data
public class Reader {
private String name;
/**
* 性别 男或女
*/
private String gender;
}
这里注意:
- 一定要实现Serializable 接口,否则在序列化的时候会报错。
- @Document(collection=“article”) 表示:操作的集合为:
article
。 - 另外,针对
@CreatedDate
注解,也和jpa
用法一样,创建时会自动赋值,需要在启动类中添加@EnableMongoAuditing
注解使其生效! - 可使用
@Field
注解,可指定存储的键值名称,默认就是类字段名。如设置@Field("msgContent")
@Id
主键,不可重复,自带索引,可以在定义的列名上标注,需要自己生成并维护不重复的约束。如果自己不设置@Id主键,mongo会自动生成一个唯一主键,并且插入时效率远高于自己设置主键。@Indexed
声明该字段需要加索引,加索引后以该字段为条件检索将大大提高速度。
唯一索引的话是@Indexed(unique = true)。
Dao接口可以按照自己需要集成Repository,CrudRepository,PagingAndSortingRepository,或者继承功能最全的 MongoRepository均可,如下
package com.xiaomifeng1010.mongo.dao;
import com.xiaomifeng1010.entity.Article;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2022/5/8 21:06
* @Description
*/
@Repository
public interface ArticleDao extends MongoRepository<Article,String> {
/**
* 支持关键字查询,和JPA的用法一样
* @param author
* @return
*/
Article findByAuthor(String author);
}
注意如果你的项目中用了mybatis或者mybatis plus,而且你在启动类中加了@mapperScan注解去扫描mapper接口,如果你设置的路径也包含了mongodb的dao层,那么你在controller层注入ArticleDao 的时候就会报错
The bean 'articleDao' could not be registered. A bean with that name has already been defined in file
所以呢,要么在启动类中去掉@mapperScan注解,要么让这个注解不会扫描到jpa(不会扫描到ArticleDao ),我选择了不扫描到ArticleDao ,让@mapperScan只扫描到mybatis的mapper接口层,即解决问题;如果还不行,就在启动类上把这个注解也加上
@EnableMongoRepositories(basePackages = {"com.**.mongo.dao" }) 用于指定mongodb的dao层所在的package路径就可以了
package com.xiaomifeng1010;
import com.aizuda.security.annotation.EnableRestEncrypt;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@MapperScan(basePackages = {"com.xiaomifeng1010.mapper"})
@EnableAspectJAutoProxy
@EnableAsync
@EnableScheduling
@EnableKnife4j
@EnableCaching
@EnableRabbit
@EnableRestEncrypt
@EnableMongoAuditing
public class NewenergyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(NewenergyApplication.class);
// 不打印输出spring boot的banner
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
在Controller里,可以自动注册ArticleDao
package com.xiaomifeng1010.mongo.controller;
import com.xiaomifeng1010.mongo.dao.ArticleDao;
import com.xiaomifeng1010.mongo.entity.Article;
import com.xiaomifeng1010.mongo.entity.Reader;
import com.google.common.collect.ImmutableList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Optional;
/**
* @author xiaomifeng1010
* @version 1.0
* @date: 2022/5/8 21:10
* @Description
*/
@RestController
public class ArticleTestController {
@Autowired
private ArticleDao articleDao;
/**
* 添加一条记录
* @return
*/
@GetMapping("addArticle")
public String addArticle(){
Article article = new Article();
article.setAuthor("莫言");
article.setContent("20世纪30年代初,山东高密地区土匪横行、民不聊生。东北乡破落地主家17岁的女儿九儿,被贪财的父亲许给有麻风病的酒坊主儿子单扁郎");
article.setTitle("红高粱");
Reader reader = new Reader();
reader.setName("xiaomifeng1010");
reader.setGender("男");
List<Reader> readers = ImmutableList.of(reader);
article.setReader(readers);
Article save = articleDao.save(article);
return save.toString();
}
@GetMapping("/all")
public List<Article> page(@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size){
// JPA 中,page是从0开始,不是从1开始;
// 因此,将用户输入的从1开始的page页码减1,才是查询的第page页
Pageable pageable = PageRequest.of(page-1,size);
Page<Article> result = articleDao.findAll(pageable);
return result.getContent();
}
@GetMapping("/queryOne")
public Article queryDetail(String id){
Optional<Article> optional = articleDao.findById(id);
return optional.get();
}
}
然后在浏览器中访问添加数据接口方法
成功响应了数据
然后到navicat中查看
同时也可以测试一下查询语句
今年五一,拿个博客五一勋章