两种查询方式:

1、JPA

2、MongoTemplate

 

一、JPA

首先是JPA的 简单查询

dao层

public interface DogRepository extends MongoRepository<Dog,String> {

    List<Dog> findByName(String name);

    List<Dog> findByIdAndName(Object id,String name);
}

service实现层,接口层跳过。 

@Service
public class DogServiceImpl implements DogService {

    @Autowired
    private DogRepository dogRepository;

    @Override
    public void delete(String id) {
        Dog dog = new Dog();
        dog.setId(id);
        dogRepository.delete(dog);
    }

    @Override
    public Dog insert(Dog dog) {
        return dogRepository.insert(dog);
    }
    
    @Override
    public Dog update(Dog dog) {
        return dogRepository.save(dog);
    }

    @Override
    public Dog getById(String id) {
        Optional<Dog> user = dogRepository.findById(id);
        return user.orElse(null);
    }

    @Override
    public List<Dog> getList() {
        return dogRepository.findAll();
    }

    @Override
    public List<Dog> findByName(String name) {
        return dogRepository.findByName(name);
    }

    @Override
    public List<Dog> findByIdAndName(Object id, String name) {
        return dogRepository.findByIdAndName(id,name);
    }

  
}

JPA的复杂查询:

ExampleMatchers  应该是比较简单的一个方法

可以直接使用 findAll,就可以实现自定义参数了

如果不是用于匹配,而是整个值匹配,就不需要创建匹配器

JPA 使用匹配器ExampleMatchers,然后传入对象实例,作为查询条件。

 

如果要增加分页的话,可以 创建Pageable对象,传入pageNumber和pageSize就可以了

而且Page对象中封装了数据总数、等信息

 

下面是一个总的复杂查询语句,包含了可能用到的所有语句,可适当增减

//排序
Sort sort = new Sort(Sort.Direction.DESC,"createTime"); 
//分页对象
Pageable pageRequest = PageRequest.of(pageNumber, pageSize,sort);

//创建匹配器
ExampleMatcher example = ExampleMatcher.matching()//构建对象
//属性参数,contains(包含有的查询方式类似模糊查询类似于:%test%)、startbigging(开始匹配类似于:test%);他会排除空字符串和null
        .withMatcher("userName", ExampleMatcher.GenericPropertyMatchers.contains());
//忽略字段,即不管password是什么值都不加入查询条件
.withIgnorePaths("password");
//条件,将查询的参数赋值到对应字段
TrackLog trackLog = new TrackLog();
//条件使用数据中含有userName这个参数的所有数据
trackLog.setUserName(userName);
//创建查询实例;精确查询不要匹配器,直接传入实体
Example<TrackLog> e = Example.of(trackLog, example);


Page<TrackLog> all = trackLogRepository.findAll(e, pageRequest);//查询

第二种 mongoTemplate

简单方式:

 

这里更新语句不一样,要使用update对象设置值

Query query = new Query(Criteria.where("id").is(dog.getId()));
Update update = new Update().set("name",dog.getName()).set("age",dog.getAge());
//更新查询出的结果的第一条
mongoTemplate.updateFirst(query,update,Dog.class);
//更新所有
mongoTemplate.updateMulti(query,update,Dog.class);
@Service
public class DogServiceImplTemplate implements DogService {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Override
    public void delete(String id) {
        Query query = new Query(Criteria.where("id").is(id));
        DeleteResult remove = mongoTemplate.remove(query);
        long c = remove.getDeletedCount();
    }

    @Override
    public Dog insert(Dog dog) {
        dog.setId(null);
        mongoTemplate.insert(dog);
        return null;
    }

    @Override
    public Dog update(Dog dog) {

        Query query = new Query(Criteria.where("id").is(dog.getId()));
        Update update = new Update().set("name",dog.getName()).set("age",dog.getAge());
        //更新查询出的结果的第一条
        mongoTemplate.updateFirst(query,update,Dog.class);
        //更新所有
        UpdateResult updateResult = mongoTemplate.updateMulti(query,update,Dog.class);
        long cout = updateResult.getModifiedCount();
        //return (int)cout;
return null;
    }

    @Override
    public Dog getById(String id) {
        Query query = new Query(Criteria.where("id").is(id));
       Dog dogs = mongoTemplate.findOne(query, Dog.class);
        return dogs;
    }

    @Override
    public List<Dog> getList() {
        return mongoTemplate.findAll(Dog.class);
    }

    @Override
    public List<Dog> findByName(String name) {
       Query query = new Query(Criteria.where("userName").is(name));
        List<Dog> trackLogs = mongoTemplate.find(query, Dog.class);
        return trackLogs;
    }

    @Override
    public List<Dog> findByIdAndName(Object id, String name) {
        Pattern p = Pattern.compile(".*"+name+".*",Pattern.CASE_INSENSITIVE);
        Query query = new Query();
        Criteria criteria ;
        if(id != null && !"".equals(id)){
            query.addCriteria(Criteria.where("id").is(id));
        }
        if(name != null && !"".equals(name)){
            query.addCriteria(Criteria.where("name").is(name));
        }
        List<Dog> dogs = mongoTemplate.find(query, Dog.class);
        return dogs;
    }

    @Override
    public List<Dog> findByNameAndAge(String name, String age) {
        Pattern p = Pattern.compile(".*"+name+".*",Pattern.CASE_INSENSITIVE);
        Query query = new Query();
        if(name != null && !"".equals(name)){
            query.addCriteria(Criteria.where("name").regex(p));
        }
        if(age != null && !"".equals(age)){
            query.addCriteria((Criteria.where("age").is(age)));
        }
        List<Dog> dogs = mongoTemplate.find(query, Dog.class);
        return dogs;
    }
}

复杂方式:

这个和JPA的有些相似,同样用到了Sort和Pageable,但是最终的查询方式不一样,mongodb的分页是query。with(page),查出的结果也是list,所以我们最后有做一个page的封装,将页面总数封装到page对象中去。

这里又有两种查询方式:

下面的复杂查询语句,包含了可能用到的所有语句,可适当增减

1、第一种

这里的toDate是我自定义的方法

//排序
Sort sort = new Sort(Sort.Direction.DESC,"createTime");
//分页对象
Pageable page = PageRequest.of(pageNumber-1,pageSize,sort);
//》第一种构建--------------------
//封装对象
Query query = new Query();
//构建查询条件
if (!StringUtils.isEmpty(userName)) {
     Pattern p = Pattern.compile(".*"+userName+".*");
     query.addCriteria(Criteria.where("userName").regex(p));
}
if (!StringUtils.isEmpty(operationType)) {
     query.addCriteria(Criteria.where("operationType").is(operationType));
}
//》--------------------------
//时间范围(这种方式不推荐,影响效率,但我也没办法);必须这样写,一个条件只能设置一次,这里传入的数据类型是date
if (startTime != null || endTime != null) {
    Criteria criteria = new Criteria("createTime");
    if(!StringUtils.isEmpty(startTime)) {
        criteria.gt(startTime);
    }
    if (!StringUtils.isEmpty(endTime)) {
        criteria.lt(endTime);
    }
    query.addCriteria(criteria);
}
//页总数
long count = mongoTemplate.count(query, TrackLog.class);
//每页数据
List<TrackLog> dogs = mongoTemplate.find(query.with(page), TrackLog.class);
//封装成page对象
Page<TrackLog> dogPage = new PageImpl<>(dogs,page,count);

2、类似于jpa,使用了匹配器ExampleMatcher

//排序
Sort sort = new Sort(Sort.Direction.DESC,"createTime");
//分页对象
Pageable page = PageRequest.of(pageNumber-1,pageSize,sort);
//》第二种方式构建条件-------------------
//创建匹配器
//对象的精准查找不用设置匹配器,不进行判断虽然能查出结果,但结果有一定规律,但不是我们要的
  ExampleMatcher matcher = ExampleMatcher.matching()
                .withIgnoreNullValues()
                .withMatcher("userId",ExampleMatcher.GenericPropertyMatchers.contains())//全局模糊查询:%test%
                .withMatcher("userName",ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("_class",ExampleMatcher.GenericPropertyMatchers.contains())
                .withIgnorePaths("clasDisplayName")//忽略这个字段的匹配
                .withIgnorePaths("createTime")
                .withIgnorePaths("_id");
//创建匹配实例

        Example<TrackLog> ex = Example.of(trackLog,matcher);
//封装对象
Query query = new Query();
query.addCriteria(Criteria.byExample(ex));
//》----------------------------
//时间范围(这种方式不推荐,影响效率,但我也没办法);必须这样写,一个条件只能设置一次,这里传入的数据类型是date
if (startTime != null || endTime != null) {
    Criteria criteria = new Criteria("createTime");
    if(!StringUtils.isEmpty(startTime)) {
        criteria.gt(startTime);
    }
    if (!StringUtils.isEmpty(endTime)) {
        criteria.lt(endTime);
    }
    query.addCriteria(criteria);
}
//页总数
long count = mongoTemplate.count(query, TrackLog.class);
//每页数据
List<TrackLog> dogs = mongoTemplate.find(query.with(page), TrackLog.class);
//封装成page对象
Page<TrackLog> dogPage = new PageImpl<>(dogs,page,count);