MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库(nosql)之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
SQL属于/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
# 暂时没有加数据卷映射,只是demo测试
docker run -d -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=123456 --restart=always --name=mongodb mongo
以docker容器内为例:
#1. 进入容器并进入mongodb命令行
docker exec -it d2a mongo admin
#2. 先进入容器 再进入命令行
docker exec -it d2a bash
mongo admin
## 如果是直接进入命令行
db.auth("username","password")
#或者
mongo -uroot -p --authenticationDatabase admin
#然后输入密码
#查看所有数据库
show dbs
#查询数据库连接数
show collecitions
#获取数据库名称
db.getName()
#获取数据库状态
db.stats()
#获取数据库版本
db.version()
#查看当前db的链接机器地址
db.getMongo()
# 进入数据库 如果没有则创建
use mongo_demo
# 删除数据库
db.dropDatabase()
#查看集合
show collections
#删除集合
db.collection.drop()
#创建结合
#options具体查阅文档 可以默认
db.createCollection(name, options)
# 查看索引 collection为集合名称
db.collection.getIndexes()
# 创建索引
# 1为正序 -1为倒序 也可以通过实体类添加@Indexed添加索引
db.daily_unit_report.createIndex({"date":-1,"unitId":1})
# 删除索引
db.collection.dropIndex("索引名称")
#查看所有数据
db.集合名字.find()
org.springframework.boot
spring-boot-starter-data-mongodb
spring:
data:
mongodb:
# 两种配置都可,选择其中一种即可
# 配置一
# uri: mongodb://root:[email protected]:27017/mongo_demo?authSource=admin&authMechanism=SCRAM-SHA-1
# 配置二
username: root
#易错点1 如果是纯数字
password: '123456'
database: mongo_demo
host: 192.168.100.21
port: 27017
#易错点2
authentication-database: admin
Caused by: com.mongodb.MongoCommandException: Command failed with error 18 (AuthenticationFailed): ‘Authentication failed.’
原因分析:主要是没有配置认证数据库导致(authentication-database)具体见配置中的易错点2,mongodb默认会将认证和授权信息保存到admin数据库,所以在配置数据库连接的时候需要配置。
Caused by: java.lang.IllegalArgumentException: Prohibited character at position 0
原因分析:数据库密码为数字的时候比如配置为123456(如果不带引号),会识别不到,具体原因是spring-boot-starter-data-mongodb读取配置文件的时候password使用char[]数组接收,所以会识别不到导致报错,正确的做法是数字加单引号和双引号即可识别。
此处还有两个小细节:
Mongodb有一个特别方便的地方就是,不用专门去创建集合的结构和_id,它会根据实体类自动去创建域(字段),如果你的实体类带有id字段,则会是用你的id,如果没有id字段则会自动生成一个。
@Data
@Document(collection = "user")
public class User {
@Id
private String id;
private String name;
private String userName;
private String password;
private String age;
}
@SpringBootTest
@Slf4j
public class UserTemplateTest {
@Resource
private MongoTemplate mongoTemplate;
/**
* 新增
*/
@Test
public void insert(){
User user = User.builder().userName("template").age("100").build();
mongoTemplate.insert(user);
}
/**
* 删除
*/
@Test
public void delete(){
Query query = new Query();
query.addCriteria(Criteria.where("userName").is("template"));
mongoTemplate.findAndRemove(query,User.class);
}
/**
* 修改
*/
@Test
public void update(){
Query query = new Query();
query.addCriteria(Criteria.where("userName").is("template"));
Update update = new Update();
update.set("age","200");
mongoTemplate.findAndModify(query,update,User.class);
}
/**
* 查询
*/
@Test
public void findList(){
Query query = new Query();
query.addCriteria(Criteria.where("age").is("100"));
//模糊匹配
String pattern_name = "template";
Pattern pattern = Pattern.compile("^.*" + pattern_name + ".*$", Pattern.CASE_INSENSITIVE);
query.addCriteria(Criteria.where("userName").regex(pattern));
List list = mongoTemplate.find(query,User.class);
for (User tempUser : list) {
System.out.println(tempUser);
}
}
}
Dao层继承UserRepository
@Repository
public interface UserRepository extends MongoRepository {
}
增删改查
@SpringBootTest
public class UserTest {
@Autowired
private UserRepository userRepository;
@Autowired
private TestProperties testProperties;
/**
* 新增
*/
@Test
public void insert(){
User user = new User();
user.setName("amxliuli");
user.setAge("19");
user.setPassword("123456");
user.setUserName("amxliuli");
User insertUser = userRepository.insert(user);
System.out.println(insertUser.toString());
}
/**
* 查询所有
*/
@Test
public void findAll(){
List lists = userRepository.findAll();
for (User user: lists) {
System.out.println(user);
}
}
/**
* 根据id查询
*/
@Test
public void findById(){
User user = userRepository.findById("62cc09c776552e4c908f4666").get();
System.out.println(user);
}
/**
* 条件查询
*/
@Test
public void findUserList(){
User user = new User();
user.setName("amx");
Example example = Example.of(user);
List list = userRepository.findAll(example);
System.out.println(list);
}
/**
* 模糊匹配
*/
@Test
public void findLikeUserList(){
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
.withIgnoreCase(true);
User user = new User();
user.setName("amx");
Example example = Example.of(user,matcher);
List list = userRepository.findAll(example);
System.out.println(list);
}
/**
* 更新
*/
@Test
public void update(){
User user = userRepository.findById("62cc09c776552e4c908f4666").get();
user.setAge("100");
User updateUser = userRepository.save(user);
System.out.println(updateUser);
}
/**
* 删除
*/
@Test
public void delete(){
userRepository.deleteAllById(Arrays.asList("62cc09c776552e4c908f4666"));
}
}
针对我司某系统的某数据表进行对比,此表共有86个字段,每条记录数据大小平均为2M,数据条数共有3000多条。
数据库(ms) | 第一次 | 第二次 | 第三次 |
---|---|---|---|
mongo | 1287 | 1175 | 985 |
mysql | 4245 | 4310 | 4779 |
数据库(ms) | 第一次 | 第二次 | 第三次 |
---|---|---|---|
mongo | 246 | 201 | 215 |
mysql | 498 | 510 | 478 |
数据库(ms) | 第一次 | 第二次 | 第三次 |
---|---|---|---|
mongo | 170 | 196 | 143 |
mysql | 469 | 334 | 320 |