本文目录导读:

我来详细介绍 SpringBoot 集成 MongoDB 的方法和最佳实践。
添加依赖
<!-- Maven 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
配置文件
application.yml
spring:
data:
mongodb:
uri: mongodb://localhost:27017/mydb
# 或者使用详细配置
host: localhost
port: 27017
database: mydb
username: user
password: pass
authentication-database: admin
# 连接池配置
options:
min-connections-per-host: 10
max-connections-per-host: 50
connect-timeout: 30000
socket-timeout: 60000
max-wait-time: 120000
server-selection-timeout: 30000
application.properties
spring.data.mongodb.uri=mongodb://localhost:27017/mydb spring.data.mongodb.host=localhost spring.data.mongodb.port=27017 spring.data.mongodb.database=mydb
实体类定义
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.time.LocalDateTime;
import java.util.List;
@Document(collection = "users") // 指定集合名称
public class User {
@Id
private String id;
@Indexed(unique = true) // 创建唯一索引
private String username;
@Field("email_address") // 自定义字段名
private String email;
private String password;
@Indexed
private Integer age;
private List<String> hobbies;
private Address address;
@Field("created_at")
private LocalDateTime createdAt;
@Field("updated_at")
private LocalDateTime updatedAt;
// 关联引用
@DBRef // 引用其他文档
private List<Order> orders;
// getters and setters
}
// 嵌入式文档
public class Address {
private String province;
private String city;
private String street;
private String zipCode;
// getters and setters
}
Repository 层
基础 CRUD Repository
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface UserRepository extends MongoRepository<User, String> {
// 根据字段查询
Optional<User> findByUsername(String username);
List<User> findByAgeGreaterThan(int age);
List<User> findByHobbiesContaining(String hobby);
// 使用 @Query 自定义查询
@Query("{ 'address.city': ?0 }")
List<User> findByCity(String city);
@Query("{ 'username': { $regex: ?0, $options: 'i' } }")
List<User> findByUsernameLike(String username);
// 分页查询
@Query("{ 'age': { $gte: ?0, $lte: ?1 } }")
List<User> findByAgeBetween(int min, int max, Pageable pageable);
// 聚合查询
@Aggregation(pipeline = {
"{ '$group': { '_id': '$address.city', 'count': { '$sum': 1 } } }",
"{ '$sort': { 'count': -1 } }"
})
List<CityCount> countUsersByCity();
}
// 聚合结果映射
public class CityCount {
private String id; // 城市名
private int count; // 用户数
// getters and setters
}
自定义 Repository 实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class CustomUserRepositoryImpl implements CustomUserRepository {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public void updateUserEmail(String userId, String newEmail) {
Query query = Query.query(Criteria.where("_id").is(userId));
Update update = Update.update("email_address", newEmail);
mongoTemplate.updateFirst(query, update, User.class);
}
@Override
public List<User> findUsersByDynamicCriteria(DynamicQuery query) {
Query mongoQuery = new Query();
if (query.getUsername() != null) {
mongoQuery.addCriteria(Criteria.where("username").is(query.getUsername()));
}
if (query.getMinAge() != null && query.getMaxAge() != null) {
mongoQuery.addCriteria(Criteria.where("age")
.gte(query.getMinAge())
.lte(query.getMaxAge()));
}
if (query.getCity() != null) {
mongoQuery.addCriteria(Criteria.where("address.city").is(query.getCity()));
}
return mongoTemplate.find(mongoQuery, User.class);
}
}
// 动态查询条件
public class DynamicQuery {
private String username;
private Integer minAge;
private Integer maxAge;
private String city;
// getters and setters
}
public interface CustomUserRepository {
void updateUserEmail(String userId, String newEmail);
List<User> findUsersByDynamicCriteria(DynamicQuery query);
}
Service 层
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private CustomUserRepository customUserRepository;
// 创建用户
public User createUser(User user) {
user.setCreatedAt(LocalDateTime.now());
user.setUpdatedAt(LocalDateTime.now());
return userRepository.save(user);
}
// 批量创建
public List<User> createUsers(List<User> users) {
users.forEach(user -> {
user.setCreatedAt(LocalDateTime.now());
user.setUpdatedAt(LocalDateTime.now());
});
return userRepository.saveAll(users);
}
// 查询所有用户
public List<User> getAllUsers() {
return userRepository.findAll();
}
// 分页查询
public Page<User> getUsersByPage(int page, int size) {
PageRequest pageRequest = PageRequest.of(page, size, Sort.by("createdAt").descending());
return userRepository.findAll(pageRequest);
}
// 根据 ID 查询
public Optional<User> getUserById(String id) {
return userRepository.findById(id);
}
// 更新用户
public User updateUser(String id, User userDetails) {
return userRepository.findById(id)
.map(user -> {
user.setUsername(userDetails.getUsername());
user.setEmail(userDetails.getEmail());
user.setAge(userDetails.getAge());
user.setHobbies(userDetails.getHobbies());
user.setAddress(userDetails.getAddress());
user.setUpdatedAt(LocalDateTime.now());
return userRepository.save(user);
})
.orElseThrow(() -> new RuntimeException("User not found with id: " + id));
}
// 部分更新
public void updateEmail(String userId, String newEmail) {
customUserRepository.updateUserEmail(userId, newEmail);
}
// 删除用户
public void deleteUser(String id) {
userRepository.deleteById(id);
}
// 高级查询
public List<User> findUsersByAgeRange(int min, int max) {
return userRepository.findByAgeBetween(min, max,
PageRequest.of(0, 10, Sort.by("age").ascending()));
}
}
Controller 层
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
User created = userService.createUser(user);
return new ResponseEntity<>(created, HttpStatus.CREATED);
}
@PostMapping("/batch")
public ResponseEntity<List<User>> createUsers(@Valid @RequestBody List<User> users) {
List<User> created = userService.createUsers(users);
return new ResponseEntity<>(created, HttpStatus.CREATED);
}
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.getAllUsers();
return ResponseEntity.ok(users);
}
@GetMapping("/page")
public ResponseEntity<Page<User>> getUsersByPage(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Page<User> userPage = userService.getUsersByPage(page, size);
return ResponseEntity.ok(userPage);
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable String id) {
return userService.getUserById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable String id, @Valid @RequestBody User user) {
User updated = userService.updateUser(id, user);
return ResponseEntity.ok(updated);
}
@PatchMapping("/{id}/email")
public ResponseEntity<Void> updateEmail(
@PathVariable String id,
@RequestParam String email) {
userService.updateEmail(id, email);
return ResponseEntity.ok().build();
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable String id) {
userService.deleteUser(id);
return ResponseEntity.noContent().build();
}
}
索引管理
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.GeospatialIndex;
import org.springframework.stereotype.Component;
@Component
public class IndexInitializer implements CommandLineRunner {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public void run(String... args) throws Exception {
// 创建复合索引
mongoTemplate.indexOps(User.class)
.ensureIndex(new org.springframework.data.mongodb.core.index.Index()
.on("username", Sort.Direction.ASC)
.on("age", Sort.Direction.ASC)
.unique());
// 创建文本索引
mongoTemplate.indexOps(User.class)
.ensureIndex(new org.springframework.data.mongodb.core.index.Index()
.on("hobbies", Sort.Direction.ASC));
// 创建地理位置索引
mongoTemplate.indexOps(Store.class)
.ensureIndex(new GeospatialIndex("location"));
}
}
高级特性
GridFS 文件存储
import com.mongodb.client.gridfs.GridFSFindIterable;
import com.mongodb.client.gridfs.model.GridFSFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsOperations;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.List;
@Service
public class FileService {
@Autowired
private GridFsOperations gridFsOperations;
public String storeFile(MultipartFile file) throws Exception {
try (InputStream inputStream = file.getInputStream()) {
// 存储文件到 GridFS
String fileId = gridFsOperations.store(
inputStream,
file.getOriginalFilename(),
file.getContentType()
).toString();
return fileId;
}
}
public GridFsResource getFile(String fileId) {
GridFSFile gridFSFile = gridFsOperations.findOne(
Query.query(Criteria.where("_id").is(fileId)));
return gridFsOperations.getResource(gridFSFile);
}
public void deleteFile(String fileId) {
gridFsOperations.delete(Query.query(Criteria.where("_id").is(fileId)));
}
}
事务支持 (MongoDB 4.0+)
import org.springframework.transaction.annotation.Transactional;
@Service
public class TransactionalService {
@Autowired
private UserRepository userRepository;
@Autowired
private OrderRepository orderRepository;
@Transactional
public void createUserWithOrder(User user, Order order) {
// MongoDB 支持事务且使用副本集
userRepository.save(user);
orderRepository.save(order);
}
}
注意事项
配置 MongoDB 连接池
spring:
data:
mongodb:
uri: mongodb://localhost:27017/mydb
options:
min-connections-per-host: 10
max-connections-per-host: 50
connect-timeout: 30000
read-timeout: 5000
write-concern: ACKNOWLEDGED
read-preference: PRIMARY_PREFERRED
性能优化建议
- 合理使用索引
- 避免频繁的关联查询
- 使用批量操作
- 合理设置连接池大小
- 使用投影查询减少数据传输
这样你就完成了 SpringBoot 集成 MongoDB 文档存储的完整配置和开发,记得根据实际需求调整配置和功能。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播