# MongoDB
**Repository Path**: huhui123/mongo-db
## Basic Information
- **Project Name**: MongoDB
- **Description**: SpringBoot整合MongoDB的相关代码(SpringBoot中操控MongoDB)
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 2
- **Created**: 2025-04-11
- **Last Updated**: 2025-04-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# MongoBD数据库
### MongoDB下载
### MongoDB的SQL语法
### SpringBoot中整合MongoDB
==MongoDB默认是本机访问的 因此需要我们开启远程访问==
#### Windows下开启远程访问:


#### Linux下修改如下
`usr/local/mongodb4/mongodb.conf`文件:
```sh
dbpath=/data/mongodb4/mongo #数据文件保存地址
logpath=/data/mongodb4/log/mongod.log #日志保存地址
port=27017 #端口
fork=true #是否后台启动
auth=true #是否开启权限,访问需要用户名和密码
bind_ip=0.0.0.0 #任意ip都能访问
logappend=true
```
#### 创建SpringBoot项目
#### 添加MongoDB的依赖:
MongoDB的依赖:
```POM
org.springframework.boot
spring-boot-starter-data-mongodb
```
1. ##### 第一种方式;
在创建项目的时候直接勾选MongoDB选项这样的话创建的项目就默认添加了MongoDB依赖

2. ##### 第二种方式:
创建SpringBoot项目之后在pom文件中添加MongoDB依赖

#### 配置文件:
(SpringBoot连接MongoDB的相关参数)
```properties
# MongoDB服务的地址
spring.data.mongodb.host=127.0.0.1
# MongoDB服务的端口号
spring.data.mongodb.port=27017
# 连接的数据库的名称
spring.data.mongodb.database=local
# 需要认证的数据库的名称
spring.data.mongodb.authentication-database=admin
# 开启MongoDB 打印SQL日志的功能
logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG
```
这些操作做完了之后启动项目没有报错的话我们就成功连接到了MongoDB数据库
#### ==MongoDB的其他一些配置==
### SpringBoot中操作MongoDB数据库
添加好依赖和配置之后接下来就可以开始进行数据库表中的增删改查操作了
#### 创建实体:
```java
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("test") //实体对应的MongoDB的数据库中的集合
public class User {
@Id
private String id;
private String name;
private String age;
private String sex;
private String bobby;
}
```
#### MongoDB实体类的注解:
| 注解 | 含义 |
| ----------------- | ------------------------------------------------------------ |
| @Id | 主键,不可重复。自带索引 |
| @Document | 标志在实体类上类似于MP的TableName注解,标明mongo来维护该表 |
| @Indexed | 生命该字段需要加索引之后以字段为条件检索将大大提高速度。唯一索引的话 是@Index(unique=true),也可以对数组进行索引,如果被索引的列是数组的时候,MongoDB会索引这个数组中的每个元素,也可以对整个和Document进行索引,排序是预定义的按插入BSON数据的插入先后升序排列。 |
| @CompoundIndex | 复合索引,加复合索引后通过复合索引字段查询将大大提高速度。是类注解@Document,@CompoundIndexes({@CompoundIndex(name="age_ies",def="{'defName':1,‘age:-1’}")}),写法如上,lastName 和 age 将作为复合索引,数字参数指定索引的方向,1为正序 ,-1为倒序。方向对单键索引和随机存不要紧,但是如果你要执行分组和排序的操作他就非常重要了。 |
| @Field | 代表一个字段,可以不加,不加的话默认以参数名为列名。给映射存储到mongodb的字段取别名 |
| @Transient | 被该注解标注的,将不会被录入到数据库中,只作为普通的javaBean属性。 |
| @DBRef | 关联另一个documen对象,类似于 mysql 的表关联,但并不一样,mongo不会做级联的操作。 |
| @Version | 表示该字段为文档的版本号字段,可以用于乐观锁。映射到MongoDB的`_v`字段 |
| @CreatedDate | 表示该字段为文档的创建日期字段,会自动填充插入文档时的日期。映射到MongoDB的创建日期字段。(long类型和Date类型) |
| @LastModifiedDate | 表示该字段为文档的最后修改日期字段,会自动填充更新文档时的日期,映射到MongoDB的最后修改日期字段。(可以注解Long类型或者Date类型的变量) |
#### 第一种方式JPA方式:
```java
/**
* JPA方式
* 集成MongoRepository即可,不需要实现类
*/
public interface UserRepository extends MongoRepository {
}
```
##### 增加
相关方法:
```java
/**
* 向数据库中插入一条数据
*参数是实体对象
*/
S insert(S entity);
/**
* 向数据库中插入多条数据
* 参数是一个实体对象集合
*/
List insert(Iterable entities);
```
案例:
```java
@Resource
private UserRepository userRepository;
/**
* 向数据库中插入一条数据(这个对象的包名和地址也会插入数据库中)
*/
@Test
void insertData(){
User user = new User();
user.setId("4");
user.setName("张三");
user.setAge("18");
user.setSex("男");
user.setBobby("篮球");
User insert = userRepository.insert(user);
// 返回结果 insert = User(id=4, name=张三, age=18, sex=男, bobby=篮球)
}
/**
* 插入单条数据不指定id(mongoDB数据库会使用自己的id生成策略帮助我们生成一个唯一id)
*/
@Test
void insertData2() {
User user = new User();
user.setName("张三");
user.setAge("18");
user.setSex("男");
user.setBobby("篮球");
User insert = userRepository.insert(user);
//返回结果:User(id=6641fd7ea53741008c23688c, name=张三, age=18, sex=男, bobby=篮球)
}
/**
* 插入多条数据
*/
@Test
void insertDatas(){
User user = new User();
user.setId("2");
user.setName("张三");
user.setAge("18");
user.setSex("男");
user.setBobby("篮球");
User user2 = new User();
user2.setId("3");
user2.setName("张三");
user2.setAge("18");
user2.setSex("男");
user2.setBobby("篮球");
ArrayList list = new ArrayList<>();
list.add(user);
list.add(user2);
List insert = userRepository.insert(list);
// 返回结果 insert = [User(id=2, name=张三, age=18, sex=男, bobby=篮球), User(id=3, name=张三, age=18, sex=男, bobby=篮球)]
}
```
==注意:==我们设置插入数据的数据库实体的时候,我们可以选择设置实体的id,也可以选择不设置实体的id,
当我们设置了实体的id的时候:
在实体插入数据库的时候,会首先判断id是否已经在数据库中存在,如果不存在就执行这条插入语句,如果存在的话就报抛异常,这条插入语句失败。
当我们不设置插入数据库的实体的对象的id的时候,MongoDB数据库内置的id生成策略会自动帮助我们生成一个唯一的id,将数据插入到数据库中。
==向数据库中插入数据的时候不用专门去创建集合(表),因为插入数据的时候会自动创建集合==
##### 删除
```java
@Test
void delete(){
//根据字段删除单个对象
userRepository.delete(new User("1", "张三", "18", "男", "篮球"));
//删除所有
userRepository.deleteAll();
//根据id删除
userRepository.deleteById("1");
//根据id集合删除
userRepository.deleteAllById(Arrays.asList("1", "2", "3"));
//根据字段删除多个
userRepository.deleteAll(Arrays.asList(
new User("1", "张三", "18", "男", "篮球"),
new User("2", "王五", "18", "男", "篮球")));
}
```
##### 修改
==如果id在数据库存在就修改,如果id在数据库中不存在就是插入一条新数据==
```java
/**
* 一次更新一条或者多条数据库中的数据。(如果id在数据库存在就修改,如果id在数据库中不存在就是插入一条新数据)
*/
@Test
void save(){
User save = userRepository.save(new User("4", "李四", "18", "男", "篮球"));
System.out.println("save = " + save);
List users = userRepository.saveAll(Arrays.asList(
new User("2", "王五", "18", "男", "篮球"),
new User("3", "赵六", "18", "男", "篮球")));
System.out.println("users = " + users);
}
```
```java
@Test
void update(){
User user = new User();
// user.setId("1");
// user.setName("Tom");
//筛选出更新的数据
Query query = new Query();
query.addCriteria(Criteria.where("id").is("2"));
//设置更新的字段内容
Update update = new Update();
update.set("name","Tom");
//TODO
// ExecutableUpdateOperation.ExecutableUpdate update = mongoTemplate.update(User.class);
// 更新一条数据
UpdateResult updateResult = mongoTemplate.updateFirst(query, update, User.class);
UpdateResult test = mongoTemplate.updateFirst(query, update, "test");
UpdateResult test1 = mongoTemplate.updateFirst(query, update, User.class, "test");
//更新多条数据
UpdateResult updateResult1 = mongoTemplate.updateMulti(query, update, User.class);
UpdateResult test2 = mongoTemplate.updateMulti(query, update, "test");
UpdateResult test3 = mongoTemplate.updateMulti(query, update, User.class, "test");
}
```
##### 查询
```java
@Test
void select(){
//查询所有数据
List users = userRepository.findAll();
//查询所有数据并按照指定字段进行排序
List users_sort_asc_by_age = userRepository.findAll(Sort.by(Sort.Direction.ASC, "age"));
//分页查询数据
PageRequest page = PageRequest.of(0, 5);
Page get_users_by_page = userRepository.findAll(page);
User user = new User();
user.setName("张三");
//通过user对象中不为null的字段查询数据集合
List get_users_by_user = userRepository.findAll(Example.of(user));
//通过id集合查询符合条件的数据
Iterable get_users_by_ids = userRepository.findAllById(Arrays.asList("1", "2", "3"));
//通过user对象获取数据
List get_users_by_user_order_by_age_asc = userRepository.findAll(Example.of(user), Sort.by(Sort.Direction.ASC, "age"));
//通过user对象分页获取对象
Page get_users_by_user_by_page = userRepository.findAll(Example.of(user), Pageable.ofSize(5));
//通过user对象获取一条数据
Optional get_user_by_user = userRepository.findOne(Example.of(user));
//通过id查询数据
Optional get_user_by_id = userRepository.findById("1");
System.out.println("users = " + users);
System.out.println("users_sort_asc_by_age = " + users_sort_asc_by_age);
System.out.println("get_users_by_page = " + get_users_by_page.getContent());
System.out.println("get_users_by_user = " + get_users_by_user);
System.out.println("get_users_by_ids = " + get_users_by_ids);
System.out.println("get_users_by_user_order_by_age_asc = " + get_users_by_user_order_by_age_asc);
System.out.println("get_users_by_user_by_page = " + get_users_by_user_by_page);
System.out.println("get_user_by_user = " + get_user_by_user);
System.out.println("get_user_by_id = " + get_user_by_id);
}
```
自定义查询:`fetchableFluentQueryf对象的一些方法可以帮助我们对查询结果在进行一次筛选`
```java
@Test
void test(){
User user = new User();
user.setName("张三");
Function, String> queryFunction = fetchableFluentQuery -> {
List list = fetchableFluentQuery.sortBy(Sort.by(Sort.Direction.ASC, "age")).all(); // 执行查询并获取结果列表
System.out.println("list = " + list);
if (list != null && !list.isEmpty()) {
return list.toString(); // 返回
} else {
return null; // 或者你可以抛出异常,或者返回一个默认值
}
};
String by = userRepository.findBy(Example.of(user), queryFunction);
System.out.println("by = " + by);
}
```
##### others
```java
//获取数据库中的总记录数
long count = userRepository.count();
boolean exists = userRepository.exists(Example.of(new User("1", "张三", "18", "男", "篮球")));
boolean equals = userRepository.equals(Example.of(new User("1", "张三", "18", "男", "篮球")));
//判断指定id是否存在
boolean existsById = userRepository.existsById("1");
```
#### 第二种方式MongoTemplate方式
直接在使用的地方依赖注入就好了
```java
@Autowired
private MongoTemplate mongoTemplate;
```
##### 增加
##### 删除
```java
@Test
void delete(){
User user = new User();
user.setId("1");
DeleteResult test = mongoTemplate.remove(user, "test");
// 返回结果 AcknowledgedDeleteResult{deletedCount=1}
System.out.println("test = " + test);
DeleteResult test1 = mongoTemplate.remove(new Query(), "test");
DeleteResult remove1 = mongoTemplate.remove(user);
DeleteResult user1 = mongoTemplate.remove(new Query(), "user");
DeleteResult test2 = mongoTemplate.remove(new Query(), User.class, "test");
//TODO
ExecutableRemoveOperation.ExecutableRemove remove = mongoTemplate.remove(User.class);
}
```
##### 修改
==id存在就修改,id不存在就插入新数据==
```java
@Test
void save(){
User user = new User();
user.setId("1");
user.setBobby("编程");
//插入或者更新数据
User save = mongoTemplate.save(user);
//针对指定的集合插入或者更新数据
User test = mongoTemplate.save(user, "test");
}
```
##### 查询
```java
@Test
void select(){
Query query = new Query();
query.addCriteria(Criteria.where("name").is("张三"));
//根据条件查询数据
List users = mongoTemplate.find(query, User.class);
List test5 = mongoTemplate.find(query, User.class, "test5");
User one = mongoTemplate.findOne(query, User.class);
//根据条件从指定集合中查询复合条件的一条数据,并指定数据映射的实体。
mongoTemplate.findOne(query, User.class, "test5");
List all = mongoTemplate.findAll(User.class);
mongoTemplate.findAll(User.class,"test5");
//查询符合条件的所有数据然后再将其删除,返回结果是查询到的数据集合
List allAndRemove = mongoTemplate.findAllAndRemove(query, User.class);
List