springbootAI 1.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- spring/__init__.py +66 -0
- spring/ai/__init__.py +78 -0
- spring/ai/advisors.py +139 -0
- spring/ai/annotations.py +74 -0
- spring/ai/autoconfig.py +481 -0
- spring/ai/core.py +391 -0
- spring/ai/etl.py +188 -0
- spring/ai/memory.py +109 -0
- spring/ai/observability.py +129 -0
- spring/ai/providers.py +789 -0
- spring/ai/resilience.py +258 -0
- spring/ai/tools.py +106 -0
- spring/ai/vectorstore.py +303 -0
- spring/annotations/__init__.py +188 -0
- spring/annotations/cache.py +126 -0
- spring/annotations/cloud.py +207 -0
- spring/annotations/conditional.py +272 -0
- spring/annotations/core.py +864 -0
- spring/annotations/messaging.py +107 -0
- spring/aop/__init__.py +4 -0
- spring/aop/cloud_aop.py +404 -0
- spring/aop/comprehensive_aop.py +1015 -0
- spring/aop/method_interceptor.py +19 -0
- spring/aop/proxy_factory.py +55 -0
- spring/cloud/__init__.py +76 -0
- spring/cloud/discovery.py +364 -0
- spring/cloud/feign.py +469 -0
- spring/cloud/gateway.py +452 -0
- spring/cloud/load_balancer.py +149 -0
- spring/cloud/seata.py +557 -0
- spring/cloud/sentinel.py +525 -0
- spring/cloud/tracer.py +337 -0
- spring/config/__init__.py +21 -0
- spring/config/binding.py +206 -0
- spring/config/config_loader.py +405 -0
- spring/context/__init__.py +13 -0
- spring/context/application_context.py +589 -0
- spring/context/bean_definition.py +70 -0
- spring/context/bean_factory.py +1052 -0
- spring/context/registry.py +58 -0
- spring/context/scanner.py +106 -0
- spring/core/__init__.py +3 -0
- spring/core/graceful_shutdown.py +196 -0
- spring/core/typing_utils.py +50 -0
- spring/csv/__init__.py +52 -0
- spring/csv/annotations.py +402 -0
- spring/csv/converters.py +69 -0
- spring/csv/easy_csv.py +95 -0
- spring/csv/exceptions.py +27 -0
- spring/csv/reader.py +195 -0
- spring/csv/writer.py +155 -0
- spring/data/__init__.py +54 -0
- spring/data/page.py +181 -0
- spring/data/repository.py +274 -0
- spring/data/specification.py +228 -0
- spring/datasource/__init__.py +66 -0
- spring/datasource/annotations.py +133 -0
- spring/datasource/context.py +69 -0
- spring/datasource/dynamic.py +148 -0
- spring/event/__init__.py +7 -0
- spring/event/publisher.py +69 -0
- spring/excel/__init__.py +51 -0
- spring/excel/annotations.py +405 -0
- spring/excel/converters.py +231 -0
- spring/excel/easy_excel.py +94 -0
- spring/excel/exceptions.py +31 -0
- spring/excel/reader.py +254 -0
- spring/excel/style.py +95 -0
- spring/excel/writer.py +197 -0
- spring/i18n/__init__.py +97 -0
- spring/i18n/accessor.py +94 -0
- spring/i18n/auto_config.py +177 -0
- spring/i18n/holder.py +106 -0
- spring/i18n/locale.py +152 -0
- spring/i18n/locale_resolver.py +367 -0
- spring/i18n/message_source.py +250 -0
- spring/i18n/middleware.py +79 -0
- spring/i18n/properties.py +168 -0
- spring/i18n/sources.py +255 -0
- spring/logging/__init__.py +1 -0
- spring/logging/loguru_logger.py +228 -0
- spring/main.py +378 -0
- spring/messaging/__init__.py +1 -0
- spring/messaging/rabbitmq.py +302 -0
- spring/monitoring/__init__.py +1 -0
- spring/monitoring/prometheus.py +199 -0
- spring/orm/__init__.py +258 -0
- spring/orm/database.py +222 -0
- spring/orm/ddl_auto.py +1217 -0
- spring/orm/migration.py +419 -0
- spring/orm/mybatis_integration.py +400 -0
- spring/orm/pymybatis/__init__.py +86 -0
- spring/orm/pymybatis/annotations/__init__.py +30 -0
- spring/orm/pymybatis/annotations/annotations.py +332 -0
- spring/orm/pymybatis/cache/__init__.py +47 -0
- spring/orm/pymybatis/cache/cache.py +371 -0
- spring/orm/pymybatis/cache/redis_cache.py +434 -0
- spring/orm/pymybatis/circuit_breaker/__init__.py +21 -0
- spring/orm/pymybatis/circuit_breaker/circuit_breaker.py +424 -0
- spring/orm/pymybatis/configuration.py +525 -0
- spring/orm/pymybatis/core/__init__.py +10 -0
- spring/orm/pymybatis/core/sql_session.py +1382 -0
- spring/orm/pymybatis/core/sql_session_factory.py +76 -0
- spring/orm/pymybatis/dialect/__init__.py +9 -0
- spring/orm/pymybatis/dialect/dialect.py +445 -0
- spring/orm/pymybatis/dynamic_sql/__init__.py +9 -0
- spring/orm/pymybatis/dynamic_sql/dynamic_sql.py +900 -0
- spring/orm/pymybatis/interceptor/__init__.py +31 -0
- spring/orm/pymybatis/interceptor/interceptor.py +427 -0
- spring/orm/pymybatis/mapper/__init__.py +9 -0
- spring/orm/pymybatis/mapper/mapper.py +540 -0
- spring/orm/pymybatis/metrics/__init__.py +41 -0
- spring/orm/pymybatis/metrics/metrics.py +595 -0
- spring/orm/pymybatis/pool/__init__.py +9 -0
- spring/orm/pymybatis/pool/connection_pool.py +711 -0
- spring/orm/pymybatis/security/__init__.py +19 -0
- spring/orm/pymybatis/security/access_control.py +415 -0
- spring/orm/pymybatis/security/password_encoder.py +293 -0
- spring/orm/pymybatis/security/sensitive_data_masker.py +326 -0
- spring/orm/pymybatis/security/sql_injection_detector.py +675 -0
- spring/orm/pymybatis/transaction/__init__.py +9 -0
- spring/orm/pymybatis/transaction/transaction.py +288 -0
- spring/orm/pymybatis/type_handler/__init__.py +37 -0
- spring/orm/pymybatis/type_handler/type_handler.py +473 -0
- spring/orm/pymybatis/version.py +9 -0
- spring/orm/pymybatis/xml_parser/__init__.py +9 -0
- spring/orm/pymybatis/xml_parser/xml_parser.py +761 -0
- spring/retry/__init__.py +12 -0
- spring/retry/retry_annotations.py +71 -0
- spring/retry/retry_decorator.py +155 -0
- spring/scheduling/__init__.py +3 -0
- spring/scheduling/scheduler.py +389 -0
- spring/security/__init__.py +39 -0
- spring/security/jwt_utils.py +281 -0
- spring/security/replay_protection.py +206 -0
- spring/security/secret_manager.py +226 -0
- spring/security/security_aop.py +248 -0
- spring/security/security_context.py +172 -0
- spring/test/__init__.py +45 -0
- spring/test/slicing.py +341 -0
- spring/tracing/__init__.py +11 -0
- spring/tracing/skywalking.py +229 -0
- spring/tx/__init__.py +52 -0
- spring/tx/events.py +172 -0
- spring/tx/synchronization.py +143 -0
- spring/utils/__init__.py +5 -0
- spring/utils/banner.py +32 -0
- spring/utils/logger.py +73 -0
- spring/utils/redis_client.py +526 -0
- spring/validation/__init__.py +55 -0
- spring/validation/aop.py +141 -0
- spring/validation/constraints.py +357 -0
- spring/validation/exceptions.py +55 -0
- spring/validation/validator.py +139 -0
- spring/web/__init__.py +12 -0
- spring/web/actuator.py +319 -0
- spring/web/exception_handler.py +61 -0
- spring/web/health.py +399 -0
- spring/web/interceptor.py +91 -0
- spring/web/result.py +44 -0
- spring/web/swagger.py +601 -0
- spring/web/web_context.py +755 -0
- spring/websocket/__init__.py +86 -0
- spring/websocket/annotations.py +169 -0
- spring/websocket/broker.py +238 -0
- spring/websocket/exceptions.py +26 -0
- spring/websocket/handler.py +243 -0
- spring/websocket/router.py +526 -0
- spring/websocket/session.py +216 -0
- springbootai-1.8.0.dist-info/METADATA +2796 -0
- springbootai-1.8.0.dist-info/RECORD +175 -0
- springbootai-1.8.0.dist-info/WHEEL +5 -0
- springbootai-1.8.0.dist-info/entry_points.txt +2 -0
- springbootai-1.8.0.dist-info/licenses/LICENSE +7 -0
- springbootai-1.8.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PyMyBatis类型处理器模块
|
|
3
|
+
|
|
4
|
+
支持自定义类型转换,适配不同数据库类型
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import datetime
|
|
8
|
+
import decimal
|
|
9
|
+
import enum
|
|
10
|
+
import uuid
|
|
11
|
+
from typing import Any, Optional, Dict
|
|
12
|
+
from abc import ABC, abstractmethod
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TypeHandler(ABC):
|
|
16
|
+
"""
|
|
17
|
+
类型处理器抽象基类
|
|
18
|
+
|
|
19
|
+
定义类型转换的核心接口:
|
|
20
|
+
- java_type: Java类型
|
|
21
|
+
- jdbc_type: JDBC类型
|
|
22
|
+
- set_parameter: 设置参数
|
|
23
|
+
- get_result: 获取结果
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def java_type(self) -> type:
|
|
29
|
+
"""Java类型"""
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
@abstractmethod
|
|
34
|
+
def jdbc_type(self) -> str:
|
|
35
|
+
"""JDBC类型"""
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
40
|
+
"""
|
|
41
|
+
设置参数
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
statement: SQL语句对象
|
|
45
|
+
parameter_index: 参数索引
|
|
46
|
+
value: 参数值
|
|
47
|
+
"""
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
@abstractmethod
|
|
51
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
52
|
+
"""
|
|
53
|
+
获取结果
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
result_set: 结果集
|
|
57
|
+
column_name: 列名
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
转换后的结果
|
|
61
|
+
"""
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
def to_database(self, value: Any) -> Any:
|
|
65
|
+
"""Convert a Python value before passing it to a DB-API driver."""
|
|
66
|
+
return value
|
|
67
|
+
|
|
68
|
+
def from_database(self, value: Any) -> Any:
|
|
69
|
+
"""Convert a DB-API value back to the declared Python type."""
|
|
70
|
+
return value
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class IntegerTypeHandler(TypeHandler):
|
|
74
|
+
"""Integer类型处理器"""
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def java_type(self) -> type:
|
|
78
|
+
return int
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def jdbc_type(self) -> str:
|
|
82
|
+
return 'INTEGER'
|
|
83
|
+
|
|
84
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
85
|
+
statement.setdefault(str(parameter_index), int(value) if value is not None else None)
|
|
86
|
+
|
|
87
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
88
|
+
value = result_set.get(column_name)
|
|
89
|
+
return int(value) if value is not None else None
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class LongTypeHandler(TypeHandler):
|
|
93
|
+
"""Long类型处理器"""
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def java_type(self) -> type:
|
|
97
|
+
return int
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def jdbc_type(self) -> str:
|
|
101
|
+
return 'BIGINT'
|
|
102
|
+
|
|
103
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
104
|
+
statement.setdefault(str(parameter_index), int(value) if value is not None else None)
|
|
105
|
+
|
|
106
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
107
|
+
value = result_set.get(column_name)
|
|
108
|
+
return int(value) if value is not None else None
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class StringTypeHandler(TypeHandler):
|
|
112
|
+
"""String类型处理器"""
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def java_type(self) -> type:
|
|
116
|
+
return str
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def jdbc_type(self) -> str:
|
|
120
|
+
return 'VARCHAR'
|
|
121
|
+
|
|
122
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
123
|
+
statement.setdefault(str(parameter_index), str(value) if value is not None else None)
|
|
124
|
+
|
|
125
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
126
|
+
value = result_set.get(column_name)
|
|
127
|
+
return str(value) if value is not None else None
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class BooleanTypeHandler(TypeHandler):
|
|
131
|
+
"""Boolean类型处理器"""
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def java_type(self) -> type:
|
|
135
|
+
return bool
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def jdbc_type(self) -> str:
|
|
139
|
+
return 'BOOLEAN'
|
|
140
|
+
|
|
141
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
142
|
+
statement.setdefault(str(parameter_index), bool(value) if value is not None else None)
|
|
143
|
+
|
|
144
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
145
|
+
value = result_set.get(column_name)
|
|
146
|
+
return bool(value) if value is not None else None
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class FloatTypeHandler(TypeHandler):
|
|
150
|
+
"""Float类型处理器"""
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def java_type(self) -> type:
|
|
154
|
+
return float
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def jdbc_type(self) -> str:
|
|
158
|
+
return 'FLOAT'
|
|
159
|
+
|
|
160
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
161
|
+
statement.setdefault(str(parameter_index), float(value) if value is not None else None)
|
|
162
|
+
|
|
163
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
164
|
+
value = result_set.get(column_name)
|
|
165
|
+
return float(value) if value is not None else None
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class DoubleTypeHandler(TypeHandler):
|
|
169
|
+
"""Double类型处理器"""
|
|
170
|
+
|
|
171
|
+
@property
|
|
172
|
+
def java_type(self) -> type:
|
|
173
|
+
return float
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def jdbc_type(self) -> str:
|
|
177
|
+
return 'DOUBLE'
|
|
178
|
+
|
|
179
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
180
|
+
statement.setdefault(str(parameter_index), float(value) if value is not None else None)
|
|
181
|
+
|
|
182
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
183
|
+
value = result_set.get(column_name)
|
|
184
|
+
return float(value) if value is not None else None
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class DateTypeHandler(TypeHandler):
|
|
188
|
+
"""Date类型处理器"""
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def java_type(self) -> type:
|
|
192
|
+
return datetime.date
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def jdbc_type(self) -> str:
|
|
196
|
+
return 'DATE'
|
|
197
|
+
|
|
198
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
199
|
+
if value is None:
|
|
200
|
+
statement.setdefault(str(parameter_index), None)
|
|
201
|
+
elif isinstance(value, datetime.datetime):
|
|
202
|
+
statement.setdefault(str(parameter_index), value.date())
|
|
203
|
+
elif isinstance(value, datetime.date):
|
|
204
|
+
statement.setdefault(str(parameter_index), value)
|
|
205
|
+
else:
|
|
206
|
+
statement.setdefault(str(parameter_index), datetime.datetime.strptime(value, '%Y-%m-%d').date())
|
|
207
|
+
|
|
208
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
209
|
+
value = result_set.get(column_name)
|
|
210
|
+
if value is None:
|
|
211
|
+
return None
|
|
212
|
+
if isinstance(value, datetime.datetime):
|
|
213
|
+
return value.date()
|
|
214
|
+
if isinstance(value, datetime.date):
|
|
215
|
+
return value
|
|
216
|
+
return datetime.datetime.strptime(str(value), '%Y-%m-%d').date()
|
|
217
|
+
|
|
218
|
+
def to_database(self, value: Any) -> Any:
|
|
219
|
+
if isinstance(value, datetime.datetime):
|
|
220
|
+
return value.date().isoformat()
|
|
221
|
+
if isinstance(value, datetime.date):
|
|
222
|
+
return value.isoformat()
|
|
223
|
+
return value
|
|
224
|
+
|
|
225
|
+
def from_database(self, value: Any) -> Any:
|
|
226
|
+
if value is None or isinstance(value, datetime.date):
|
|
227
|
+
return value
|
|
228
|
+
return datetime.date.fromisoformat(str(value))
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class DateTimeTypeHandler(TypeHandler):
|
|
232
|
+
"""DateTime类型处理器"""
|
|
233
|
+
|
|
234
|
+
@property
|
|
235
|
+
def java_type(self) -> type:
|
|
236
|
+
return datetime.datetime
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
def jdbc_type(self) -> str:
|
|
240
|
+
return 'TIMESTAMP'
|
|
241
|
+
|
|
242
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
243
|
+
if value is None:
|
|
244
|
+
statement.setdefault(str(parameter_index), None)
|
|
245
|
+
elif isinstance(value, datetime.datetime):
|
|
246
|
+
statement.setdefault(str(parameter_index), value)
|
|
247
|
+
else:
|
|
248
|
+
statement.setdefault(str(parameter_index), datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S'))
|
|
249
|
+
|
|
250
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
251
|
+
value = result_set.get(column_name)
|
|
252
|
+
if value is None:
|
|
253
|
+
return None
|
|
254
|
+
if isinstance(value, datetime.datetime):
|
|
255
|
+
return value
|
|
256
|
+
if isinstance(value, datetime.date):
|
|
257
|
+
return datetime.datetime(value.year, value.month, value.day)
|
|
258
|
+
return datetime.datetime.strptime(str(value), '%Y-%m-%d %H:%M:%S')
|
|
259
|
+
|
|
260
|
+
def to_database(self, value: Any) -> Any:
|
|
261
|
+
return value.isoformat(sep=' ') if isinstance(value, datetime.datetime) else value
|
|
262
|
+
|
|
263
|
+
def from_database(self, value: Any) -> Any:
|
|
264
|
+
if value is None or isinstance(value, datetime.datetime):
|
|
265
|
+
return value
|
|
266
|
+
return datetime.datetime.fromisoformat(str(value))
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class DecimalTypeHandler(TypeHandler):
|
|
270
|
+
"""Portable DECIMAL/NUMERIC handler for DB-API drivers."""
|
|
271
|
+
|
|
272
|
+
@property
|
|
273
|
+
def java_type(self) -> type:
|
|
274
|
+
return decimal.Decimal
|
|
275
|
+
|
|
276
|
+
@property
|
|
277
|
+
def jdbc_type(self) -> str:
|
|
278
|
+
return 'DECIMAL'
|
|
279
|
+
|
|
280
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
281
|
+
statement.setdefault(str(parameter_index), self.to_database(value))
|
|
282
|
+
|
|
283
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
284
|
+
value = result_set.get(column_name)
|
|
285
|
+
return self.from_database(value)
|
|
286
|
+
|
|
287
|
+
def to_database(self, value: Any) -> Any:
|
|
288
|
+
return None if value is None else str(value)
|
|
289
|
+
|
|
290
|
+
def from_database(self, value: Any) -> Any:
|
|
291
|
+
return None if value is None else decimal.Decimal(str(value))
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class UUIDTypeHandler(TypeHandler):
|
|
295
|
+
"""Store UUID values as portable text while retaining UUID on reads."""
|
|
296
|
+
|
|
297
|
+
@property
|
|
298
|
+
def java_type(self) -> type:
|
|
299
|
+
return uuid.UUID
|
|
300
|
+
|
|
301
|
+
@property
|
|
302
|
+
def jdbc_type(self) -> str:
|
|
303
|
+
return 'VARCHAR'
|
|
304
|
+
|
|
305
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any) -> None:
|
|
306
|
+
statement.setdefault(str(parameter_index), self.to_database(value))
|
|
307
|
+
|
|
308
|
+
def get_result(self, result_set: Any, column_name: str) -> Any:
|
|
309
|
+
return self.from_database(result_set.get(column_name))
|
|
310
|
+
|
|
311
|
+
def to_database(self, value: Any) -> Any:
|
|
312
|
+
return None if value is None else str(value)
|
|
313
|
+
|
|
314
|
+
def from_database(self, value: Any) -> Any:
|
|
315
|
+
return None if value is None or isinstance(value, uuid.UUID) else uuid.UUID(str(value))
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
class TypeHandlerRegistry:
|
|
319
|
+
"""
|
|
320
|
+
类型处理器注册中心
|
|
321
|
+
|
|
322
|
+
管理所有类型处理器,支持自动选择和自定义注册
|
|
323
|
+
"""
|
|
324
|
+
|
|
325
|
+
def __init__(self):
|
|
326
|
+
"""初始化类型处理器注册中心"""
|
|
327
|
+
self.type_handlers: Dict[type, TypeHandler] = {}
|
|
328
|
+
self.jdbc_type_handlers: Dict[str, TypeHandler] = {}
|
|
329
|
+
|
|
330
|
+
# 注册默认类型处理器
|
|
331
|
+
self._register_default_handlers()
|
|
332
|
+
|
|
333
|
+
def _register_default_handlers(self) -> None:
|
|
334
|
+
"""注册默认类型处理器"""
|
|
335
|
+
self.register(int, IntegerTypeHandler())
|
|
336
|
+
self.register(bool, BooleanTypeHandler())
|
|
337
|
+
self.register(float, DoubleTypeHandler())
|
|
338
|
+
self.register(str, StringTypeHandler())
|
|
339
|
+
self.register(datetime.date, DateTypeHandler())
|
|
340
|
+
self.register(datetime.datetime, DateTimeTypeHandler())
|
|
341
|
+
self.register(decimal.Decimal, DecimalTypeHandler())
|
|
342
|
+
self.register(uuid.UUID, UUIDTypeHandler())
|
|
343
|
+
|
|
344
|
+
def register(self, java_type: type, handler: TypeHandler, jdbc_type: Optional[str] = None) -> None:
|
|
345
|
+
"""
|
|
346
|
+
注册类型处理器
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
java_type: Java类型
|
|
350
|
+
handler: 类型处理器
|
|
351
|
+
"""
|
|
352
|
+
# Also accept MyBatis' ``register(java_type, jdbc_type, handler)``
|
|
353
|
+
# ordering for easier Java-to-Python migration.
|
|
354
|
+
if isinstance(handler, str) and isinstance(jdbc_type, TypeHandler):
|
|
355
|
+
handler, jdbc_type = jdbc_type, handler
|
|
356
|
+
self.type_handlers[java_type] = handler
|
|
357
|
+
if jdbc_type:
|
|
358
|
+
self.jdbc_type_handlers[str(jdbc_type).upper()] = handler
|
|
359
|
+
|
|
360
|
+
def get_handler(self, java_type: type, jdbc_type: Optional[str] = None) -> Optional[TypeHandler]:
|
|
361
|
+
"""
|
|
362
|
+
获取类型处理器
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
java_type: Java类型
|
|
366
|
+
|
|
367
|
+
Returns:
|
|
368
|
+
类型处理器,未找到返回None
|
|
369
|
+
"""
|
|
370
|
+
if jdbc_type is not None:
|
|
371
|
+
handler = self.jdbc_type_handlers.get(str(jdbc_type).upper())
|
|
372
|
+
if handler is not None:
|
|
373
|
+
return handler
|
|
374
|
+
handler = self.type_handlers.get(java_type)
|
|
375
|
+
if handler is not None:
|
|
376
|
+
return handler
|
|
377
|
+
for registered_type, registered_handler in self.type_handlers.items():
|
|
378
|
+
try:
|
|
379
|
+
if isinstance(java_type, type) and isinstance(registered_type, type) and issubclass(java_type, registered_type):
|
|
380
|
+
return registered_handler
|
|
381
|
+
except TypeError:
|
|
382
|
+
continue
|
|
383
|
+
return None
|
|
384
|
+
|
|
385
|
+
def get_handler_by_jdbc_type(self, jdbc_type: str) -> Optional[TypeHandler]:
|
|
386
|
+
"""
|
|
387
|
+
根据JDBC类型获取类型处理器
|
|
388
|
+
|
|
389
|
+
Args:
|
|
390
|
+
jdbc_type: JDBC类型
|
|
391
|
+
|
|
392
|
+
Returns:
|
|
393
|
+
类型处理器,未找到返回None
|
|
394
|
+
"""
|
|
395
|
+
for handler in self.type_handlers.values():
|
|
396
|
+
if handler.jdbc_type == jdbc_type:
|
|
397
|
+
return handler
|
|
398
|
+
return None
|
|
399
|
+
|
|
400
|
+
def get_or_default(self, java_type: type) -> TypeHandler:
|
|
401
|
+
"""
|
|
402
|
+
获取类型处理器,如果未找到则返回String类型处理器
|
|
403
|
+
|
|
404
|
+
Args:
|
|
405
|
+
java_type: Java类型
|
|
406
|
+
|
|
407
|
+
Returns:
|
|
408
|
+
类型处理器
|
|
409
|
+
"""
|
|
410
|
+
handler = self.get_handler(java_type)
|
|
411
|
+
if handler is None:
|
|
412
|
+
handler = StringTypeHandler()
|
|
413
|
+
return handler
|
|
414
|
+
|
|
415
|
+
def to_database(self, value: Any) -> Any:
|
|
416
|
+
if value is None:
|
|
417
|
+
return None
|
|
418
|
+
if isinstance(value, enum.Enum):
|
|
419
|
+
value = value.value
|
|
420
|
+
handler = self.get_handler(type(value))
|
|
421
|
+
return handler.to_database(value) if handler else value
|
|
422
|
+
|
|
423
|
+
def from_database(self, value: Any, java_type: Optional[type] = None) -> Any:
|
|
424
|
+
if value is None or java_type is None:
|
|
425
|
+
return value
|
|
426
|
+
handler = self.get_handler(java_type)
|
|
427
|
+
return handler.from_database(value) if handler else value
|
|
428
|
+
|
|
429
|
+
def set_parameter(self, statement: Any, parameter_index: int, value: Any, java_type: Optional[type] = None) -> None:
|
|
430
|
+
"""
|
|
431
|
+
设置参数
|
|
432
|
+
|
|
433
|
+
Args:
|
|
434
|
+
statement: SQL语句对象
|
|
435
|
+
parameter_index: 参数索引
|
|
436
|
+
value: 参数值
|
|
437
|
+
java_type: Java类型,不指定则自动推断
|
|
438
|
+
"""
|
|
439
|
+
if java_type is None:
|
|
440
|
+
java_type = type(value) if value is not None else str
|
|
441
|
+
|
|
442
|
+
handler = self.get_or_default(java_type)
|
|
443
|
+
handler.set_parameter(statement, parameter_index, value)
|
|
444
|
+
|
|
445
|
+
def get_result(self, result_set: Any, column_name: str, java_type: Optional[type] = None) -> Any:
|
|
446
|
+
"""
|
|
447
|
+
获取结果
|
|
448
|
+
|
|
449
|
+
Args:
|
|
450
|
+
result_set: 结果集
|
|
451
|
+
column_name: 列名
|
|
452
|
+
java_type: Java类型,不指定则自动推断
|
|
453
|
+
|
|
454
|
+
Returns:
|
|
455
|
+
转换后的结果
|
|
456
|
+
"""
|
|
457
|
+
value = result_set.get(column_name)
|
|
458
|
+
|
|
459
|
+
if java_type is None:
|
|
460
|
+
if value is None:
|
|
461
|
+
return None
|
|
462
|
+
java_type = type(value)
|
|
463
|
+
|
|
464
|
+
handler = self.get_or_default(java_type)
|
|
465
|
+
return handler.get_result(result_set, column_name)
|
|
466
|
+
|
|
467
|
+
def get_all_handlers(self) -> Dict[type, TypeHandler]:
|
|
468
|
+
"""获取所有类型处理器"""
|
|
469
|
+
return self.type_handlers
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
# 全局默认类型处理器注册中心
|
|
473
|
+
DEFAULT_REGISTRY = TypeHandlerRegistry()
|