zhuml4
2026-03-05 d6b4a1373d51f53d2e68b589c03b91511ece0c83
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
package com.xiaopeng.order.utils;
 
import lombok.extern.slf4j.Slf4j;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * 分表查询辅助工具类
 * 提供分表查询的SQL构建和批量查询支持
 *
 * @author auto-generated
 * @date 2026-03-05
 */
@Slf4j
public class ShardingQueryHelper {
 
    /**
     * 构建单个分表的查询SQL
     *
     * @param baseTableName 基础表名
     * @param shardingValue 分片键值
     * @param shardingCount 分片数量
     * @param whereClause   WHERE子句(不包含WHERE关键字)
     * @return 完整的查询SQL
     */
    public static String buildSingleTableQuery(String baseTableName, Long shardingValue,
                                               int shardingCount, String whereClause) {
        String tableName = ShardingTableUtil.getShardingTableName(baseTableName, shardingValue, shardingCount);
        StringBuilder sql = new StringBuilder("SELECT * FROM ");
        sql.append(tableName);
 
        if (whereClause != null && !whereClause.trim().isEmpty()) {
            sql.append(" WHERE ").append(whereClause);
        }
 
        String query = sql.toString();
        log.debug("Generated single table query: {}", query);
        return query;
    }
 
    /**
     * 构建全表扫描的UNION查询SQL(适用于需要查询所有分表的场景)
     *
     * @param baseTableName 基础表名
     * @param shardingCount 分片数量
     * @param whereClause   WHERE子句(不包含WHERE关键字)
     * @param orderBy       排序字句(不包含ORDER BY关键字)
     * @param limit         限制返回数量,null表示不限制
     * @return UNION查询SQL
     */
    public static String buildUnionAllQuery(String baseTableName, int shardingCount,
                                           String whereClause, String orderBy, Integer limit) {
        StringBuilder sql = new StringBuilder();
 
        for (int i = 0; i < shardingCount; i++) {
            if (i > 0) {
                sql.append(" UNION ALL ");
            }
 
            sql.append("SELECT * FROM ").append(baseTableName).append("_").append(i);
 
            if (whereClause != null && !whereClause.trim().isEmpty()) {
                sql.append(" WHERE ").append(whereClause);
            }
        }
 
        // 外层排序和限制
        if (orderBy != null && !orderBy.trim().isEmpty()) {
            sql.insert(0, "SELECT * FROM (");
            sql.append(") AS union_result ORDER BY ").append(orderBy);
        }
 
        if (limit != null && limit > 0) {
            sql.append(" LIMIT ").append(limit);
        }
 
        String query = sql.toString();
        log.debug("Generated union all query for {} tables: {}", shardingCount, query);
        return query;
    }
 
    /**
     * 获取需要查询的分表索引列表(基于分片键值范围)
     *
     * @param startValue    起始分片键值
     * @param endValue      结束分片键值
     * @param shardingCount 分片数量
     * @return 需要查询的表索引列表
     */
    public static List<Integer> getShardingIndexesInRange(Long startValue, Long endValue, int shardingCount) {
        List<Integer> indexes = new ArrayList<>();
 
        if (startValue == null || endValue == null || startValue > endValue) {
            log.warn("Invalid range: start={}, end={}, returning all indexes", startValue, endValue);
            for (int i = 0; i < shardingCount; i++) {
                indexes.add(i);
            }
            return indexes;
        }
 
        // 计算涉及的分表索引
        for (long value = startValue; value <= endValue; value++) {
            int index = (int) (value % shardingCount);
            if (!indexes.contains(index)) {
                indexes.add(index);
            }
        }
 
        log.debug("Range query from {} to {} covers indexes: {}", startValue, endValue, indexes);
        return indexes;
    }
 
    /**
     * 构建基于索引列表的UNION查询
     *
     * @param baseTableName    基础表名
     * @param tableIndexes     要查询的表索引列表
     * @param whereClause      WHERE子句
     * @param orderBy          排序字句
     * @param limit            限制数量
     * @return UNION查询SQL
     */
    public static String buildUnionQueryByIndexes(String baseTableName, List<Integer> tableIndexes,
                                                  String whereClause, String orderBy, Integer limit) {
        if (tableIndexes == null || tableIndexes.isEmpty()) {
            log.warn("No table indexes provided, returning empty query");
            return "";
        }
 
        StringBuilder sql = new StringBuilder();
 
        for (int i = 0; i < tableIndexes.size(); i++) {
            if (i > 0) {
                sql.append(" UNION ALL ");
            }
 
            int tableIndex = tableIndexes.get(i);
            sql.append("SELECT * FROM ").append(baseTableName).append("_").append(tableIndex);
 
            if (whereClause != null && !whereClause.trim().isEmpty()) {
                sql.append(" WHERE ").append(whereClause);
            }
        }
 
        // 外层排序和限制
        if (orderBy != null && !orderBy.trim().isEmpty()) {
            sql.insert(0, "SELECT * FROM (");
            sql.append(") AS union_result ORDER BY ").append(orderBy);
        }
 
        if (limit != null && limit > 0) {
            sql.append(" LIMIT ").append(limit);
        }
 
        String query = sql.toString();
        log.debug("Generated union query for indexes {}: {}", tableIndexes, query);
        return query;
    }
 
    /**
     * 构建订单相关表的批量查询SQL示例
     */
    public static class OrderQueryBuilder {
 
        /**
         * 根据用户ID查询订单
         */
        public static String queryOrderByUserId(Long appUserId, String additionalWhere) {
            String tableName = ShardingTableUtil.getOrderTableName(appUserId);
            StringBuilder sql = new StringBuilder("SELECT * FROM ").append(tableName);
            sql.append(" WHERE app_user_id = ").append(appUserId);
 
            if (additionalWhere != null && !additionalWhere.trim().isEmpty()) {
                sql.append(" AND ").append(additionalWhere);
            }
 
            return sql.toString();
        }
 
        /**
         * 根据订单ID查询订单详情
         */
        public static String queryOrderDetailByOrderId(Long orderId) {
            String tableName = ShardingTableUtil.getOrderDetailTableName(orderId);
            return "SELECT * FROM " + tableName + " WHERE order_id = " + orderId;
        }
 
        /**
         * 根据订单ID查询订单支付信息
         */
        public static String queryOrderPaymentByOrderId(Long orderId) {
            String tableName = ShardingTableUtil.getOrderPaymentTableName(orderId);
            return "SELECT * FROM " + tableName + " WHERE order_id = " + orderId;
        }
 
        /**
         * 根据订单ID查询订单评价
         */
        public static String queryOrderEvaluateByOrderId(Long orderId) {
            String tableName = ShardingTableUtil.getOrderEvaluateTableName(orderId);
            return "SELECT * FROM " + tableName + " WHERE order_id = " + orderId;
        }
 
        /**
         * 根据订单ID查询订单取消记录
         */
        public static String queryOrderCancelByOrderId(Long orderId) {
            String tableName = ShardingTableUtil.getOrderCancelTableName(orderId);
            return "SELECT * FROM " + tableName + " WHERE order_id = " + orderId;
        }
 
        /**
         * 查询所有订单(全表扫描)
         */
        public static String queryAllOrders(String whereClause, String orderBy, Integer limit) {
            return ShardingQueryHelper.buildUnionAllQuery("xp_order", 20, whereClause, orderBy, limit);
        }
 
        /**
         * 查询所有订单详情(全表扫描)
         */
        public static String queryAllOrderDetails(String whereClause, String orderBy, Integer limit) {
            return ShardingQueryHelper.buildUnionAllQuery("xp_order_detail", 20, whereClause, orderBy, limit);
        }
    }
 
    /**
     * 分表查询计数工具
     */
    public static class ShardingCountHelper {
 
        /**
         * 构建分表计数查询(UNION ALL + SUM)
         */
        public static String buildCountQuery(String baseTableName, int shardingCount, String whereClause) {
            StringBuilder sql = new StringBuilder("SELECT SUM(cnt) AS total_count FROM (");
 
            for (int i = 0; i < shardingCount; i++) {
                if (i > 0) {
                    sql.append(" UNION ALL ");
                }
 
                sql.append("SELECT COUNT(*) AS cnt FROM ").append(baseTableName).append("_").append(i);
 
                if (whereClause != null && !whereClause.trim().isEmpty()) {
                    sql.append(" WHERE ").append(whereClause);
                }
            }
 
            sql.append(") AS count_result");
 
            String query = sql.toString();
            log.debug("Generated count query: {}", query);
            return query;
        }
 
        /**
         * 统计所有订单数量
         */
        public static String countAllOrders(String whereClause) {
            return buildCountQuery("xp_order", 20, whereClause);
        }
    }
 
    /**
     * 打印查询示例
     */
    public static void printQueryExamples() {
        log.info("========== Sharding Query Examples ==========");
        log.info("1. Query order by userId 12345:");
        log.info("   {}", OrderQueryBuilder.queryOrderByUserId(12345L, "status = 1"));
        log.info("");
        log.info("2. Query order detail by orderId 67890:");
        log.info("   {}", OrderQueryBuilder.queryOrderDetailByOrderId(67890L));
        log.info("");
        log.info("3. Query all orders with status=1 (UNION ALL):");
        log.info("   {}", OrderQueryBuilder.queryAllOrders("status = 1", "create_time DESC", 100));
        log.info("");
        log.info("4. Count all orders:");
        log.info("   {}", ShardingCountHelper.countAllOrders("status IN (9, 10)"));
        log.info("=============================================");
    }
}