文章目录
- SpringBoot整合MongoDB
- 文档操作
- 添加文档
- 查询文档
- 更新文档
- 删除文档
SpringBoot整合MongoDB
-
创建项目,添加依赖,配置连接
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.32</version> </dependency>
spring:data:mongodb: # uri: mongodb://xxx:xxx@192.168.1.x:27017/database_name?authSource=adminhost: 192.168.1.xport: 27017username: xxxpassword: xxxdatabase: mydatabase_nameauthentication-database: admin
-
连接测试
@Resource MongoTemplate mongoTemplate;/*** 连接测试*/ @Test public void testConnection(){MongoDatabase mongoDatabase = mongoTemplate.getDb();System.out.println("Connected to database: " + mongoDatabase.getName());// 获取所有集合的名称并打印mongoDatabase.listCollectionNames().forEach(collectionName -> {System.out.println("Collection: " + collectionName);}); }
-
集合操作
/*** 创建集合测试*/ @Test public void testCreateCollection(){boolean exists = mongoTemplate.collectionExists("emp");if (exists){mongoTemplate.dropCollection("emp");}mongoTemplate.createCollection("emp"); }
文档操作
注解 | 描述 | 示例 |
---|---|---|
@Document | 标识一个类为MongoDB的文档,并指定集合名 | @Document(collection="users") |
@Id | 标识一个字段为文档的唯一标识符(_id) | @Id private String id; |
@Field | 指定字段在MongoDB中的名称 | @Field("user_name") private String username; |
@Indexed | 为字段创建索引 | @Indexed private String email; |
@CompoundIndex | 创建复合索引 | @CompoundIndex(name="name_age", def="{'firstName': 1, 'age': -1}") |
@TextIndexed | 为字段创建文本索引 | @TextIndexed private String description; |
@Transient | 标识字段不被持久化到数据库 | @Transient private String tempField; |
@DBRef | 引用另一个文档 | @DBRef private List<Role> roles; |
@Version | 用于乐观锁,自动处理版本控制 | @Version private Long version; |
@CreatedDate | 自动记录文档的创建时间 | @CreatedDate private Date createdDate; |
@LastModifiedDate | 自动记录文档的最后修改时间 | @LastModifiedDate private Date lastModifiedDate; |
- 详细解说
-
@Document
- 用于标识一个Java类为MongoDB的文档,并可以指定集合名称。如果不指定集合名称,默认使用类名的小写形式。
- 示例:
@Document(collection="users")
-
@Id
- 用于标识一个字段为文档的唯一标识符(_id)。通常映射到MongoDB的
_id
字段。 - 示例:
@Id private String id;
- 用于标识一个字段为文档的唯一标识符(_id)。通常映射到MongoDB的
-
@Field
- 用于指定字段在MongoDB中的名称。如果不使用此注解,字段名称默认与Java类中的字段名称一致。
- 示例:
@Field("user_name") private String username;
-
@Indexed
- 用于为字段创建索引,可以提高查询效率。可以通过参数指定索引类型和方向。
- 示例:
@Indexed private String email;
-
@CompoundIndex
- 用于创建复合索引,可以提高多字段查询的效率。
- 示例:
@CompoundIndex(name="name_age", def="{'firstName': 1, 'age': -1}")
-
@TextIndexed
- 用于为字段创建文本索引,支持全文搜索。
- 示例:
@TextIndexed private String description;
-
@Transient
- 用于标识字段不被持久化到数据库。
- 示例:
@Transient private String tempField;
-
@DBRef
- 用于引用另一个文档,类似于关系数据库的外键。
- 示例:
@DBRef private List<Role> roles;
-
@Version
- 用于乐观锁,自动处理版本控制。每次更新文档时,版本号会自动增加。
- 示例:
@Version private Long version;
-
@CreatedDate
- 自动记录文档的创建时间。
- 示例:
@CreatedDate private Date createdDate;
-
@LastModifiedDate
- 自动记录文档的最后修改时间。
- 示例:
@LastModifiedDate private Date lastModifiedDate;
添加文档
// 1. 选择数据库 (如使用 'test' 数据库)
use mydatabase// 2. 创建 emp 集合并插入文档
db.emp.insertOne({_id:10, name: "John Doe",age: 30,salary: 55000.00,birthday: new Date("1992-05-15")
})// 3. 也可以插入多个文档
db.emp.insertMany([{_id:20name: "Jane Smith",age: 25,salary: 60000.00,birthday: new Date("1997-08-23")},{_id:30name: "Alice Johnson",age: 27,salary: 65000.00,birthday: new Date("1995-03-12")}
])// 4. 查询集合中的所有文档以验证插入是否成功
db.emp.find().pretty()
- insert方法返回值是新增的Document对象,里面包含了新增后id的值。如果集合不存在会自动创建集合。
- 通过Spring Data MongoDB会给集合中多加一个class的属性,存储新增时Document对应Java中类的全限定路径。原因为了查询时能把Document转换为Java类型。
@Document("emp") //对应emp集合中的一个文档
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {@Idprivate Integer id;@Fieldprivate String name;@Fieldprivate int age;@Fieldprivate Double salary;@Fieldprivate Date birthday;
}
/*** 添加文档*/@Testpublic void testInsert(){Employee employee = new Employee(1, "小明", 30,10000.00, new Date());//insert:_id存在抛出异常 支持批量操作mongoTemplate.insert(employee);//sava:_id存在时更新数据mongoTemplate.save(employee);//插入多条数据List<Employee> list = Arrays.asList(new Employee(2,"张三", 21,5000.00, new Date()),new Employee(3,"李四",26,8000.00, new Date()),new Employee(4, "王五",22, 8000.00, new Date()),new Employee(5,"张龙",28,6000.00, new Date()),new Employee(6,"赵虎",24,7000.00, new Date()),new Employee(7,"赵六",28,12000.00, new Date()));Collection<Employee> employees = mongoTemplate.insert(list, Employee.class);System.out.println(employees);}
查询文档
-
Criteria是标准查询的接口,可以引l用静态的criteria.where的把多个条件组合在一起,就可以轻松地将多个方法标准和查询连接起来,方便操作查询语句
-
MongoDB 中
Criteria
查询标准的表格:
Criteria 语法 | MongoDB 中的语法 | 说明 |
---|---|---|
Criteria.where(String key) | { key: ... } | 创建一个以指定键为目标的查询条件。 |
Criteria.andOperator(Criteria... criteria) | $and | 创建一个并且(AND)组合查询条件。 |
Criteria.orOperator(Criteria... criteria) | $or | 创建一个或者(OR)组合查询条件。 |
Criteria.is(Object value) | key: value | 等于指定值。 |
Criteria.ne(Object value) | key: { $ne: value } | 不等于指定值。 |
Criteria.lt(Object value) | key: { $lt: value } | 小于指定值。 |
Criteria.lte(Object value) | key: { $lte: value } | 小于或等于指定值。 |
Criteria.gt(Object value) | key: { $gt: value } | 大于指定值。 |
Criteria.gte(Object value) | key: { $gte: value } | 大于或等于指定值。 |
Criteria.in(Object... values) | key: { $in: [values...] } | 在指定的值列表中。 |
Criteria.nin(Object... values) | key: { $nin: [values...] } | 不在指定的值列表中。 |
Criteria.regex(String regex) | key: { $regex: regex } | 匹配指定的正则表达式。 |
Criteria.exists(boolean exists) | key: { $exists: exists } | 检查字段是否存在。 |
Criteria.type(int type) | key: { $type: type } | 检查字段的 BSON 类型。 |
Criteria.elemMatch(Criteria criteria) | key: { $elemMatch: {...} } | 匹配数组中的元素。 |
Criteria.size(int size) | key: { $size: size } | 检查数组的长度。 |
Criteria.not() | key: { $not: {...} } | 否定条件。 |
Criteria.mod(Number value, Number remainder) | key: { $mod: [value, remainder] } | 按指定值取模。 |
Criteria.all(Object... values) | key: { $all: [values...] } | 数组包含所有指定的元素。 |
Criteria.within(Shape shape) | key: { $geoWithin: {...} } | 地理空间查询,检查点是否在指定的形状内。 |
Criteria.near(Point point) | key: { $near: {...} } | 地理空间查询,查找接近指定点的文档。 |
-
示例解释:
-
Criteria.andOperator
:
Criteria 语法:
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("age").gt(25), Criteria.where("salary").lt(60000));
MongoDB 语法:
{"$and": [{ "age": { "$gt": 25 } },{ "salary": { "$lt": 60000 } }]
}
Criteria.orOperator
:
Criteria 语法:
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("status").is("Active"), Criteria.where("status").is("Pending"));
MongoDB 语法:
{"$or": [{ "status": "Active" },{ "status": "Pending" }]
}
说明:
Criteria
类用于构建复杂的查询条件。- MongoDB 对应语法中,条件操作符通常以
$
开头,例如$and
,$or
,$gt
,$lt
等。 - 使用
Criteria
类可以链式调用,方便地组合多种条件,生成复杂的查询语句。
/*** 查询文档*/@Testpublic void SelectTest() {//查询所有数据List<Employee> all = mongoTemplate.findAll(Employee.class);System.out.println(all);//查询id=1的数据Employee employee = mongoTemplate.findById(1, Employee.class);System.out.println(employee);//无条件查询Employee one = mongoTemplate.findOne(new Query(), Employee.class);System.out.println(one);//查询薪资大于8000的员工Query condition1 = new Query(Criteria.where("salary").gte(8000));System.out.println(mongoTemplate.find(condition1, Employee.class));//查询姓张的员工Query condition2 = new Query(Criteria.where("name").regex("^张"));System.out.println(mongoTemplate.find(condition2, Employee.class));//查询姓张并且薪资大于5000的员工Criteria criteria = new Criteria();criteria.andOperator(Criteria.where("name").regex("^张"),Criteria.where("salary").gt(5000));Query query = new Query(criteria);query.with(Sort.by(Sort.Order.asc("name")));List<Employee> employeeList = mongoTemplate.find(query, Employee.class);employeeList.forEach(System.out::println);}
@Testpublic void testFindBuJson(){String json="{name:'张三'}";BasicQuery query = new BasicQuery(json);mongoTemplate.find(query,Employee.class).forEach(System.out::println);String json2="{$or: [{age:{$gt:25}},{salary:{$gte:8000}}]}";BasicQuery query2 = new BasicQuery(json2);mongoTemplate.find(query2,Employee.class).forEach(System.out::println);}
更新文档
- 在Mongodb中无论是使用客户端APl还是使用SpringData,更新返回结果一定是受行数影响。如果更新后的结果和更新前的结果是相同,返回0。
- updateFirst():只更新满足条件的第一条记录
- updateMulti():更新所有满足条件的记录
- upsert():没有符合条件的记录则插入数据
/*** 更新文档*/@Testpublic void testUpdate(){//query设置查询条件Query query = new Query(Criteria.where("salary").gte(5000));System.out.println("更新前");List<Employee> employees = mongoTemplate.find(query, Employee.class);employees.forEach(System.out::println);//设置更新属性Update update = new Update();update.inc("salary",3000); //加工资//update.inc("salary",-3000); //减工资//只更新满足条件的第一条记录//mongoTemplate.updateFirst(query,update, Employee.class);//更新满足条件的多条记录mongoTemplate.updateMulti(query,update, Employee.class);//upsert 没有符合条件则插入数据Query query2 = new Query(Criteria.where("id").is(12));Update update2 = new Update();update2.setOnInsert("salary",8000);update2.setOnInsert("name","小龙");update2.setOnInsert("age",23);UpdateResult updateResult = mongoTemplate.upsert(query2, update2, Employee.class);//返回修改的记录数System.out.println(updateResult.getModifiedCount());}
删除文档
/*** 删除文档*/@Testpublic void testDelete(){//条件删除Query query = new Query(Criteria.where("id").is(12));mongoTemplate.remove(query,Employee.class);//删除所有文档mongoTemplate.dropCollection("emp"); //推荐//mongoTemplate.remove(new Query(), Employee.class); //不推荐}