MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
这个简单,肯定是存储数据。MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
自行百度吧。。。
mongoDb菜鸟教程可以使用两种方式MongoRepository方式和mongoTemplate方式
public interface LogRepository extends MongoRepository<Log>{ } 复制代码
看一下MongoRepository源码里有什么方法
@NoRepositoryBean public interface MongoRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> { <S extends T> List<S> save(Iterable<S> var1); List<T> findAll(); List<T> findAll(Sort var1); <S extends T> S insert(S var1); <S extends T> List<S> insert(Iterable<S> var1); <S extends T> List<S> findAll(Example<S> var1); <S extends T> List<S> findAll(Example<S> var1, Sort var2); } 复制代码
/** * 根据地址查询 * * @param address * @author zyc * @return */ List<AlarmLog> findByAddress(String address); /** * 根据地址查询带分页 * * @param address * @author zyc * @return */ Page<AlarmLog> findByAddress(String address, Pageable pageable); 复制代码
/** * 根据地址查询带分页 * * @param address * @author zyc * @return */ Page<AlarmLog> findByAddressLike(String address, Pageable pageable); 复制代码
@Query(value="{'address':?0}",fields="{'address':1}") public Page<Person> findByAddressLike(String address,Pageable pageable); 复制代码
个人感觉这种方式更加全面一点,更好理解。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> 复制代码
server: port: 8080 spring: data: mongodb: uri: mongodb://localhost:27017/test01 application: name: myserver 复制代码
@Repository("userDao") public class UserDaoImpl implements UserDao { /** * 由springboot自动注入,默认配置会产生mongoTemplate这个bean */ @Autowired private MongoTemplate mongoTemplate; @Override public void insert(User user) { //插入数据id自增(mongoDB中存在自己的_id,如果不自己定义自增,会默认返回mongoDB中的_id,我看网上说是不建议将_id自增的,因为高并发会影响性能。从这看的https://segmentfault.com/q/1010000006019599) mongoTemplate.insert(user); } @Override public void update(User user) { //根据id修改 update user set name=user.getName(),age=user.getAge() where id =user.getId() mongoTemplate.updateFirst(new Query(Criteria.where("id").is(user.getId())), new Update().set("name", user.getName()).set("age", user.getAge()), User.class); } @Override public List<User> findAll() { //select * from A return mongoTemplate.findAll(User.class); } @Override public User findOne() { //select * from A LIMIT 1 return mongoTemplate.findOne(new Query(), User.class);// 第一条 } @Override public User findById(Long id) { //Select * from A where a.id=id; return mongoTemplate.findById(id, User.class);// id查询 } @Override public List<User> find() { //select name from A where name='10' DBObject dbObject = new BasicDBObject(); dbObject.put("name", "10"); // 查询条件 BasicDBObject fieldsObject = new BasicDBObject(); // 指定返回的字段 fieldsObject.put("name", true); return mongoTemplate.find(new BasicQuery(dbObject, fieldsObject), User.class); } @Override public List<User> findOr() { //select * from A where name='10' or age=13 return mongoTemplate.find( new Query(new Criteria().orOperator(Criteria.where("name").is("10"),Criteria.where("age").is(11))), User.class); } @Override public List<User> findAnd(){ //select * from A where name='13' and id=1 return mongoTemplate.find(new Query(Criteria.where("name").is("13").and("id").is(1)), User.class); } @Override public List<User> findOrAnd() { //select * from A where a.id=1 and (age=9 or name =13) return mongoTemplate.find( new Query(Criteria.where("id").is(1).andOperator(new Criteria().orOperator(new Criteria().orOperator(Criteria.where("age").is(10),Criteria.where("name").is("13"))))), User.class); } @Override public List<User> findDayuXiaoyu(){ //select * from A where age>1 and age<10 //gte大于等于 lte小于等于 //ge大于 lt小于 //ne 不等于 Query ge_lt = new Query(Criteria.where("age").gt(1).lt(10));//大于等于 Query gte_lte = new Query(Criteria.where("age").gte(1).lte(10));//小于等于 Query ne = new Query(Criteria.where("age").ne(5));//不等于 return mongoTemplate.find(ne, User.class); } /** * 模糊查询 regex 完全匹配 "^hzb$" 右匹配 "^.*hzb$" 左匹配 "^hzb.*$" 双开 "^.*hzb.*$" */ @Override public List<User> findLike(){ Query query = new Query(Criteria.where("name").regex("^.*2$")); return mongoTemplate.find(query, User.class); } @Override public List<User> findInNot(){ //in 和not in Query in = new Query(Criteria.where("age").in(5,6,7)); //in Query notIn = new Query(Criteria.where("age").nin(5,6,7)); //not in return mongoTemplate.find(notIn, User.class); } @Override public List<User> findDie(){ Query findDie = new Query(Criteria.where("age").mod(9, 1)); //取模(取余) age % 5==1 return mongoTemplate.find(findDie, User.class); } @Override public List<User> findAllMatching(){ Query findAllMatching = new Query(Criteria.where("list").all(1L,2L)); //all 数据 [name=10, age=10, id=4, list=[1, 2]] //完全匹配返回数据 return mongoTemplate.find(findAllMatching, User.class); } @Override public List<User> findSize(){ Query findSize = new Query(Criteria.where("list").size(2)); //size 数据 [name=10, age=10, id=4, list=[1, 2]] 匹配数组内的元素数量的 list.size =2 返回 return mongoTemplate.find(findSize, User.class); } @Override public List<User> findExists(){ Query findExists = new Query(Criteria.where("list").exists(false)); //exists 判断字段是否为空 等同于sql的 list is null 和 list is not null return mongoTemplate.find(findExists, User.class); } @Override public List<User> findType(){ Query findType = new Query(Criteria.where("list").type(4)); //匹配数据类型 //Double 1 “double” //String 2 “string” //Object 3 “object” //Array 4 “array” //Binary data 5 “binData” //Undefined 6 “undefined” Deprecated. //ObjectId 7 “objectId” //Boolean 8 “bool” //Date 9 “date” //Null 10 “null” //Regular Expression 11 “regex” //DBPointer 12 “dbPointer” Deprecated. //JavaScript 13 “javascript” //Symbol 14 “symbol” Deprecated. //JavaScript (with scope) 15 “javascriptWithScope” //32-bit integer 16 “int” //Timestamp 17 “timestamp” //64-bit integer 18 “long” //Decimal128 19 “decimal” New in version 3.4. //Min key -1 “minKey” //Max key 127 “maxKey” return mongoTemplate.find(findType, User.class); } @Override public List<User> findNot() { Query findDie = new Query(Criteria.where("age").not().mod(9, 1)); //not取反 return mongoTemplate.find(findDie, User.class); } @Override public long count() { Query count = new Query(Criteria.where("age").not().mod(9, 1)); //总条数 return mongoTemplate.count(count, User.class); } @Override public List<?> distinct(){ return mongoTemplate.getCollection("User").distinct("name"); } @Override public List<?> sort(){ Query sort = new Query(); //排序 return mongoTemplate.find(sort.with(new Sort(Direction.DESC, "id")), User.class); } @Override public List<?> limit(){ Query limit = new Query(); //分页 //skip 设置起始数 //limit 设置查询条数 return mongoTemplate.find(limit.skip(1).limit(3), User.class); } } 复制代码
复杂分页查询 我的理解这里的query就是用来封装查询条件的 criteria.and().is() 在这里是构建了一个精准查询的条件,并且用 'and' 相连。
@Override public Page<AlarmLog> findAlarmLog(LogCondition logCondition) { log.info("进入查询告警接口,请求参数LogCondition={}",JSON.toJSONString(logCondition)); int currentPage = logCondition.getCurrentPage(); int pageSize = logCondition.getPageSize(); Date startTime = logCondition.getStartTime(); Query query = new Query(); //设置起始数 query.skip((currentPage - 1) * pageSize); //设置查询条数 query.limit(pageSize); Criteria criteria = new Criteria(); if (StringUtils.isNotEmpty(logCondition.getSystem())) { criteria.and("system").is(logCondition.getSystem()); } if (StringUtils.isNotEmpty(logCondition.getLevel())) { criteria.and("level").is(logCondition.getLevel()); } if (StringUtils.isNotEmpty(logCondition.getHostname())) { criteria.and("hostname").is(logCondition.getHostname()); } if (StringUtils.isNotEmpty(logCondition.getMessage())) { criteria.and("message").is(logCondition.getMessage()); } if (StringUtils.isNotEmpty(logCondition.getStatus())) { criteria.and("status").is(logCondition.getStatus()); } if (StringUtils.isNotEmpty(logCondition.getStartTime()) && StringUtils.isNotEmpty(logCondition.getEndTime())) { criteria.and("createTime").gte(logCondition.getStartTime()).lte(logCondition.getEndTime()); } else if (StringUtils.isNotEmpty(logCondition.getStartTime())) { criteria.and("createTime").gte(logCondition.getStartTime()); } else if (StringUtils.isNotEmpty(logCondition.getEndTime())) { criteria.and("createTime").lte(logCondition.getEndTime()); } query.addCriteria(criteria); query.with(new Sort(Sort.Direction.DESC, "createTime")); List<AlarmLog> alarmLogs = mongoOperations.find(query,AlarmLog.class); log.info("查询结果alarmLogs={}", JSON.toJSONString(alarmLogs)); int count = (int) mongoOperations.count(query, AlarmLog.class); Page<AlarmLog> logPage = new Page<>(); logPage.setRecords(alarmLogs); logPage.setTotal(count); logPage.setCurrent(currentPage); logPage.setSize(pageSize); 复制代码
这里解释一下,上面是最近做的一个查询,是对多个字段可能有可能没有的分页查询,所以我只能用If做判断处理,里面有个查询条件是个开始时间和截止时间内容。对一个字段做两次
criteria.and("createTime").gte() criteria.and("createTime").lte() 复制代码
会报错,所以使用了上面颇为丑陋的if else判断。写的时候查到了这种情况的处理方式,用到 andOperator 方法。试了一下可以。
//大于方法 Criteria gt = Criteria.where("createTime").gte("你的条件"); //小于方法 Criteria lt = Criteria.where("createTime").lte("你的条件"); /** * new Criteria().andOperator(gt,lt) 把上面的大于和小于放在一起,注意上面两个key一定是一样的 * andOperator() 这个方法就是关键的方法了,把同key的多个条件组在一起 * 但是 andOperator() 有个很坑的地方就是,在一个query中只能出现一次 * 如果你有很固定很明确的入参,那还好,直接调用一次 andOperator() * 如果是多个key需要多个条件,而且条件数量还是动态的,怕不是魔鬼吧... */ criteria.andOperator(gte, lte); 复制代码