IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> [mongo]JPA继承SimpleMongoRepository实现Springboot整合Mongo JPA复杂条件分页查询 -> 正文阅读

[Java知识库][mongo]JPA继承SimpleMongoRepository实现Springboot整合Mongo JPA复杂条件分页查询

因为MongoRepository对复杂查询并不友好,所以继承了其实现类增加了一些新的查询方法;
重写MongoRepository的接口实现参照博文实现:https://www.cnblogs.com/sweetchildomine/p/7732766.html

需要完成的功能:

根据是否删除(isDeleted)、时间(createTime)、用户id(userId)三个条件动态的查询结果集,且完成分页,其中,是否删除、用户手机号为精确查询,时间为范围查询,三个参数皆可为空

遇到的问题:

在这里插入图片描述
以上是一个继承了MongoRepository的接口类,可以发现其并未存在范围查询,所以使用MongoRepository的自带方法并不能实现我们需要的功能。

通过JPA通过的自定义方法可以解决:
在这里插入图片描述
自定义一个创建时间的范围查询,但是存在一个问题就是,参数是动态的,方法名是固定的,这样就需要在业务层根据传入参数的不同做相关的逻辑判断来调不同的方法,差不多要定义八个相关的方法:
ps:Object …… param代表省略的参数

Page<XXX> findByCreateTimeBetweenAndUserIdIsAAndIsDeletedIs(Object …… param);
Page<XXX> findByCreateTimeBetweenAndUserIdIsA(Object …… param);
Page<XXX> findByCreateTimeBetweenAndIsDeletedIs(Object …… param);
Page<XXX> findByUserIdIsAAndIsDeletedIs(Object …… param);
…………

以上就会存在一个弊端,参数越多需要定义的方法名就越多,不支持动态参数;

最终解决方案:

查看MongoRepository的API可以发现一个方法,这个方法既支持动态传参,也支持分页,但弊端是Example不支持范围查询:

<S extends T> Page<S> findAll(Example<S> example, Pageable pageable);

查看此方法的底层实现:

@Override
public <S extends T> Page<S> findAll(final Example<S> example, Pageable pageable) {

	Assert.notNull(example, "Sample must not be null!");
	Assert.notNull(pageable, "Pageable must not be null!");

	Query q = new Query(new Criteria().alike(example)).with(pageable);
	List<S> list = mongoOperations.find(q, example.getProbeType(), entityInformation.getCollectionName());

	return PageableExecutionUtils.getPage(list, pageable,
			() -> mongoOperations.count(q, example.getProbeType(), entityInformation.getCollectionName()));
}

我们可以发现,该方法底层是把Example转换成了Query去查询的,Example支持动态参数不支持范围查询,Query既支持动态参数也支持范围查询,所以,如果我们可以声明一个入参为Query和Pageable的方法就可以实现动态参数查询和范围查询分页了,以下是实现方法:

  • 继承MongoRepository的实现类进行方法扩展:
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoOperations;
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 org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.util.List;

/**
 * MongoRepository扩展
 * liurui
 * @author liurui
 * @param <T>
 * @param <ID>
 */
public class ExtendSimpleMongoRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> {
    private final MongoOperations mongoOperations;
    private final MongoEntityInformation<T, ID> entityInformation;


    public ExtendSimpleMongoRepository(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) {
        super(metadata, mongoOperations);
        this.entityInformation = metadata;
        this.mongoOperations = mongoOperations;
    }

    public <S extends T> Page<S> findAll(final Example<S> example, final Query query, Pageable pageable) {
        Assert.notNull(example, "Sample must not be null!");
        query.addCriteria((new Criteria()).alike(example)).with(pageable);
        List<S> list = this.mongoOperations.find(query, example.getProbeType(), this.entityInformation.getCollectionName());
        return PageableExecutionUtils.getPage(list, pageable, () -> mongoOperations.count(query, example.getProbeType(),entityInformation.getCollectionName()));
    }

    public <S extends T> Page<T> findAll(Query query, Pageable pageable) {
        query.with(pageable);
        List<T> list = mongoOperations.find(query, entityInformation.getJavaType(), entityInformation.getCollectionName());

        return PageableExecutionUtils.getPage(list, pageable,
                () -> mongoOperations.count(query, entityInformation.getJavaType(), entityInformation.getCollectionName()));
    }
}
  • 修改mongo配置中MongoRepository的实现类:
@Configuration
// 通过@EnableMongoRepositories注解的repositoryBaseClass属性可以更换MongoRepository的实现类,通过mongoTemplateRef可以更换不同的mongoTemplate数据源
@EnableMongoRepositories(basePackages = "com.xxx.xxxx.xxx.xxx.repository", repositoryBaseClass = ExtendSimpleMongoRepository.class)
public class MongoConfig {

	// 以下内容省略
}
  • 在所需要使用该方法的Repository类中声明该方法:
import com.odianyun.demo.repository.support.MySimpleMongoRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface SuperVipOpenCardRecordRepository extends MongoRepository<xxxx, Long> {
    Page<xxxx> findAll(Query query, Pageable pageable);
}
  • 使用并进行测试:
    在这里插入图片描述
    在这里插入图片描述

成功完成所需功能。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-04 15:22:29  更:2022-03-04 15:25:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:46:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码