github:https://github.com/Ccww-lx/Sp...
在NoSQL盛行的时代,App很大可能会涉及到MongoDB数据库的使用,而也必须学会在Spring boot使用Spring Data连接MongoDB进行数据增删改查操作,如下为详细的操作手册。
依赖
直接导入spring-data-mongodb包或者使用Spring Boot starter
<dependencies>
<!-- other dependency elements omitted -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.2 .0 .RELEASE</version>
</dependency>
</dependencies>
<!--spring 框架使用最新的 -->
<spring.framework.version>5.2 .0 .RELEASE</spring.framework.version>
<!--用一即可-->
<!--使用Spring Boot starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
属性文件application.properties
#mongodb连接地址,集群用“;”隔开
spring.mongo.mongoDatabaseAddress =10.110 .112.165 :27092 ;10.110 .112.166 :27092
#mongo数据名
spring.mongo.dbname =mongodb
#mongo用户
spring.mongo.username =mongodbopr
#mongo密码
spring.mongo.password =123456
#mongo最大连接数
spring.mongo.connectionsPerHost =50
mongoDB 配置
注册Mongo实例配置:
@Configuration
public class MongodbConfig {
public static final String COMMA = " ; " ;
public static final String COLON = " : " ;
@Value( " ${spring.mongo.mongoDatabaseAddress} " )
private String mongoDatabaseAddress;
@Value( " ${spring.mongo.username} " )
private String username;
@Value( " ${spring.mongo.dbname} " )
private String dbname;
@Value( " ${spring.mongo.password} " )
private String password;
@Value( " ${spring.mongo.connectionsPerHost} " )
private String connectionsPerHost;
/* *
* 获取mongodb的地址
*
* @return
*/
private List<ServerAddress> getMongoDbAddress() {
List <ServerAddress> serverAddrList = new ArrayList<ServerAddress>();
// 如果有多个服务器的话
if (this .mongoDatabaseAddress.indexOf(COMMA) > 0 ) {
String[] addressArrays = mongoDatabaseAddress.split(COMMA);
String[] hostPort;
for (String address : addressArrays) {
hostPort = address.split(COLON);
ServerAddress serverAdress = new ServerAddress(hostPort[0 ], Integer.valueOf(hostPort[1 ]));
serverAddrList.add(serverAdress);
}
} else {
String[] hostPort = mongoDatabaseAddress.split(COLON);
ServerAddress serverAdress = new ServerAddress(hostPort[0 ], Integer.valueOf(hostPort[1 ]));
serverAddrList.add(serverAdress);
}
return serverAddrList;
}
/* *
* 设置连接参数
*/
private MongoClientOptions getMongoClientOptions() {
MongoClientOptions.Builder builder = MongoClientOptions.builder();
// todo 添加其他参数配置
// 最大连接数
builder.connectionsPerHost(Integer.valueOf(connectionsPerHost));
MongoClientOptions options = builder.readPreference(ReadPreference.nearest()).build();
return options;
}
/* *
*
* @return
*/
@Bean
public MongoClient mongoClient() {
// 使用数据库名、用户名密码登录
MongoCredential credential = MongoCredential.createCredential(username, dbname, password.toCharArray());
// 创建Mongo客户端
return new MongoClient(getMongoDbAddress(), credential, getMongoClientOptions());
}
/* *
* 注册mongodb操作类
* @param mongoClient
* @return
*/
@Bean
@ConditionalOnClass(MongoClient. class )
public MongoTemplate mongoTemplate(MongoClient mongoClient) {
MongoTemplate mongoTemplate = new MongoTemplate(new SimpleMongoDbFactory(mongoClient, dbname));
return mongoTemplate;
}
}
mongoDB操作
使用MongoTemplate类进行增删改查
@Service
public class MongodbService {
@Autowired
private MongoTemplate mongoTemplate;
/* *
* 新增文档
*
* @param userDTO
* @return
*/
public UserDTO insert(UserDTO userDTO) {
// insert方法并不提供级联类的保存,所以级联类需要先自己先保存
return mongoTemplate.insert(userDTO);
}
public UserDTO save(UserDTO userDTO) {
Sort sort = new Sort(Sort.Direction.DESC, " name " );
userDTO = mongoTemplate.findOne(Query.query(Criteria.where ("" )).with(sort), UserDTO.class );
return mongoTemplate.save(userDTO);
}
/* *
* 删除文档
* NOTE:remove方法不支持级联删除所以要单独删除子数据
* @param name
*/
public void remove(String name) {
// 根据名字查询数据并删除
UserDTO userDTO = mongoTemplate.findOne(Query.query(Criteria.where (" name " ).is (name)), UserDTO.class );
// remove方法不支持级联删除所以要单独删除子数据
List<AddressDTO> addressList = userDTO.getAddressList();
for (AddressDTO addressDTO : addressList) {
mongoTemplate.remove(addressDTO);
}
// 删除主数据
mongoTemplate.remove(userDTO);
}
/* *
* 更新文档
* @param userDTO
*/
public void update(UserDTO userDTO) {
mongoTemplate.updateFirst(Query.query(Criteria. where (" name " ).is (userDTO.getName())), Update.update(" age " , userDTO.getAge()), UserDTO.class );
}
/* *
* 查询文档
* @param name
*/
public void find(String name) {
Sort sort = new Sort(Sort.Direction.DESC, " name " );
List <UserDTO> userDTOS = mongoTemplate.find(Query.query(Criteria.where (" name " ).is (name)), UserDTO.class );
// 基于sort排序使用findOne查询最新一条记录
UserDTO userDTO = mongoTemplate.findOne(Query.query(Criteria.where (" name " ).is (name)).with(sort), UserDTO.class );
// 模糊查询
List<UserDTO> userDTOList = mongoTemplate.find(Query.query(Criteria.where (" name " ).is (name).regex(name)).with(sort), UserDTO.class );
// 分页查询
Pageable pageable = PageRequest.of(3 , 20 , sort);
List <UserDTO> userDTOPageableList = mongoTemplate.find(Query.query(Criteria.where (" name " ).is (name)).with(pageable), UserDTO.class );
// 总数
long conut = mongoTemplate.count(Query.query(Criteria.where (" name " ).is (name)), UserDTO.class );
Page <UserDTO> page = new PageImpl(userDTOPageableList, pageable, conut);
}
}
NOTE: 在开发中,如果从任何MongoDB操作返回的com.mongodb.WriteResult包含错误,则可以方便地记录或引发异常。 通常,在开发过程中很容易忘记执行此操作,然后最终得到一个看似运行成功的App,但实际上该数据库操作发生异常,没执行成功。 可以将MongoTemplate的WriteResultChecking属性设置为以下值之一:
EXCEPTION:引发Exception
NONE:不执行任何操作,默认值
对于更高级的情况,可以将每个操作设置不同的WriteConcern值(用于删除,更新,插入和保存操作),则可以在MongoTemplate上配置WriteConcernResolver的策略接口。 由于MongoTemplate用于持久化POJO,因此WriteConcernResolver允许您创建一个策略,该策略可以将特定的POJO类映射到WriteConcern值。
WriteConcernResolver接口:
public interface WriteConcernResolver {
WriteConcern resolve(MongoAction action);
}
自定义WriteConcernResolver接口,实现不同WriteConcern策略:
private class MyAppWriteConcernResolver implements WriteConcernResolver {
public WriteConcern resolve(MongoAction action) {
if (action.getEntityClass().getSimpleName().contains(" UserDTO " )) {
return WriteConcern.NONE;
} else if (action.getEntityClass().getSimpleName().contains(" Metadata " )) {
return WriteConcern.JOURNAL_SAFE;
}
return action.getDefaultWriteConcern();
}
}
常用的类以及方法解析
5.1 MongoClient、ServerAddress、MongoCredential以及MongoClientOptions
基于ServerAddress单机或者Replica Set在使用MongoClient连接mongodb数据库注册mongo实例,在注册示例中可能要使得MongoCredential账号密码验证以及使用MongoClientOptions配置mongodb其他的参数。
MongoClient常用的构造器方法:
public MongoClient(String host){}
public MongoClient(MongoClientURI uri){}
public MongoClient(String host, MongoClientOptions options) {}
public MongoClient(ServerAddress addr, MongoCredential credential, MongoClientOptions options){}
public MongoClient(List<ServerAddress> seeds, MongoCredential credential, MongoClientOptions options){}
5.2 MongoTemplate
使用MongoTemplate结合Sort、Criteria、Query、Update以及分页Pageable类灵活地进行对mongodb数据库进行增删改查。
query方法:
// 根据查询条件查询
public <T> List<T> find(Query query, Class<T> entityClass){}
// 根据查询条件查询返回一条记录
public <T> <T>findOne(Query query, Class<T> entityClass){}
// 查询该collection所有记录
public <T> List<T> findAll(Class<T> entityClass){}
insert方法:
// 新增一条记录
public <T> T insert(T objectToSave){}
// 在collectionName中新增一条记录
public <T> T insert(T objectToSave, String collectionName) {}
//
public <T> T save(T objectToSave){}
remove方法:
// 根据Object删除
public DeleteResult remove(Object object ) {}
// 根据查询条件进行删除
public DeleteResult remove(Query query, Class<?> entityClass){}
update方法:
//
public UpdateResult upsert(Query query, Update update, Class<?> entityClass) {}
// 更新查询出来的第一条记录
public UpdateResult updateFirst(Query query, Update update, String collectionName) {}
5.3 Sort
Sort查询排序类。Sort类常用方法:
// 构造方法创建一个排序。direction为排序方向的枚举类型,properties为排序字段数组
Sort(Sort.Direction direction, String... properties)
// 多个排序条件链接
and(Sort sort)
// 返回升序排列对象
ascending()
// 返回降序排列对象
descending()
5.4 Criteria
Criteria查询条件类,类似于SQL的where,常用方法:
// 声明定义查询条件,且为静态方法
where (String key)
// 与操作
and(String key)
// 正则表达式,即可为模糊查询
regex(String re)
// 包含
in (Object... o)
// 大于
gt(Object o)
// 大于等于
gte(Object o)
// 等于
is (Object o)
// 小于
lt(Object o)
// 小于等于
lte(Object o)
// 非
not()
// 创建与操作
andOperator(Criteria... criteria)
5.5 Query
Query查询对象,具有查询的全部信息,其中包括筛选条件、排序、返回数量等。常用的方法:
// 定义查询对象,静态方法
query(CriteriaDefinition criteriaDefinition)
// 在本次查询添加一个CriteriaDefinition查询条件
addCriteria(CriteriaDefinition criteriaDefinition)
// 添加一个Sort排序对象
with(Sort sort)
// 添加一个Pageable分页对象、通常情况下,分页和排序一起使用。
with(Pageable pageable)
详细接口信息可查看【MogoDB API官方文档】
常用注解
注解 解析
@Id
用于标记id字段,没有标记此字段的实体也会自动生成id字段,但是我们无法通过实体来获取id。id建议使用ObjectId类型来创建
@Document
用于标记此实体类是mongodb集合映射类
@DBRef
用于指定与其他集合的级联关系,但是需要注意的是并不会自动创建级联集合
@Indexed
用于标记为某一字段创建索引
@CompoundIndex
用于创建复合索引
@TextIndexed:
用于标记为某一字段创建全文索引
@Language
指定documen语言
@Transient:
被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性
@Field:
用于指定某一个字段映射到数据库中的名称
来源:https://www.cnblogs.com/21-Gram/p/12014944.html