orderby排序慢_使用@OrderBy对Spring Data MongoDB集合进行排序
orderby排序慢
在本文中,我将展示如何使用Spring Data MongoDB使用@OrderBy批注实现排序 。
用例
对于那些以前没有使用过JPA @OrderBy的人来说,这只是一个简短的例子。 我们这里有两个类和一对多关系:
package pl.maciejwalkowiak.springdata.mongodb.domain;import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;@Document
public class Backpack {@Idprivate ObjectId id;private List<Item> items;...
}
public class Item {private String name;private int price;...
}
背包在这里是主要类别,其中包含嵌入式物品清单。 从数据库中装入背包时,其项目将按接近插入顺序的顺序装入。 如果我们想更改它并按其字段之一订购商品怎么办? 我们需要自己实现排序,然后再次扩展AbstractMongoEventListener 。
排序详细信息:介绍@OrderBy
与JPA相反,在这种情况下,排序不能在数据库级别进行。 我们需要在应用程序端注意这一点–可以在两个地方完成:
- 在将对象转换为MongoDB数据结构之前–如果我们要确保在MongoDB集合中正确对对象进行排序
- 将对象从MongoDB数据结构转换为Java对象之后–如果我们只想确保应用程序内部的List正确排序
为了指定应该在哪个位置进行排序,我创建了SortPhase枚举:
public enum SortPhase {AFTER_CONVERT,BEFORE_CONVERT;
}
最后– @OrderBy批注将包含三个几乎自我描述的属性:
package pl.maciejwalkowiak.springdata.mongodb;import org.springframework.data.mongodb.core.query.Order;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface OrderBy {/*** Field name*/String value();Order order() default Order.ASCENDING;SortPhase[] phase() default SortPhase.AFTER_CONVERT;
}
实现SortingMongoEventListener
声明式排序必须使用反射。 为了保持代码可读性,我使用了commons-beanutils,但可以不使用它而手动完成。 在项目中添加以下依赖项:
<dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.8.3</version>
</dependency><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.1</version>
</dependency>
最后一部分是SortingMongoEventListener
实现:
package pl.maciejwalkowiak.springdata.mongodb;import com.mongodb.DBObject;
import org.apache.commons.beanutils.BeanComparator;
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
import org.springframework.data.mongodb.core.query.Order;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;/*** MongoEventListener that intercepts object before its converted to BasicDBObject (before it is saved into MongoDB)* and after its loaded from MongoDB.** @author Maciej Walkowiak*/
public class SortingMongoEventListener extends AbstractMongoEventListener {@Overridepublic void onAfterConvert(DBObject dbo, final Object source) {ReflectionUtils.doWithFields(source.getClass(), new SortingFieldCallback(source, SortPhase.AFTER_CONVERT));}@Overridepublic void onBeforeConvert(Object source) {ReflectionUtils.doWithFields(source.getClass(), new SortingFieldCallback(source, SortPhase.BEFORE_CONVERT));}/*** Performs sorting with field if:* <ul>* <li>field is an instance of list</li>* <li>is annotated with OrderBy annotation</li>* <li>OrderBy annotation is set to run in same phase as SortingFieldCallback</li>* </ul>*/private static class SortingFieldCallback implements ReflectionUtils.FieldCallback {private Object source;private SortPhase phase;private SortingFieldCallback(Object source, SortPhase phase) {this.source = source;this.phase = phase;}public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {if (field.isAnnotationPresent(OrderBy.class)) {OrderBy orderBy = field.getAnnotation(OrderBy.class);if (Arrays.asList(orderBy.phase()).contains(phase)) {ReflectionUtils.makeAccessible(field);Object fieldValue = field.get(source);sort(fieldValue, orderBy);}}}private void sort(Object fieldValue, OrderBy orderBy) {if (ClassUtils.isAssignable(List.class, fieldValue.getClass())) {final List list = (List) fieldValue;if (orderBy.order() == Order.ASCENDING) {Collections.sort(list, new BeanComparator(orderBy.value()));} else {Collections.sort(list, new BeanComparator(orderBy.value(), Collections.reverseOrder()));}}}}
}
为了使用它,您只需要在应用程序上下文中将该类声明为Spring Bean:
<bean class="pl.maciejwalkowiak.springdata.mongodb.SortingMongoEventListener" />
例
现在是从这篇文章的开头将创建的OrderBy批注添加到Backpack类的时候了。 假设我们要按价格降序订购商品:
@Document
public class Backpack {@Idprivate ObjectId id;@OrderBy(value = "price", order = Order.DESCENDING)private List<Item> items;...
}
而已。 现在,每次加载背包对象时(无论它的findAll,findOne还是您的自定义方法都没有关系),背包中的物品将被订购。
摘要
SortingMongoEventListener
是Spring Data MongoDB事件系统功能强大的另一个示例。 欢迎您发表评论,如果您认为此功能可能是Spring Data MongoDB的一部分,请告诉我。
参考: Software Development Journey博客上的JCG合作伙伴 Maciej Walkowiak 使用@OrderBy对Spring Data MongoDB集合进行排序 。
翻译自: https://www.javacodegeeks.com/2012/07/sorting-spring-data-mongodb-collections.html
orderby排序慢
orderby排序慢_使用@OrderBy对Spring Data MongoDB集合进行排序相关推荐
- 使用@OrderBy对Spring Data MongoDB集合进行排序
这是关于调整和增强Spring Data MongoDB功能的第三篇文章. 这次,我发现我错过了一个JPA功能– @OrderBy批注. @OrderBy指定在检索关联值时集合值关联的元素的顺序. 在 ...
- 使用Spring访问Mongodb的方法大全——Spring Data MongoDB查询指南
1.概述 Spring Data MongoDB 是Spring框架访问mongodb的神器,借助它可以非常方便的读写mongo库.本文介绍使用Spring Data MongoDB来访问mongod ...
- mongodb数据库java接口,MongoDB —— 使用Spring Data MongoDB操作数据库
我们使用Spring Data MongoDB可以方便的在Spring boot项目中操作MongoDB 文档地址:https://docs.spring.io/spring-boot/docs/2. ...
- 数据聚合Spring Data MongoDB:嵌套结果
1引言 在上一篇文章中,我们构建了聚合管道的基本示例. 如果您需要有关如何创建项目和配置应用程序的更多详细信息,也许您想看看使用Spring Data MongoDB和Spring Boot进行数据聚 ...
- SpringBoot 集成 Spring Data Mongodb 操作 MongoDB 详解
一.MongoDB 简介 MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,且与关系数据库的最为相像的.它支持的数据结构非常松散,是类似 json 的 bso ...
- Spring认证中国教育管理中心-Spring Data MongoDB教程五
原标题:Spring认证中国教育管理中心-Spring Data MongoDB教程五(内容来源:Spring中国教育管理中心) 11.6.5.GeoJSON 支持 MongoDB 支持GeoJSON ...
- Spring Data MongoDB 学习和使用
1.准备环境 新建一个Springboot项目 点击finish完成项目的搭建 2.配置连接参数 # application.properties # 配置数据库连接 #格式: mongodb://账 ...
- Spring Data MongoDB教程
在当今世界,尽快启动并运行应用程序非常重要. 该应用程序还应该易于开发和维护. Spring是这样的框架,它提供了与许多不同框架的集成的简便性,这使得使用Spring开发应用程序变得容易. 一种这样的 ...
- Spring Data MongoDB级联保存在DBRef对象上
默认情况下, Spring Data MongoDB不支持对带有@DBRef注释的引用对象的级联操作,如引用所述 : 映射框架不处理级联保存 . 如果更改了Person对象引用的Account对象,则 ...
最新文章
- Oracle如何代码编辑,配置UltraEdit为Oracle PL/SQL代码编辑器
- Mysql Cluster节点类型
- mybatis foreach 错误_MyBatis高级结果映射之一对一映射
- JAVA8 Optional新特性和使用详解
- Java - 初识Java
- 初二模拟赛总结(2019.8.7)
- 【转】Magento2 数据库操作
- Java常用性能分析工具 jconsole、jvisualvm、 jstat、jinfo、jmap、jhat、jstack
- scala 隐式参数入门及应用
- 【洛谷P3369】【模板】普通平衡树题解
- java migration_JetPack知识点实战系列九:Room数据库Migration
- 2021 第四届安洵杯 MISC wp
- csv文件用什么打开_什么是CSV文件,如何打开它?
- Mac下Go的安装与配置
- 阿里云--短信服务---开通步骤
- 给view添加单边阴影
- Design a Facebook NewsFeed
- ros:init()
- ChinaSoft 论坛巡礼 | 软件工程教学案例交流与竞赛
- Mesos+Marathon搭建部署
热门文章
- Oracle入门(四)之查询基本信息
- 关于人脸和指纹识别共同交流方案
- C#基础知识详解之【字段与属性】
- 2020蓝桥杯省赛---java---B---2(寻找 2020)+测试txt
- SparkContext源码分析
- oracle8修改最大连接数,ORACLE查看并修改最大连接数的具体步骤
- org.springframework.amqp.AmqpConnectException java.net.ConnectException的解决办法
- 拦截第三方快递物流 ,console控制台打印正常 ,浏览器显示正常 ,传至后台乱码
- thinking-in-java(10)内部类
- jvm(8)-虚拟机字节码执行引擎