jetlinks / jetlinks-community

JetLinks 基于Java8,Spring Boot 2.x ,WebFlux,Netty,Vert.x,Reactor等开发, 是一个全响应式的企业级物联网平台。支持统一物模型管理,多种设备,多种厂家,统一管理。统一设备连接管理,多协议适配(TCP,MQTT,UDP,CoAP,HTTP等),屏蔽网络编程复杂性,灵活接入不同厂家不同协议等设备。实时数据处理,设备告警,消息通知,数据转发。地理位置,数据可视化等。能帮助你快速建立物联网相关业务系统。
https://www.jetlinks.cn/
Apache License 2.0
5.57k stars 1.67k forks source link

请问下可以自定义排序吗 #310

Closed MoonBottle closed 1 year ago

MoonBottle commented 1 year ago

现在有个字段存储数据是这样的 A1,A6,B3,A10,B5,分为两部分组成,前面的字母和后面的数字 现在要根据这个字段进行排序,先按照前缀字母排序,字母相同按照后面的数字排序

比如上面的排序结果为 A1,A6,A10,B3,B5

编写了如下sql可以实现

SELECT your_column
FROM your_table
ORDER BY SUBSTRING(your_column FROM '^[A-Za-z]+') ASC, CAST(SUBSTRING(your_column FROM '[0-9]+$') AS INTEGER) ASC;

想问下可以类似和 自定义查询 一样,自定义排序吗?

zhou-hao commented 1 year ago
  1. 自定义实现接口FunctionFragmentBuilder,并注入spring.
  2. 前端排序参数: { ~"column":"your_column",~ "name":"your_column", "type":"FunctionFragmentBuilder#getFunction值", "opts":{ 其他拓展参数 }, "order":"asc" }

才加的功能,有啥问题随时反馈。

MoonBottle commented 1 year ago
@Data
public class OrderFunctionFragmentBuilder implements FunctionFragmentBuilder {

    private  String function;

    private  String name;

    @Override
    public SqlFragments create(String columnFullName, RDBColumnMetadata metadata, Map<String, Object> opts) {
        String sql = "ORDER BY SUBSTRING(" + columnFullName + " FROM '^[A-Za-z]+') ASC, CAST(SUBSTRING(" + columnFullName + " FROM '[0-9]+$') AS INTEGER) ASC";
        return PrepareSqlFragments
            .of()
            .addSql(function.concat("(").concat(sql).concat(")"));
    }

}
@Configuration
public class FunctionConfig {

    @Bean
    public OrderFunctionFragmentBuilder testOrder() {
        OrderFunctionFragmentBuilder orderFunctionFragmentBuilder = new OrderFunctionFragmentBuilder();
        orderFunctionFragmentBuilder.setFunction("testOrder");
        orderFunctionFragmentBuilder.setName("测试排序");
        return orderFunctionFragmentBuilder;
    }
}
{
            "name": "xxx",
            "type":"FunctionFragmentBuilder#testOrder",
            "order": "asc"
        }

我 debug 了一下,没有进入我的实现类,是哪里写的不对么?

MoonBottle commented 1 year ago

image

似乎是因为这里没赋值? org.hswebframework.ezorm.rdb.mapping.defaults.DefaultQuery#getSortOrder

zhou-hao commented 1 year ago

你的easyorm版本是多少。 需要最新 4.1.1-SNAPSHOT版本

type应该使用: "type":"testOrder"

MoonBottle commented 1 year ago

版本是最新的 4.1.1-SNAPSHOT 版本,使用 "type":"testOrder" 试了下,没有进入实体类的断点

zhou-hao commented 1 year ago

本地 刷新一下maven依赖

image
MoonBottle commented 1 year ago

刷新了,没有刷过来 - - image

zhou-hao commented 1 year ago

好的,我看看。

zhou-hao commented 1 year ago

再刷新一下试试

MoonBottle commented 1 year ago

这下有了,我再去试试 image

MoonBottle commented 1 year ago

可以执行了,不过有个小问题

    public SqlFragments create(String columnFullName, RDBColumnMetadata metadata, Map<String, Object> opts) {
        String sql = "SUBSTRING(" + columnFullName + " FROM '^[A-Za-z]+') ASC, CAST(SUBSTRING(" + columnFullName + " FROM '[0-9]+$') AS INTEGER) ASC";
        return PrepareSqlFragments
            .of()
            .addSql("(".concat(sql).concat(")"));
    }
        {
            "name": "xxx",
            "type": "testOrder",
            "opts": {},
            "order": "asc"  // 试过空字符串,拼出来的也是 asc
        },

拼出来的 sql 多了个 asc

order by (SUBSTRING(xxx FROM '^[A-Za-z]+') ASC, CAST(SUBSTRING(xxx  FROM '[0-9]+$') AS INTEGER) ASC) asc
MoonBottle commented 1 year ago

我这个情况比较特殊,等于是自己完全把 order 条件拼全了 - - ,用不到参数里的 order 字段

zhou-hao commented 1 year ago

我这个情况比较特殊,等于是自己完全把 order 条件拼全了 - - ,用不到参数里的 order 字段

默认asc就行了吧?不要在里面拼接多个order,应该是通过参数来传递多个order

MoonBottle commented 1 year ago

你是对的,我实现上有问题,应该定义成两个 function

MoonBottle commented 1 year ago

改成两个 function 可以了,多谢多谢!