find、skip、limit 就是修改查询属性,通过一个Example一步一步来达到lambda表达式的相关

发布时间:2020-02-11  栏目:数据  评论:0 Comments

对于数据分页,我们已经见的太多了,几乎每个列表页面都要用到分页,这已经成了一种定理了,在进行大数据展示时,如果不去分页,而直接把数据加载到内存,这简直是不可以去相向的,呵呵,在很多ORM工具中都对分页有了更好的支持,如LINQ里有大家熟悉的take和skip,而在MongoDB里也有这种概念,它使用limit和skip实现,这在大多数的Mongo客户端上都集成了这个功能,即帮助我们组合命令参数,并带我们把分页取数据的指令发到Mongo服务器去,实现分页技术!

Lambda 表达式&函数式接口

Lambda表达式好像已经出现很久了好像大部分人还是比较倾向于使用内部类
(老程序员表示Lambda表达式影响可读性,但是在很多组件中使用Lambda表达式还是很有必要的)

Lamdba表达式和接口是分不开的,JAVA8改动Lambda表达式的同时也新增了函数式接口

DBCurosr 是 DBCollection 的 find 方法返回的对象,可以设置 skip、limit
等属性之后,执行查询,得到查询结果,

一、引入lambda

定义:lambda就是简化了匿名内部类

使用前提:安装JDK 8

通过一个Example一步一步来达到lambda表达式的相关 :

添加了分页后的IMongoDBRepository接口

函数式接口

Functional
Interface的定义很简单:任何包含唯一一个抽象方法的接口都可以称之为函数式接口。

但是函数式接口中还可以存在签名与Object的public方法相同的接口(毕竟最终父类时Object),并且可以存在静态方法。

@FunctionalInterface
interface FunctionalInterfaceWithStaticMethod {
    static int sum(int[] array) {
        return Arrays.stream(array).reduce((a, b) -> a+b).getAsInt();
    }

    boolean equals(Object obj);

    void apply();
}
//这依旧是一个函数式接口

为了让编译器帮助我们确保一个接口满足函数式接口的要求,Java8提供了@FunctionalInterface注解。

另外JDK中已有的一些接口本身就是函数式接口,如Runnable。 JDK
8中又增加了java.util.function包,
提供了常用的函数式接口。

举个函数式接口的栗子

@FunctionalInterface  
public interface Runnable {  
    public abstract void run();  
}  
//Runnable接口提供了一个run()抽象方法

在java8之前,你可以通过匿名内部类来实现对这个接口的调用,像下面这样

Thread thread = new Thread(new Runnable() {
  public void run() {
    System.out.println("In another thread");
  }
}); 

但是如果我们想要我们的代码更加优雅,我们应该使用Lambda表达式,当我们使用Lambda表达式刚刚代码就可以这样写:

Thread thread = new Thread(() -> 
System.out.println("In another thread"));

用法如下:

筛选出集合内大于50的数
  • 普通Java代码实现

 public static void main(String[] args) { List<Integer> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { Random random = new Random(); int nextInt = random.nextInt + 1; list.add; } System.out.println("原:" + list); System.out.println("筛选出大于50的数"); filter; } public static void filter(List<Integer> list) { for (Integer integer : list) { if (integer > 50) { System.out.println; } } }
  • 匿名类部类实现

 public static void main(String[] args) { List<Integer> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { Random random = new Random(); int nextInt = random.nextInt + 1; list.add; } System.out.println("原:" + list); Checker checker = new Checker() { @Override public boolean check(Integer i) { return i > 50; } }; filter(list, checker); } public static void filter(List<Integer> list, Checker checker) { for (Integer integer : list) { if (checker.check { System.out.println; } } } // Checker接口 public interface Checker { public boolean check(Integer i); }
  • 一步一步演变成lambda表达式

 public static void main(String[] args) { List<Integer> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { Random random = new Random(); int nextInt = random.nextInt + 1; list.add; } Checker c1 = new Checker() { @Override public boolean check(Integer i) { return i > 50; } }; System.out.println("筛选出大于50的数--->1"); filter; Checker c2 = (Integer i) -> { return i > 50; }; System.out.println("筛选出大于50的数--->2"); filter; Checker c3 = (Integer i) -> i > 50; System.out.println("筛选出大于50的数--->3"); filter; Checker c4 = i -> i > 50; System.out.println("筛选出大于50的数--->4"); filter; System.out.println("筛选出大于50的数--->5"); filter(list, i -> i > 50); List<Integer> is = list.stream().filter(i -> i > 50).collect(Collectors.toList; System.out.println; } public static void filter(List<Integer> list, Checker checker) { for (Integer integer : list) { if (checker.check { System.out.println; } } }
    /// <summary>    /// MongoDB集成的查询方法,大数据情况下,有分页时使用这个方法    /// </summary>    /// <typeparam name="U">匿名对象,用来为条件赋值</typeparam>    /// <param name="template">条件对象</param>    /// <param name="limit"></param>    /// <param name="skip"></param>    /// <returns></returns>    PagedResult<TEntity> GetModel<U>(U template, int pageIndex, int pageSize);    /// <summary>    /// MongoDB集成的查询方法,大数据情况下,有分页和排序时使用这个方法    /// </summary>    /// <typeparam name="U">匿名对象,用来为条件赋值</typeparam>    /// <typeparam name="O">匿名对象,用来为排序赋值,NoRM.OrderBy枚举</typeparam>    /// <param name="template">条件对象</param>    /// <param name="orderby">排序对象</param>    /// <param name="limit"></param>    /// <param name="skip"></param>    /// <returns></returns>    PagedResult<TEntity> GetModel<U, O>(U template, O orderby, int pageIndex, int pageSize);

Lambda表达式

Lambda表达式在Java8中最大的改动是
它允许把函数作为一个方法的参数(函数作为参数传递进方法中)

以下是lambda表达式的重要特征:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动确定返回值

还是先上栗子:

public class Java8Tester {
   public static void main(String args[]){
      Java8Tester tester = new Java8Tester();

      // 类型声明
      MathOperation addition = (int a, int b) -> a + b;

      // 不用类型声明
      MathOperation subtraction = (a, b) -> a - b;

      // 大括号中的返回语句
      MathOperation multiplication = (int a, int b) -> { return a * b; };

      // 没有大括号及返回语句
      MathOperation division = (int a, int b) -> a / b;

      System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
      System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
      System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
      System.out.println("10 / 5 = " + tester.operate(10, 5, division));

      // 不用括号
      GreetingService greetService1 = message ->
      System.out.println("Hello " + message);

      // 用括号
      GreetingService greetService2 = (message) ->
      System.out.println("Hello " + message);

      greetService1.sayMessage("Runoob");
      greetService2.sayMessage("Google");
   }

   interface MathOperation {
      int operation(int a, int b);
   }

   interface GreetingService {
      void sayMessage(String message);
   }

   private int operate(int a, int b, MathOperation mathOperation){
      return mathOperation.operation(a, b);
   }
}

变量作用域

  • lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在
    lambda
    内部修改定义在域外的局部变量,否则会编译错误。(其实也可以不声明final)

int num = 1;
Converter<Integer, String> s =
        (param) -> String.valueOf(param + num);
num = 5;
//编译会出错
  • 在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

String first = "";  
Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length()); 
 //编译会出错 

Java代码

总结
1.匿名类的正常写法 Checker checker = new Checker() { @Override public boolean check(Integer i) { return i > 50; } };

2. 把外面的壳子去掉,只保留方法参数和方法体,参数和方法体之间加上符号 -> Checker c2 = (Integer i) -> { return i > 50; };

3. 把return和{}去掉 Checker c3 = (Integer i) -> i > 50;

4. 去掉参数小括号,得到Lambda表达式 Checker c4 = i -> i > 50;

 //TODO 匿名类部类 Collections.sort(list, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo; // TODO lambda表达式 Collections.sort(list,  -> o1.compareTo;

看我是如何去实现它的,事实上是调用了Mongo客户端封装的Find<T, U,
O>(this IMongoCollection<T> collection, U template, O orderby,
int limit, int skip);方法

方法引用

方法引用通过方法的名字来指向一个方法。
方法引用使用一对冒号 ::
内容比较简单并且Java核心已经有讲过
所以直接上栗子,我们在 Car 类中定义了 4 个方法作为例子来区分 Java 中 4
种不同方法的引用。

package com.runoob.main;

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

class Car {

    public static Car create(final Supplier<Car> supplier) {
        return supplier.get();
    }

    public static void collide(final Car car) {
        System.out.println("Collided " + car.toString());
    }

    public void follow(final Car another) {
        System.out.println("Following the " + another.toString());
    }

    public void repair() {
        System.out.println("Repaired " + this.toString());
    }
}
  • 构造器引用

final Car car = Car.create( Car::new );
final List< Car > cars = Arrays.asList( car );
  • 静态方法引用

cars.forEach( Car::collide );
//Class< T >::new
  • 特定类的任意对象的方法引用
    //Class::static_method

cars.forEach( Car::repair );
//Class::method
  • 特定对象的方法引用

final Car police = Car.create( Car::new );
cars.forEach( police::follow );
//instance::method

图片 1

二、聚合操作

遍历: 传统方式与聚合操作遍历数据

 List<Integer> list = new ArrayList<>(); Random random = new Random(); for (int i = 0; i < 10; i++) { int nextInt = random.nextInt + 1; list.add; } // TODO 传统方式for循环遍历数据 for (Integer itg : list) { if (itg > 50) { System.out.println; } } // TODO 聚合操作遍历数据 list.stream().filter(itg -> itg > 50).forEach(itg -> System.out.println; // TODO lambda的方法引用(简介: 静态方法、对象方法等等的引入) list.stream().filter(itg -> itg > 50).forEach(System.out::println);

Stream和管道的概念

  1. Stream: Stream是一系列元素, 象生产线上的罐头, 一罐一罐的生产出来
  2. 管道: 是指一系列聚合操作, 分为:管道源、中间操作、结束操作。

管道源:在前面的例子里面,管道源是list集合

  • 将Collection切换到管道源只需要调用stream()方法即可:

 list.stream();
  • 数组却没有stream()方法,需要使用:

 int[] arr = {1, 2, 3, 4}; Arrays.stream.forEach(System.out::println);

中间操作:也叫‘懒’操作,并不会进行变量,每一步中间操作都会返回一个Stream对象

  • 对元素进行筛选

    • filter 匹配
    • distinct 去除重复(根据equals判断)
    • sorted 自然排序
    • sorted(Comparator<T>) 指定排序
    • limit 保留
    • skip 忽略
  • 转换为其他形式的流

    • mapToDouble 转换为double的流
    • map 转换为任意类型的流

 //TODO 去重排序打印 list.stream().distinct().sorted().forEach(System.out::println); //TODO 保留前三个元素并打印 list.stream().limit.forEach(System.out::println); //TODO 忽略前三个 list.stream.forEach( System.out::println); //TODO 转换任意类型的Stream list.stream().map(itg -> itg + "-hello").forEach( System.out::println);

结束操作: 结束操作不会返回Stream,但是会返回int、float、String、
Collection或者像forEach或者什么都不返回

  • forEach() 遍历每个元素
  • toArray() 转换为数组
  • min(Comparator<T>) 取最小的元素
  • max(Comparator<T>) 取最大的元素
  • count() 总数
  • findFirst() 第一个元素

 // 遍历集合中的每个数据 list.stream().forEach(h->System.out.print; // 返回一个数组 Object[] array= list.stream().toArray(); // 返回最小值 Integer integer = list.stream().min -> a1.compareTo.get(); // 返回最大值 Integer integer = list.stream().max -> a1.compareTo.get(); // 数据的总数 long count = list.stream; // 第一个元素 Integer integer = list.stream().findFirst;

实现的,我们来看一下代码

Java Stream

Stream是 Java 8新增加的类,用来补充集合类
既然是补充集合类,那么先来列举一下它们的区别(主要是与迭代器的区别):
1.不储存数据
流是基于数据源的对象,它本身不存储数据元素,而是通过管道将数据源的元素传递给操作。
2.函数式编程
流的操作不会修改数据源,例如filter不会将数据源中的数据删除。
3.延迟操作
流的很多操作如filter,map等中间操作是延迟执行的,只有到终点操作才会将操作顺序执行。
4.可以解绑
对于无限数量的流,有些操作是可以在有限的时间完成的,比如limit(n) 或
findFirst(),这些操作可是实现”短路”(Short-circuiting),访问到有限的元素后就可以返回。
5.纯消费
流的元素只能访问一次,类似Iterator,操作没有回头路,如果你想从头重新访问流的元素,对不起,你得重新生成一个新的流。

在具体讲解方法之前,还是先来看一个栗子:

List<Integer> a = {1,2,3};
List<Integer> b = a.stream()
             .filter(i ->  i >= 2 )
             .collect(Collectors.toList());

我们可以把以上代码分为三部分来具体分析:
1.创建Stream

  • 通过集合的stream()方法或者parallelStream(),比如Arrays.asList(1,2,3).stream()。
  • 通过Arrays.stream(Object[])方法, 比如Arrays.stream(new
    int[]{1,2,3})。
  • 使用流的静态方法,比如Stream.of(Object[]), IntStream.range(int,
    int) 或者 Stream.iterate(Object, UnaryOperator),如Stream.iterate(0,
    n -> n *
  • BufferedReader.lines()从文件中获得行的流。
  • Files类的操作路径的方法,如list、find、walk等。
  • 随机数流Random.ints()。
  • 更底层的使用StreamSupport,它提供了将Spliterator转换成流的方法。

2.中间操作

  • distinct
    distinct保证输出的流中包含唯一的元素,它是通过Object.equals(Object)来检查是否包含相同的元素。

List<String> l = Stream.of("a","b","c","b")
        .distinct()
        .collect(Collectors.toList());
System.out.println(l); //[a, b, c]
  • filter
    filter返回的流中只包含满足断言(predicate)的数据。
    下面的代码返回流中的偶数集合。

List<Integer> l = IntStream.range(1,10)
        .filter( i -> i % 2 == 0)
        .boxed()
        .collect(Collectors.toList());
System.out.println(l); //[2, 4, 6, 8]
  • map
    map方法将流中的元素映射成另外的值,新的值类型可以和原来的元素的类型不同。

map( c -> c*2)
  • flatmap
    flatmap方法将映射后的流的元素全部放入到一个新的流中。

String poetry = "Where, before me, are the ages that have gone?\n" +
        "And where, behind me, are the coming generations?\n" +
        "I think of heaven and earth, without limit, without end,\n" +
        "And I am all alone and my tears fall down.";
Stream<String> lines = Arrays.stream(poetry.split("\n"));
Stream<String> words = lines.flatMap(line -> Arrays.stream(line.split(" ")));
  • limit
    limit方法指定数量的元素的流。对于串行流,这个方法是有效的,这是因为它只需返回前n个元素即可,但是对于有序的并行流,它可能花费相对较长的时间,如果你不在意有序,可以将有序并行流转换为无序的,可以提高性能。

List<Integer> l = IntStream.range(1,100).limit(5)
        .boxed()
        .collect(Collectors.toList());
System.out.println(l);//[1, 2, 3, 4, 5]
  • peek
    peek方法方法会使用一个Consumer消费流中的元素,但是返回的流还是包含原来的流中的元素。

String[] arr = new String[]{"a","b","c","d"};
Arrays.stream(arr)
        .peek(System.out::println) //a,b,c,d
        .count();
  • sorted
    sorted()将流中的元素按照自然排序方式进行排序,如果元素没有实现Comparable,则终点操作执行时会抛出java.lang.ClassCastException异常。
    sorted(Comparator<? super T> comparator)可以指定排序的方式。

对于有序流,排序是稳定的。对于非有序流,不保证排序稳定。

String[] arr = new String[]{"b_123","c+342","b#632","d_123"};
List<String> l  = Arrays.stream(arr)
        .sorted((s1,s2) -> {
            if (s1.charAt(0) == s2.charAt(0))
                return s1.substring(2).compareTo(s2.substring(2));
            else
                return s1.charAt(0) - s2.charAt(0);
        })
        .collect(Collectors.toList());
System.out.println(l); //[b_123, b#632, c+342, d_123]
  • skip
    skip返回丢弃了前n个元素的流,如果流中的元素小于或者等于n,则返回空的流。

3.终点操作

  • Match
    分为三种具体方法,用来检查流中的元素是否满足段言。

public boolean  allMatch(Predicate<? super T> predicate)
public boolean  anyMatch(Predicate<? super T> predicate)
public boolean  noneMatch(Predicate<? super T> predicate)
  • count
    count方法返回流中的元素的数量。

  • collect
    这是一个比较重要的终点操作,实现最终对处理过的流的收集。辅助类Collectors提供了很多的collector,可以满足我们日常的需求,你也可以创建新的collector实现特定的需求。

  • find
    findAny()返回任意一个元素,如果流为空,返回空的Optional,对于并行流来说,它只需要返回任意一个元素即可,所以性能可能要好于findFirst(),但是有可能多次执行的时候返回的结果不一样。
    findFirst()返回第一个元素,如果流为空,返回空的Optional。

  • forEach
    forEach遍历流的每一个元素,执行指定的action。

Stream.of(1,2,3,4,5).forEach(System.out::println);
  • max/min
    max返回流中的最大值,
    min返回流中的最小值。

  • toArray()
    将流中的元素放入到一个数组中。

多说一句~~~~~~~~~
流可以从非线程安全的集合中创建,当流的管道执行的时候,非concurrent数据源不应该被改变。下面的代码会抛出java.util.ConcurrentModificationException异常:

List<String> l = new ArrayList(Arrays.asList("one", "two"));
Stream<String> sl = l.stream();
sl.forEach(s -> l.add("three"));

但是使用CopyOnWriteArrayList可以解决这个问题

Listobj

 public PagedResult<TEntity> GetModel<U, O>(U template, O orderby, int pageIndex, int pageSize)    {      var skip = (pageIndex - 1) * pageSize;      var limit = pageSize;      var recordCount = _table.Count();      return new PagedResult<TEntity>(        recordCount,        (int)(recordCount + pageSize - 1) / pageSize,        pageSize,        pageIndex,        _table.Find(template, orderby, limit, skip).ToList());    }

Optional——一个可以为 null 的容器

Java
8中的Optional<T>是一个可以包含或不可以包含非空值的容器对象,在
Stream
API中很多地方也都使用到了Optional。(暂时没有找到特别合适的用法…)

基本方法:

  • of()

  • ofNullable()

  • isPresent()
    如果值存在,返回 true,否则返回 false

  • map()

  • orElse()

  • orElseGet()

=collection.find(query).skip(1000).limit(100).toArray();

代码主要实现的是分页和排序功能,其中template是查询条件,可以传入一个匿名对象,而orderby参数表示一个排序的匿名对象,把排序字段写到对象里即可,升序为1,降

DBCursor 类的方法可以可以分为两类:修改查询属性 和 执行查询。

序为-1,也可以使用它定义好的枚举来赋值,下面我们为上面方法做一个重载,来针对不需要排序的需求

以上面的代码为例,find、skip、limit 就是修改查询属性,而 toArrray
就是执行查询。

  public PagedResult<TEntity> GetModel<U>(U template, int pageIndex, int pageSize)    {      return GetModel(template, new { }, pageIndex, pageSize);    }

在实际的实现中,修改查询属性的方法实际上是修改 DBCursor
对象的属性,执行查询则是通过调用 DBCollection._find 得到查询结果。

有了底层的方法,再来看它的返回值,如果是分页返回对象,那么一定要返回一个PagedResult泛型对象,这个对象主要向外部公开一个参数,如当前页的数据集,当前页号

修改查询属性

每面显示记录数,总页数和总的记录数及URL条件集合等。

Java代码

  /// <summary>  /// 分页结果对象,UI显示它,BLL为它赋值  /// 陈晴阳开发,张占岭修改,添加了AddParameters属性,用来存储URL参数  /// </summary>  /// <typeparam name="T"></typeparam>  public class PagedResult<T> : IEnumerable<T>, ICollection<T>  {    #region Public Fields    /// <summary>    /// 获取一个当前类型的空值。    /// </summary>    public static readonly PagedResult<T> Empty = new PagedResult<T>(0, 0, 0, 0, null);    #endregion    #region Ctor    /// <summary>    /// 初始化一个新的<c>PagedResult{T}</c>类型的实例。    /// </summary>    public PagedResult()    {      Data = new List<T>();      AddParameters = new NameValueCollection();      PageSize = 10;    }    /// <summary>    /// 初始化一个新的<c>PagedResult{T}</c>类型的实例。    /// </summary>    /// <param name="totalRecords">总记录数。</param>    /// <param name="totalPages">页数。</param>    /// <param name="pageSize">页面大小。</param>    /// <param name="pageNumber">页码。</param>    /// <param name="data">当前页面的数据。</param>    public PagedResult(long totalRecords, int totalPages, int pageSize, int pageNumber, List<T> data)    {      this.TotalPages = totalPages;      this.TotalRecords = totalRecords;      this.PageSize = pageSize;      this.PageIndex = pageNumber;      this.Data = data;    }    #endregion    #region Public Properties    /// <summary>    /// 获取或设置总记录数。    /// </summary>    public long TotalRecords { get; set; }    /// <summary>    /// 获取或设置页数。    /// </summary>    public int TotalPages { get; set; }    /// <summary>    /// 获取或设置页面大小。    /// </summary>    public int PageSize { get; set; }    /// <summary>    /// 获取或设置页码。    /// </summary>    public int PageIndex { get; set; }    /// <summary>    /// 获取或设置当前页面的数据。    /// </summary>    public List<T> Data { get; set; }    /// <summary>    /// 分页参数    /// </summary>    public NameValueCollection AddParameters { get; set; }    #endregion    #region Public Methods    /// <summary>    /// 确定指定的Object是否等于当前的Object。    /// </summary>    /// <param name="obj">要与当前对象进行比较的对象。</param>    /// <returns>如果指定的Object与当前Object相等,则返回true,否则返回false。</returns>    /// <remarks>有关此函数的更多信息,请参见:http://msdn.microsoft.com/zh-cn/library/system.object.equals。    /// </remarks>    public override bool Equals(object obj)    {      if (ReferenceEquals(this, obj))        return true;      if (obj == (object)null)        return false;      var other = obj as PagedResult<T>;      if (other == (object)null)        return false;      return this.TotalPages == other.TotalPages &&        this.TotalRecords == other.TotalRecords &&        this.PageIndex == other.PageIndex &&        this.PageSize == other.PageSize &&        this.Data == other.Data;    }    /// <summary>    /// 用作特定类型的哈希函数。    /// </summary>    /// <returns>当前Object的哈希代码。</returns>    /// <remarks>有关此函数的更多信息,请参见:http://msdn.microsoft.com/zh-cn/library/system.object.gethashcode。    /// </remarks>    public override int GetHashCode()    {      return this.TotalPages.GetHashCode() ^        this.TotalRecords.GetHashCode() ^        this.PageIndex.GetHashCode() ^        this.PageSize.GetHashCode();    }    /// <summary>    /// 确定两个对象是否相等。    /// </summary>    /// <param name="a">待确定的第一个对象。</param>    /// <param name="b">待确定的另一个对象。</param>    /// <returns>如果两者相等,则返回true,否则返回false。</returns>    public static bool operator ==(PagedResult<T> a, PagedResult<T> b)    {      if (ReferenceEquals(a, b))        return true;      if ((object)a == null || (object)b == null)        return false;      return a.Equals(b);    }    /// <summary>    /// 确定两个对象是否不相等。    /// </summary>    /// <param name="a">待确定的第一个对象。</param>    /// <param name="b">待确定的另一个对象。</param>    /// <returns>如果两者不相等,则返回true,否则返回false。</returns>    public static bool operator !=(PagedResult<T> a, PagedResult<T> b)    {      return !(a == b);    }    #endregion    #region IEnumerable<T> Members    /// <summary>    /// 返回一个循环访问集合的枚举数。    /// </summary>    /// <returns>一个可用于循环访问集合的 IEnumerator 对象。</returns>    public IEnumerator<T> GetEnumerator()    {      return Data.GetEnumerator();    }    #endregion    #region IEnumerable Members    /// <summary>    /// 返回一个循环访问集合的枚举数。 (继承自 IEnumerable。)    /// </summary>    /// <returns>一个可用于循环访问集合的 IEnumerator 对象。</returns>    IEnumerator IEnumerable.GetEnumerator()    {      return Data.GetEnumerator();    }    #endregion    #region ICollection<T> Members    /// <summary>    /// 将某项添加到 ICollection{T} 中。    /// </summary>    /// <param name="item">要添加到 ICollection{T} 的对象。</param>    public void Add(T item)    {      Data.Add(item);    }    /// <summary>    /// 从 ICollection{T} 中移除所有项。    /// </summary>    public void Clear()    {      Data.Clear();    }    /// <summary>    /// 确定 ICollection{T} 是否包含特定值。    /// </summary>    /// <param name="item">要在 ICollection{T} 中定位的对象。</param>    /// <returns>如果在 ICollection{T} 中找到 item,则为 true;否则为 false。</returns>    public bool Contains(T item)    {      return Data.Contains(item);    }    /// <summary>    /// 从特定的 Array 索引开始,将 ICollection{T} 的元素复制到一个 Array 中。    /// </summary>    /// <param name="array">作为从 ICollection{T} 复制的元素的目标的一维 Array。 Array 必须具有从零开始的索引。</param>    /// <param name="arrayIndex">array 中从零开始的索引,从此索引处开始进行复制。</param>    public void CopyTo(T[] array, int arrayIndex)    {      Data.CopyTo(array, arrayIndex);    }    /// <summary>    /// 获取 ICollection{T} 中包含的元素数。    /// </summary>    public int Count    {      get { return Data.Count; }    }    /// <summary>    /// 获取一个值,该值指示 ICollection{T} 是否为只读。    /// </summary>    public bool IsReadOnly    {      get { return false; }    }    /// <summary>    /// 从 ICollection{T} 中移除特定对象的第一个匹配项。    /// </summary>    /// <param name="item">要从 ICollection{T} 中移除的对象。</param>    /// <returns>如果已从 ICollection{T} 中成功移除 item,则为 true;否则为 false。 如果在原始 ICollection{T} 中没有找到 item,该方法也会返回 false。 </returns>    public bool Remove(T item)    {      return Data.Remove(item);    }    #endregion  }

图片 2

有了底层方法和返回的对象,下面就是前台显示了,我们可以扩展一个PagerHelper,重新为它起个名字叫PagedResultHelper吧,把它的相关PagedList类型对象修改成PagedResult对象即可,代码如下

//排序

 /// <summary>  /// 关于PagedResult对象的分页展示  /// 作者:张占岭,花名:仓储大叔  /// </summary>  public static class PagedResultHelper  {    #region Ajax分页    /// <summary>    /// AJAX分页    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="html"></param>    /// <param name="pagedList"></param>    /// <param name="UpdateTargetId"></param>    /// <returns></returns>    public static MvcHtmlString AjaxPagerResult<T>(this HtmlHelper html, PagedResult<T> pagedList, string UpdateTargetId, bool isDisplayCompletePage)    {      var ui = new UIHelper(html.ViewContext.RequestContext.HttpContext.Request.Url.ToString(), UpdateTargetId, pagedList.AddParameters);      if (!isDisplayCompletePage)        return MvcHtmlString.Create(ui.GetPage(pagedList.PageIndex, pagedList.PageSize, (int)pagedList.TotalRecords, false));      else        return MvcHtmlString.Create(ui.GetPage(pagedList.PageIndex, pagedList.PageSize, (int)pagedList.TotalRecords));    }    public static MvcHtmlString AjaxPager<T>(this HtmlHelper html, PagedResult<T> pagedList, string UpdateTargetId)    {      return AjaxPagerResult<T>(html, pagedList, UpdateTargetId, true);    }    /// <summary>    /// AJAX分页    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="html"></param>    /// <param name="pagedList"></param>    /// <param name="UpdateTargetId"></param>    /// <param name="ActionName"></param>    /// <param name="ControllerName"></param>    /// <returns></returns>    public static MvcHtmlString AjaxPagerResult<T>(this HtmlHelper html, PagedResult<T> pagedList, string UpdateTargetId, string ActionName, string ControllerName, bool isDisplayCompletePage, bool isTop)    {      var mvcUrl = new UrlHelper(html.ViewContext.RequestContext).Action(ActionName, ControllerName); //占岭修改      var localUrl = string.Format(@"{0}://{1}", html.ViewContext.RequestContext.HttpContext.Request.Url.Scheme, html.ViewContext.RequestContext.HttpContext.Request.Url.Authority);      var url = string.Format("{0}{1}{2}", localUrl, mvcUrl, html.ViewContext.RequestContext.HttpContext.Request.Url.Query);      var ui = new UIHelper(url, UpdateTargetId, pagedList.AddParameters);      return MvcHtmlString.Create(ui.GetPage(pagedList.PageIndex, pagedList.PageSize, (int)pagedList.TotalRecords, isDisplayCompletePage, false, isTop));    }    public static MvcHtmlString AjaxPagerResult<T>(this HtmlHelper html, PagedResult<T> pagedList, string UpdateTargetId, string ActionName, string ControllerName, bool isDisplayCompletePage)    {      return AjaxPagerResult<T>(html, pagedList, UpdateTargetId, ActionName, ControllerName, true, false);    }    /// <summary>    /// ajax方式,MVC路由支持的分页    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="html"></param>    /// <param name="pagedList"></param>    /// <param name="UpdateTargetId"></param>    /// <param name="ActionName"></param>    /// <param name="ControllerName"></param>    /// <returns></returns>    public static MvcHtmlString AjaxPagerResult<T>(this HtmlHelper html, PagedResult<T> pagedList, string UpdateTargetId, string ActionName, string ControllerName)    {      var mvcUrl = new UrlHelper(html.ViewContext.RequestContext).Action(ActionName, ControllerName); //占岭修改      var localUrl = string.Format(@"{0}://{1}", html.ViewContext.RequestContext.HttpContext.Request.Url.Scheme, html.ViewContext.RequestContext.HttpContext.Request.Url.Authority);      var url = string.Format("{0}{1}{2}", localUrl, mvcUrl, html.ViewContext.RequestContext.HttpContext.Request.Url.Query);      var ui = new UIHelper(url, UpdateTargetId, pagedList.AddParameters);      return MvcHtmlString.Create(ui.GetPage(pagedList.PageIndex        , pagedList.PageSize        , (int)pagedList.TotalRecords        , 0        , new UrlHelper(html.ViewContext.RequestContext)        , html.ViewContext.RouteData.Values["action"].ToString()        , html.ViewContext.RouteData.Values["controller"].ToString(), true, false, null));    }        #endregion    #region Html分页    /// <summary>    /// Html分页,不使用MVC路由    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="html"></param>    /// <param name="pagedList"></param>    /// <returns></returns>    public static MvcHtmlString PagerResult<T>(this HtmlHelper html, PagedResult<T> pagedList)    {      return PagerResult<T>(html, pagedList, false);    }    public static MvcHtmlString PagerResult<T>(this HtmlHelper html, PagedResult<T> pagedList, string className)    {      return PagerResult<T>(html, pagedList, false, className);    }    public static MvcHtmlString PagerResult<T>(this HtmlHelper html, PagedResult<T> pagedList, bool router, string className)    {      return PagerResult<T>(html, pagedList, router, true, className);    }    /// <summary>    /// Html分页,router为true表示走MVC路由    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="html"></param>    /// <param name="pagedList"></param>    /// <param name="router">路由</param>    /// <param name="className">CSS类名</param>    /// <returns></returns>    public static MvcHtmlString PagerResult<T>(this HtmlHelper html, PagedResult<T> pagedList, bool router, bool isCompleteDisplay, string className)    {      if (pagedList == null)        return null;      UIHelper ui = new UIHelper(html.ViewContext.RequestContext.HttpContext.Request.Url.ToString(), pagedList.AddParameters);      if (router)        return MvcHtmlString.Create(ui.GetPage(pagedList.PageIndex          , pagedList.PageSize          , (int)pagedList.TotalRecords          , 0          , new UrlHelper(html.ViewContext.RequestContext)          , html.ViewContext.RouteData.Values["action"].ToString()          , html.ViewContext.RouteData.Values["controller"].ToString(), isCompleteDisplay, false, className));      return MvcHtmlString.Create(ui.GetPage(pagedList.PageIndex, pagedList.PageSize, (int)pagedList.TotalRecords, isCompleteDisplay, className));    }    public static MvcHtmlString PagerResult<T>(this HtmlHelper html, PagedResult<T> pagedList, bool router)    {      return PagerResult<T>(html, pagedList, router, null);    }    #endregion  }

publicDBCursorsort(DBObjectorderBy)

这样,我们前台调用分页时,还是一句话就搞定了,呵呵!

//添加特殊设置

图片 3

publicDBCursoraddSpecial(Stringname,Objecto)

事实上,对于PagedResult我们也可以用在其它ORM工具上,因为一定的数据库和NoSql都开放了limit及skip等功能,大家可以放眼去看,放心去想,呵呵!

//hint,建议MongoDB使用的索引

publicDBCursorhint(DBObjectindexKeys)

//快照

publicDBCursorsnapshot()

//设置返回结果数量

publicDBCursorlimit(intn)

//每次读取的数量

publicDBCursorbatchSize(intn)

//设置开始读取的位置

publicDBCursorskip(intn)

//添加查询设置

publicDBCursoraddOption(intoption)

//指定查询设置

publicvoidsetOptions(intoptions)

以 sort 为例:

Java代码

图片 4

//设置排序

publicDBCursorsort(DBObjectorderBy){

//检查是否已经执行过查询

if(_it!=null)

thrownewIllegalStateException(“can’tsortafterexecutingquery”);

//设置_ordderBy,返回

_orderBy=orderBy;

returnthis;

相关文章

留下评论

网站地图xml地图