使用ibatis抛出java.lang.IllegalArgumentException实则抛出:NestedSQLException异常

程序在测试库上运行没有任何问题,一旦在正试库上运行就报错了。抛出了如下错误:

java.lang.IllegalArgumentException

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.ibatis.sqlmap.engine.accessplan.PropertyAccessPlan.setProperties(PropertyAccessPlan.java:46)
at com.ibatis.sqlmap.engine.exchange.JavaBeanDataExchange.setData(JavaBeanDataExchange.java:112)
at com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultObjectValues(BasicResultMap.java:373)
at com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.handleResultObject(RowHandlerCallback.java:64)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor.java:382)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleMultipleResults(SqlExecutor.java:301)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:190)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:205)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:615)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:589)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:118)
at org.springframework.orm.ibatis.SqlMapClientTemplate$3.doInSqlMapClient(SqlMapClientTemplate.java:263)
at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:188)
at org.springframework.orm.ibatis.SqlMapClientTemplate.executeWithListResult(SqlMapClientTemplate.java:214)
at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForList(SqlMapClientTemplate.java:261)
at com.nyl.crm.dao.BaseDaoImpl.queryForList(BaseDaoImpl.java:69)
at com.nyl.crm.service.BaseServiceImpl.getResultList(BaseServiceImpl.java:79)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:203)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:162)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:209)
at $Proxy5.getResultList(Unknown Source)
at com.nyl.crm.action.SysModelInfoAction.execute(SysModelInfoAction.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:404)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:267)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:229)
at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:221)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:150)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:48)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:123)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:167)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:105)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:83)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:207)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:74)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:127)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:107)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:206)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:115)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:143)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:121)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:170)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:123)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:50)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:504)
at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:419)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)

at java.lang.Thread.run(Thread.java:595)

查了半天,原来是数据问题,

在测试库上查出的记录每个字段都不为空

如图:

在正式库上查出的记录,有空字段,

如图:

解决方法:只要把具有空值的字段赋上默认值就能解决.

如图:


<think>好的,我现在需要帮助用户解决在MyBatis中遇到的日期类型与字符串类型比较导致的异常问题。首先,我需要回顾用户提供的错误信息和之前的对话历史,确保理解问题的根源。 用户当前的异常是`org.mybatis.spring.MyBatisSystemException`,嵌套的异常指出无效的比较:`java.util.Date`和`java.lang.String`。同时,引用了之前的问题,其中涉及PostgreSQL的日期类型与字符类型的操作符不匹配错误。用户现在希望解决MyBatis中类似的类型不匹配问题。 首先,我需要分析错误的原因。根据引用[3]和[5],MyBatis在进行条件判断时,如果日期类型的参数与空字符串`''`进行比较,会引发`IllegalArgumentException`。例如,在XML中的`<if test="handlingDate != null and handlingDate != ''">`这样的条件判断,当`handlingDate`是`java.util.Date`类型时,与空字符串比较会导致类型不匹配,因为Date类型不能与String直接比较。 接下来,用户提到的另一个引用[4]中的示例代码,虽然在SQL中使用了`date(create_time) = date(#{createTime})`,但问题可能出在MyBatis的条件判断部分。同样,引用[5]指出,去掉空字符串的判断可以解决问题,这说明问题的根源在于MyBatis的动态SQL条件中的类型比较。 用户之前的问题涉及PostgreSQL的日期与字符串类型不匹配,解决方法是显式类型转换或参数类型修正。现在在MyBatis中,虽然数据库不同,但问题类似,即类型不匹配导致SQL异常。 我需要考虑以下几点解决方案: 1. **去除空字符串判断**:根据引用[5],在MyBatis的条件判断中,如果参数是Date类型,与空字符串比较会导致错误。因此,用户应删除`handlingDate != ''`这样的条件,只保留非空检查。 2. **显式指定参数类型**:在MyBatis的XML映射文件中,使用`jdbcType`属性明确指定参数类型为DATE,例如`#{startDate, jdbcType=DATE}`,这有助于MyBatis正确处理类型转换。 3. **使用数据库函数转换**:在SQL语句中,使用数据库函数(如`DATE()`或PostgreSQL的`::date`)将传入的参数转换为日期类型,避免隐式转换问题。 4. **Java代码中参数类型修正**:确保传入的参数是`java.util.Date`或其子类(如`java.sql.Date`),而不是字符串,以避免类型不匹配。 5. **自定义类型处理器**:如果存在复杂的日期处理需求,可以创建自定义的MyBatis类型处理器,确保日期类型在传递到SQL时被正确转换。 另外,需要注意用户提到的`org.springframework.jdbc.BadSqlGrammarException`和PostgreSQL的PSQLException,这说明最终生成的SQL语法有问题,可能因为类型转换不正确导致数据库拒绝执行。 综合以上分析,解决方案应集中在修正MyBatis的动态SQL条件,避免Date与String的比较,并确保参数类型正确。同时,在SQL中显式转换类型,或调整Java代码中的参数类型,可以消除此类异常。 最后,验证步骤也很重要,用户需要测试修改后的代码,确保SQL正确生成,并且没有类型不匹配的错误。检查日志中的SQL语句,确认日期参数被正确转换为数据库接受的格式。</think>针对MyBatis中日期类型与字符串比较导致的异常问题,结合错误日志和引用内容,提供以下分步解决方案: --- ### 一、核心问题定位 1. **非法类型比较**:MyBatis动态SQL中`<if>`标签对`java.util.Date`类型参数执行`!= ''`空字符串判断时触发类型冲突[^3][^5] 2. **SQL参数类型不匹配**:XML映射中参数未正确声明日期类型,导致生成SQL时出现`date`与`varchar`类型比较 3. **框架处理机制**:MyBatis 3.4.6之前版本存在日期类型与空字符串比较的兼容性问题[^5] --- ### 二、解决方案步骤 #### 方法1:修正动态SQL条件判断(推荐) ```xml <!-- 原错误写法(包含字符串空值判断) --> <if test="handlingDate != null and handlingDate != ''"> <!-- 引发非法比较 --> handlingDate = #{handlingDate} </if> <!-- 修正后(仅保留非空判断) --> <if test="handlingDate != null"> <!-- 正确过滤null值 --> handlingDate = #{handlingDate, jdbcType=DATE} </if> ``` *原理*:`java.util.Date`类型参数无法与空字符串进行逻辑比较,删除`!= ''`判断可规避类型冲突[^5] #### 方法2:显式指定参数类型 ```xml <!-- 强制声明参数为DATE类型 --> <if test="startDate != null"> AND record_date = #{startDate, jdbcType=DATE} </if> <!-- PostgreSQL类型转换写法 --> <if test="endDate != null"> AND record_date <![CDATA[ <= ]]> #{endDate, jdbcType=DATE}::timestamp </if> ``` #### 方法3:Java代码层类型修正 ```java // Controller层传递参数时使用Date类型 @GetMapping("/query") public List<Record> queryRecords( @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date queryDate) { return service.getRecords(queryDate); } // Mapper接口明确参数类型 public interface RecordMapper { List<Record> selectByDate(@Param("queryDate") java.sql.Date queryDate); } ``` #### 方法4:数据库函数处理(跨数据库方案) ```xml <!-- 统一使用DATE()函数转换 --> <if test="createTime != null"> AND DATE(create_time) = DATE(#{createTime, jdbcType=TIMESTAMP}) </if> <!-- PostgreSQL特定写法 --> <where> create_time::date = #{targetDate, jdbcType=DATE}::date </where> ``` --- ### 三、错误重现与验证 #### 错误SQL生成示例 ```sql -- MyBatis错误生成的SQL(类型不匹配) SELECT * FROM check_record WHERE record_date >= '2023-01-01' -- 参数作为字符串传递 -- 修正后的正确SQL SELECT * FROM check_record WHERE record_date >= DATE '2023-01-01' ``` #### 调试建议 1. **开启MyBatis日志**: ```properties # application.properties logging.level.com.example.mapper=TRACE ``` 2. **检查生成的SQL**: ``` DEBUG [main] c.e.m.RecordMapper.selectByDate - ==> Preparing: SELECT * FROM check_record WHERE create_time::date = ?::date DEBUG [main] c.e.m.RecordMapper.selectByDate - ==> Parameters: 2023-08-15(Date) ``` --- ### 四、进阶优化方案 #### 1. 自定义类型处理器 ```java @MappedTypes(Date.class) @MappedJdbcTypes(JdbcType.DATE) public class StrictDateTypeHandler extends BaseTypeHandler<Date> { @Override public void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) { ps.setDate(i, new java.sql.Date(parameter.getTime())); } // 其他方法实现... } <!-- mybatis-config.xml注册处理器 --> <typeHandlers> <typeHandler handler="com.example.handler.StrictDateTypeHandler"/> </typeHandlers> ``` #### 2. SQL注入防护 ```xml <!-- 安全的时间范围查询 --> <where> <if test="beginDate != null"> AND create_time >= #{beginDate, jdbcType=DATE} </if> <if test="endDate != null"> AND create_time <![CDATA[ <= ]]> #{endDate, jdbcType=DATE} + INTERVAL '1 day' </if> </where> ``` --- ### 五、关联知识扩展 1. **PostgreSQL日期类型对照表**: | Java类型 | PostgreSQL类型 | 转换示例 | |--------------------|----------------|-------------------------| | java.sql.Date | DATE | `2023-08-15` | | java.sql.Timestamp | TIMESTAMP | `2023-08-15 14:30:00` | 2. **MyBatis类型处理优先级**: ``` 参数声明(jdbcType) → 类型处理器注册 → 数据库驱动转换 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值