文章目录
SpringBoot整合MongoDB
-
创建项目,添加依赖,配置连接
xml<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>
yamlspring: data: mongodb: # uri: mongodb://xxx:xxx@192.168.1.x:27017/database_name?authSource=admin host: 192.168.1.x port: 27017 username: xxx password: xxx database: mydatabase_name authentication-database: admin
-
连接测试
java@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); }); }
-
集合操作
java/** * 创建集合测试 */ @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;
添加文档
sql
// 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:20
name: "Jane Smith",
age: 25,
salary: 60000.00,
birthday: new Date("1997-08-23")
},
{
_id:30
name: "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类型。
java
@Document("emp") //对应emp集合中的一个文档
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
@Id
private Integer id;
@Field
private String name;
@Field
private int age;
@Field
private Double salary;
@Field
private Date birthday;
}
java
/**
* 添加文档
*/
@Test
public 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 语法:
java
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("age").gt(25), Criteria.where("salary").lt(60000));
MongoDB 语法:
json
{
"$and": [
{ "age": { "$gt": 25 } },
{ "salary": { "$lt": 60000 } }
]
}
Criteria.orOperator
:
Criteria 语法:
java
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("status").is("Active"), Criteria.where("status").is("Pending"));
MongoDB 语法:
json
{
"$or": [
{ "status": "Active" },
{ "status": "Pending" }
]
}
说明:
Criteria
类用于构建复杂的查询条件。- MongoDB 对应语法中,条件操作符通常以
$
开头,例如$and
,$or
,$gt
,$lt
等。 - 使用
Criteria
类可以链式调用,方便地组合多种条件,生成复杂的查询语句。
java
/**
* 查询文档
*/
@Test
public 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);
}
java
@Test
public 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():没有符合条件的记录则插入数据
java
/**
* 更新文档
*/
@Test
public 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());
}
删除文档
java
/**
* 删除文档
*/
@Test
public 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); //不推荐
}