推荐个大神写的 mongo实现动态查询
https://www.cnblogs.com/wslook/p/9275861.html
下面试学习mongoDB的基本使用,这里使用的是spring boot 集成 mongodb
安装好mongoDB之后,需要在项目pom中导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
配置参数
spring:
data:
mongodb:
host: xx.xx.xx.xx
port: xxxx
username: xxxx
password: xxxx
database: xxxx
#设置允许文件大小
servlet:
multipart:
max-file-size: 200MB
max-request-size: 200MB
Q1:集合是什么?
答:等同于 mysql 中的 table
Q2:spring boot怎么操作 mongo?
答:可以直接使用mongoTemplate的API,也可以使用MongoRepository的API。
mongoTemplate类似于JDBCTemplate,MongoRepository类似于mybatis
主键使用Long型,mongo默认使用 _id作为主键
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
public class DemoEasy {
/**
* 主键id
* @Id 注解会将对象里的id字段,转化为mongodb中的 _id
* _id默认是ObjectId类型(有4个字段),但是ObjectId.toString() 会得到一个字符串,后续查询使用要使用这个字符串
**/
@Id
private Long id;
/**
* 姓名
**/
private String name;
/**
* 年龄
**/
private Integer age;
/**
* 工作
**/
private String job;
/**
* 兴趣爱好
**/
private String like;
/**
* 备注
**/
private String remark;
/**
* 备注
**/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime = new Date();
}
说明:
1:如果不使用MongoRepository,那么可以不用写这个接口和实现类。
只需要在controller类里面直接用mongoTemplate。
2:如果仅用MongoRepository自带的API,可以不写实现类。
import com.tao.demoEasy.model.DemoEasy;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
public interface IDemoEasyService extends MongoRepository<DemoEasy, Long> {
List<DemoEasy> findByName(String name);
}
import com.tao.demoEasy.model.DemoEasy;
import com.tao.demoEasy.service.IDemoEasyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
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.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
import java.util.List;
public class DemoEasyServiceImpl extends SimpleMongoRepository<DemoEasy, Long> implements IDemoEasyService {
@Autowired
private MongoTemplate mongoTemplate;
public DemoEasyServiceImpl(MongoEntityInformation<DemoEasy, Long> metadata, MongoOperations mongoOperations) {
super(metadata, mongoOperations);
}
@Override
public List<DemoEasy> findByName(String name) {
List<DemoEasy> retult = mongoTemplate.find(Query.query(Criteria.where("name").regex(name)), DemoEasy.class);
return retult;
}
}
1:使用mongoTemplate
mongoTemplate可以结合Criteria、Aggregation、Query等实现动态查询,当然实现代码要稍微复杂些
@Autowired
private MongoTemplate mongoTemplate;
//---------------------------使用 mongoTemplate 进行查询 ---------------------------------
@RequestMapping(value = "save", method = RequestMethod.POST)
public String save(@RequestBody JSONObject jsonObject) {
JSONObject demoEasy = mongoTemplate.save(jsonObject, "demoEasy");
return demoEasy.getString("_id");
}
@RequestMapping(value = "find", method = RequestMethod.POST)
public JSONObject find(@RequestBody JSONObject jsonObject) {
Query query = new Query(Criteria.where("_id").is(jsonObject.getString("id")));
JSONObject one = mongoTemplate.findOne(query, JSONObject.class);
return one;
}
@RequestMapping(value = "update", method = RequestMethod.POST)
public Object update(@RequestBody DemoEasy model) {
//查询条件
Query query = new Query(Criteria.where("id").is(model.getId()));
//按需更新字段
Update update = new Update();
if (StringUtils.isNotBlank(model.getName())) {
update.set("name", model.getName());
}
if (StringUtils.isNotBlank(model.getJob())) {
update.set("job", model.getJob());
}
if (null != model.getAge()) {
update.set("age", model.getAge());
}
if (StringUtils.isNotBlank(model.getRemark())) {
update.set("remark", model.getRemark());
}
//执行更新语句
return mongoTemplate.updateFirst(query, update, DemoEasy.class);
}
2:使用MongoRepository
MongoRepository自带的API用起来要简单些…要先熟悉下ExampleMatcher 的用发
@Autowired
private IDemoEasyService iDemoEasyService;
//---------------------------使用 demoEasyService MongoRepository 进行查询 ---------------------------------
/**
* 增加单个对象
**/
@RequestMapping(value = "insert", method = RequestMethod.POST)
public DemoEasy insert(@RequestBody DemoEasy model) {
model.setCreateTime(new Date());
DemoEasy save = iDemoEasyService.save(model);
return save;
}
/**
* 增加多个对象
**/
@RequestMapping(value = "insertBatch", method = RequestMethod.POST)
public List<DemoEasy> insertBatch(@RequestBody List<DemoEasy> model) {
List<DemoEasy> save = iDemoEasyService.saveAll(model);
return save;
}
/**
* 根据id删除一个数据
**/
@RequestMapping(value = "remove", method = RequestMethod.POST)
public void remove(@RequestBody DemoEasy model) {
iDemoEasyService.deleteById(model.getId());
}
@RequestMapping(value = "findById", method = RequestMethod.POST)
public Object findById(@RequestBody DemoEasy model) {
log.debug("--mongodb_tao开始查询 jSONObject集合");
return iDemoEasyService.findById(model.getId());
}
/**
* 分页查询
**/
@RequestMapping(value = "listPage", method = RequestMethod.POST)
public Page<DemoEasy> listPage(@RequestBody DemoEasy model) {
//排序
Sort sort = new Sort(Sort.Direction.DESC, "createTime");
//设置分页参数 -- 默认分页参数
PageRequest pageRequest = PageRequest.of(0, 5, sort);
if (model.getPageNum() != null && model.getPageSize() != null) {
pageRequest = PageRequest.of((model.getPageNum()-1), model.getPageSize(), sort);
}
//查询条件:模糊匹配name字段
ExampleMatcher matcher = ExampleMatcher.matching().
//改变默认字符串匹配为:模糊查询
withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING).
//name字段模糊匹配
withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());
DemoEasy query = new DemoEasy();
query.setName(model.getName());
Example<DemoEasy> example = Example.of(query, matcher); //动态查询
Page<DemoEasy> result = iDemoEasyService.findAll(example, pageRequest);
return result;
}
/**
* todo 列表查询全量数据
* 条件:name字段模糊匹配 根据id进行排序
**/
@RequestMapping(value = "list", method = RequestMethod.POST)
public List<DemoEasy> list(@RequestBody DemoEasy model) {
//排序
Sort sort = new Sort(Sort.Direction.DESC, "createTime");
//模糊匹配
ExampleMatcher matcher = ExampleMatcher.matching().
withMatcher("name", ExampleMatcher.GenericPropertyMatcher::contains);
//查询
Example<DemoEasy> example = Example.of(model, matcher);
List<DemoEasy> result = iDemoEasyService.findAll(example, sort);
return result;
}
Q1:都说mongo可以直接存储各种文档的。那么到底要怎么实现(通过API直接把各种文件直接存到mongo中)?
答: 使用GridFsTemplate的API,可以直接把文件写入mongo。
主要是用在GridFS的数据源(类似于备注),所有没有这个对象也可以。
@Data
public class BaseFileModel {
@Id
private Long id;
private Long fileSize;
private String fileBeLong;
private String remark;
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
@Configuration
public class MongoConfig {
@Bean
public GridFsTemplate gridFsTemplate(MongoDbFactory dbFactory, MongoConverter converter) {
return new GridFsTemplate(dbFactory, converter, "gridFS_tao");
}
}
@RestController
@RequestMapping(value = "fileMongo")
public class FileMongoController {
@Autowired
private GridFsTemplate gridFsTemplate;
/**
* 文件的存储
**/
@RequestMapping(value = "saveFile", method = RequestMethod.POST)
public String saveFile(@RequestParam(value = "file") MultipartFile file, @RequestParam(value = "fileName") String fileName) throws IOException {
InputStream inputStream = file.getInputStream();
//BaseFileModel baseFileModel = new BaseFileModel();
//baseFileModel.setFileSize(file.getSize());
//baseFileModel.setRemark("test file save");
//baseFileModel.setFileBeLong("zhang_san");
//ObjectId store = gridFsTemplate.store(inputStream, fileName, file.getContentType(), baseFileModel);
ObjectId store = gridFsTemplate.store(inputStream, fileName, file.getContentType());
return store.toString();
}
/**
* 获取文件
**/
@RequestMapping(value = "getFile/{id}", method = RequestMethod.GET)
public void getFile(@PathVariable("id") String id, HttpServletResponse response) throws IOException {
GridFSFile gridFSFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id)));
//设置contentType, 这个比较重要,没有的话,会默认返回页面.zip文件,且里面奇奇怪怪的
response.setContentType(gridFSFile.getMetadata().getString("_contentType"));
//获取流对象
GridFsResource resource = gridFsTemplate.getResource(gridFSFile);
//获取流中的数据
byte[] bytes = IOUtils.toByteArray(resource.getInputStream());
OutputStream out = response.getOutputStream();
//byte数组用于存放字节数据
out.write(bytes);
//关闭响应输出流
out.close();
}
/**
* 文件的删除
**/
@RequestMapping(value = "deleteFile/{id}", method = RequestMethod.DELETE)
public void deleteFile(@PathVariable("id") String id, HttpServletResponse response) throws IOException {
gridFsTemplate.delete(new Query(Criteria.where("_id").is(id)));
}
}
以上就是mongo的简单使用。
ps:
1: 搭建mongoDB时,自定义数据库有点坑。
2: ExampleMatcher matcher = ExampleMatcher.matching() 后面跟的条件,只能用’.'连接,不能像mybatis-plus的QueryWrapper一样。不知道有没有更加简介的书写方式