两种查询方式:
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);