简体   繁体   English

Java构建用于排序的特定自定义比较器

[英]Java Building a specific custom Comparator for Sorting

I am working on an ORM system (Object relational mapping, basically a wrapper in java classes such that I don't need to use SQL code directly) 我在ORM系统上工作(对象关系映射,基本上是Java类中的包装器,因此不需要直接使用SQL代码)

This question goes about searching in a table, by specyfing constraints: 这个问题是通过指定约束在表中进行搜索:

public final List<B> search(final AbstractConstraint... c) throws SearchException {
    if (c.length == 0) {
        throw new IllegalArgumentException("orm.Manager.search: c.length == 0");
    }
    try {
        List<B> beans = new ArrayList<>();

        for (AbstractConstraint constraint : c) {
            try (PreparedStatement ps = new QueryBuilder(connection, tableName(), getPaths(), searchQuery()).add(constraint).build();
                    ResultSet rs = ps.executeQuery()) {
                while (rs.next()) {
                    beans.add(createBean(rs));
                }
            }
        }

        if (c.length > 1) {
            boolean sorting = true;
            Field field = c[0].getField();
            Order order = c[0].getOrder();
            for (int i = 1; i < c.length; i++) {
                Field currentField = c[i].getField();
                Order currentOrder = c[i].getOrder();
                if (!field.equals(currentField) || !order.equals(currentOrder)) {
                    sorting = false;
                    break;
                }
            }
            if (sorting) {
                //sort on field with comparator of supertype
            }
        }

        return beans;
    } catch (SQLException ex) {
        Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
        throw new SearchException(ex);
    }
}

Normally the AbstractConstraint itself takes care of the order. 通常,AbstractConstraint本身会处理顺序。 But there is a special case if you are using multiple AbstractConstraints (essentially my counterpart to the SQL OR ). 但是,如果您使用多个AbstractConstraints(本质上是SQL OR对应对象),则是一种特殊情况。 If two of those individual AbstractConstraints (which are already ordered), share the same ordering, then the resulting List<B> should be in total also ordered, and not contain two ordered lists stacked on top of eachother. 如果这些单独的AbstractConstraints中的两个(已排序)共享相同的排序,则结果List<B>应总共也排序,并且不包含两个彼此堆叠的排序列表。

How would I go about doing that? 我将如何去做? This is what I know: 这是我所知道的:

  • The Field object, specyfing on which field should be searched, this is a direct reference to a column in a table in an SQL database. 指定要搜索哪个字段的Field对象,这是对SQL数据库表中列的直接引用。
  • The Order object Order对象

So I am thinking that (in my current implementation), columns (thus fields) can have the following values: 因此,我认为(在当前实施中)列(因此字段)可以具有以下值:

  • String (in SQL varchar) 字符串(在SQL varchar中)
  • Integer (in SQL int) 整数(在SQL int中)
  • Date (in SQL datetime) 日期(以SQL datetime为单位)
  • BigInteger (in SQL decimal) BigInteger(以SQL十进制表示)

And the orderings would be ascending or descending. 并且顺序将是升序或降序。

How would I need to extend my Field class to capture the type of the column? 我该如何扩展Field类以捕获列的类型? This is all what Field is currently: 这就是Field当前的全部内容:

public interface Field {
    public String getFieldName();
}

And how would I write the Comparator ? 我该如何编写Comparator Actually, do I even have to write the Comparator or should I let Field implement Comparable in some way? 实际上,我是否甚至必须编写Comparator还是应该让Field以某种方式实现Comparable

I hope the question is understandable and looking forward to any responses. 我希望这个问题是可以理解的,并期待任何答复。

EDIT: Adding example of concrete implementation of Field : 编辑:添加示例的具体实施Field

public enum InvoiceFields implements Field {
    invoiceId("invoices.invoiceId"),
    businessPartnerId("invoices.businessPartnerId"),
    invoiceNumber("invoices.invoiceNumber"),
    invoiceDate("invoices.invoiceDate"),
    priceExclVAT("invoices.priceExclVAT"),
    VAT("invoices.VAT"),
    priceInclVAT("invoices.priceInclVAT"),
    paymentDiscount("invoices.paymentDiscount"),
    status("invoices.status");

    private final String enumName;

    private InvoiceFields(final String enumName) {
        this.enumName = enumName;
    }

    @Override
    public String getFieldName() {
        return enumName;
    }
}

I think you want an abstract class. 我认为您想要一个抽象类。 ie then create subclasses for each of your different type of fields. 即为每个不同类型的字段创建子类。

public abstract class Field implements Comparable<Field> {

public abstract String getFieldName();

public int compareTo(Field field) {
return 0;
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM