1:需要引用的jar包:
<!-- mongodb链接包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
2:这个包有2个类可以操作数据库的curd
一:MongoRepository
二:MongoTemplate
这里简单说明下2个类的操作方式
首先 MongoRepository简单,但是在操作中,一些复制的查询,或者需要用到map的动态加属性的情况下,操作起来就非常麻烦,相反 MongoTemplate就简单了很多。
先说说MongoRepository的使用:
3:MongoRepository的使用 简单的curd
第一步 Dao层需要写一个接口 ,相当于 mybits里面的mapping接口 如果想要使用map数组,可以自顶一个类去继承map类,MapInfo是自定义的实体。由于想要map类型,所以我自定义了一个MapInfo去继承map对象。
public interface DictionaryHeaderRepository extends MongoRepository<DictionaryHeaderDO, String> {
}
第二步:定义一个对象实体类:数据对象层 data层
主要 :@Document(collection = "dictionaryHeader") 里面的dictionaryHeader就是表名,自定义的
Data
@Document(collection = "dictionaryHeader")
public class DictionaryHeaderDO extends BaseEntity{
//pid供mongodb内部使用
@Id
private String id;
@AutoIncKey
private Long seqId;//序列值
/**
* 编码
*/
private String code;
/**
* 中文名称
*/
private String name;
/**
* 备注说明
*/
private String remarks;
/**
* 状态 0 有效 1 无效 默认是0
*/
private String logic_delete;
}
第三步:保存方法,直接把对象 放入到之前dao层的接口继承的方法 sava中即可,不需要创建表。mongo会自定根据对象创建表。
另外:这里的修改也是该方法,需要注意的是,如果修改时只传需要修改的数据。那么其他字段就会全部清空。所以在修改之前必须先查询该实体对象的所有值,然后对该对象进行修改,再调用save方法,这也是比较坑的地方,用MongoTemplate 就不会出现这样的问题。
/**
* 保存方法
* @param request
*/
@Override
public int SaveInfo(StandardDetailRequest request) {
//对象转换为数据对象
StandardDetailDO data=new StandardDetailDO();
BeanUtils.copyProperties(request, data);
StandardDetailDO count = standardInfoRepository.save(data);
if (count != null) {
return 1;
} else {
return 0;
}
}
第四步:查询方法:其实就是 dao的继承接口中调用findAll方法。这里比较麻烦的就是按条件查询,坑比较多。所以选择了用MongoTemplate类操作。
@Override
public List<DictionaryHeaderDTO> GetHeaderList(int current, int rowCount, String sortId) {
List<DictionaryHeaderDTO> lists = new ArrayList<>();
List<DictionaryHeaderDO> all=dictionaryHeaderRepository.findAll();
lists= all.stream()
.map(a -> {
DictionaryHeaderDTO dto = new DictionaryHeaderDTO();
BeanUtils.copyProperties(a, dto);
return dto;
})
.collect(Collectors.toList());
return lists;
}
第五步:删除 根据上面的方法直接用delete 调用就可以删除具体对象,参数为对象,也可以删除所有用 deleteall。
总结 MongoRepository在curd上不太适合使用,但是MongoRepository既然存在就是有道理的,首先:他非常简单,容易使用,主要他有其他的一些好用的方法,例如,查总页数,数据是否存在,等等,还是很好使用。
4:MongoTemplate的使用
他不需要在dao层用接口去继承方法,直接使用注解即可。
@Autowired
MongoTemplate mongo;
然后就可以对他进行curd方法
查询方法:
注意:里面的COLLECTION_NAME_ATTRIBUTE是一个常量,值是具体的表名。
@Override
public List<EntryAttributeDTO> QueryInfo(EntryAttributeRequest request) {
//添加条件查询
Query query = new Query(Criteria.where("logic_delete").is("0"));
if (!StringUtil.isNullOrEmpty(request.getCode())) {
query.addCriteria(Criteria.where("code").is(request.getCode()));
}
if (!StringUtil.isNullOrEmpty(request.getName())) {
query.addCriteria(Criteria.where("name").is(request.getName()));
}
if (!StringUtil.isNullOrEmpty(request.getId())) {
query.addCriteria(Criteria.where("id").is(request.getId()));
}
// 满足所有条件的数据
List<Map> ans = mongo.find(query, Map.class, TableNameInfo.COLLECTION_NAME_ATTRIBUTE);
List<EntryAttributeDTO> listDOs = MapObjectUtil.listMapParseListObj(ans, EntryAttributeDTO.class);
return listDOs;
}
新增方法:
List<SysUser> userList = new ArrayList<>();
userList.add(new SysUser(11,"1","白小飞","18888888888"));
userList.add(new SysUser(9,"1","白敬亭","13333333333"));
userList.add(new SysUser(5,"1","林宥嘉","14444444444"));
userList.add(new SysUser(6,"1","彭于晏","15555555555"));
userList.add(new SysUser(7,"1","周杰伦","16666666666"));
mongoTemplate.insert(userList, "userList");
修改方法 :
主要是可以根据具体字段进行修改,不需要先查询所有值,用id即可。
Query query = new Query();
query.addCriteria(Criteria.where("id").is(request.getId()));
Update update = new Update();
if(!StringUtil.isNullOrEmpty(request.getName())){
update.set("name", request.getName());
}
if(request.getNum()!=null && request.getNum()>0){
update.set("num", request.getNum());
}
if( request.getParent_Id()>0){
update.set("parent_Id", request.getParent_Id());
}
if(request.getIs_disable()>0){
update.set("is_disable", request.getIs_disable());
}
if(request.getLevel()>0){
update.set("level", request.getLevel());
}
if(!StringUtil.isNullOrEmpty(request.getRemarks())){
update.set("remarks", request.getRemarks());
}
UpdateResult result = mongo.updateFirst(query, update, ModularDO.class);
if(result.getMatchedCount()>0){
count = 1;
}
删除方法:
其实这里是用于逻辑删除方法,修改是否有效
Query , Update 都是 该jar包里面的类。注意引用的时候不要引用错了
@Override
public long deleteInfo(StandardDetailRequest req) {
// 校验数据
if(req==null){
throw new BusinessException(ResultCodeEnum.DATA_NOT_EXIST);
}
if(StringUtil.isNullOrEmpty(req.getId())){
throw new BusinessException(ResultCodeEnum.MISS_PARAM);
}
//对象转换为数据对象
Query query = new Query();
query.addCriteria(Criteria.where("id").is(req.getId()));
Update update = Update.update("logic_delete",req.getLogic_delete()).set("updateAt",req.getUpdateAt()).set("updateBy",req.getUpdateBy());
UpdateResult result = mongo.updateFirst(query, update, StandardDetailDO.class);
return result.getMatchedCount();
}
}
5:这里还有些问题,例如自增长的列怎么做? 其实是mongo在新增了一张表,专门管理自增长的列数据,然后在java里面做一个注解。
在实体对象中加列属性时,一个
//标识注解:标识主键ID需要自动增长
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoIncKey {
}
@AutoIncKey
private Long seqId;//序列值
package com.health.standard.config.mongo;
import com.health.standard.data.AutoIncKey;
import com.health.standard.data.entity.SeqInfo;
import com.health.standard.data.entity.StandardDetailDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
//@Component泛指组件,把SaveEventListener 加入容器
@Component
public class SaveEventListener extends AbstractMongoEventListener<Object>{
@Autowired
MongoTemplate mongo;
@Override
public void onBeforeConvert(BeforeConvertEvent<Object> event) {
final Object source = event.getSource();
if (source != null) {
ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
ReflectionUtils.makeAccessible(field);
// 如果字段添加了我们自定义的AutoIncKey注解
if (field.isAnnotationPresent(AutoIncKey.class)) {
// 设置自增ID
field.set(source, getNextId(source.getClass().getSimpleName()));
}
}
});
}
}
private Long getNextId(String collName) {
Query query = new Query(Criteria.where("collName").is(collName));
Update update = new Update();
update.inc("seqId", 1);
FindAndModifyOptions options = new FindAndModifyOptions();
options.upsert(true);
options.returnNew(true);
SeqInfo seq = mongo
.findAndModify(query, update, options, SeqInfo.class);
return seq.getSeqId();
}
}