Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lealone + mybatis plus LocalDateTime字段插入数据报错 #179

Open
zhoujin7 opened this issue May 15, 2023 · 14 comments
Open

lealone + mybatis plus LocalDateTime字段插入数据报错 #179

zhoujin7 opened this issue May 15, 2023 · 14 comments

Comments

@zhoujin7
Copy link

测试项目 https://github.com/zhoujin7/lealone-boot
执行:
https://github.com/zhoujin7/lealone-boot/blob/main/src/test/java/com/example/lealoneboot/LealoneBootApplicationTests.java

需要先将依赖库mvn install到本地 https://github.com/zhoujin7/mybatis-plus (对mybatis-plus添加了对lealone的支持)

实体类User
private LocalDateTime createdAt;
如果用java.util.Date类型就不会报错.

报错信息:

2023-05-15 20:46:29.949 ERROR 75200 --- [           main] druid.sql.Statement                      : {conn-10005, pstmt-20005} execute error. INSERT INTO sys_user  ( user_id,
username,
nickname,
phone,
gender,
password,
memo,
created_by,
created_at )  VALUES  ( ?,
?,
?,
?,
?,
?,
?,
?,
? )

org.lealone.common.exceptions.JdbcSQLException: Cannot parse "TIMESTAMP" constant "aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e7050f142e1d361efb0078"; SQL statement:
INSERT INTO sys_user  ( user_id,
username,
nickname,
phone,
gender,
password,
memo,
created_by,
created_at )  VALUES  ( ?,
?,
?,
?,
?,
?,
?,
?,
? ) -- row #2 (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9) [22007-2]
	at org.lealone.net.TransferConnection.parseError(TransferConnection.java:72) ~[lealone-net-5.1.2.jar:na]
	at org.lealone.net.TcpClientConnection.handleResponse(TcpClientConnection.java:96) ~[lealone-net-5.1.2.jar:na]
	at org.lealone.net.TransferConnection.handle(TransferConnection.java:130) ~[lealone-net-5.1.2.jar:na]
	at org.lealone.net.nio.NioEventLoop.read(NioEventLoop.java:224) ~[lealone-net-5.1.2.jar:na]
	at org.lealone.net.nio.NioEventLoopClient.run(NioEventLoopClient.java:75) ~[lealone-net-5.1.2.jar:na]
	at org.lealone.net.nio.NioEventLoopClient.lambda$0(NioEventLoopClient.java:47) ~[lealone-net-5.1.2.jar:na]
	at java.lang.Thread.run(Thread.java:750) ~[na:1.8.0_371]


org.springframework.dao.DataIntegrityViolationException: 
### Error updating database.  Cause: org.lealone.common.exceptions.JdbcSQLException: Cannot parse "TIMESTAMP" constant "aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e7050f142e1d361efb0078"; SQL statement:
INSERT INTO sys_user  ( user_id,
username,
nickname,
phone,
gender,
password,
memo,
created_by,
created_at )  VALUES  ( ?,
?,
?,
?,
?,
?,
?,
?,
? ) -- row #2 (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9) [22007-2]
	at org.lealone.common.exceptions.DbException.getJdbcSQLException(DbException.java:342)
	at org.lealone.common.exceptions.DbException.get(DbException.java:162)
	at org.lealone.db.value.ValueTimestamp.parse(ValueTimestamp.java:91)
	at org.lealone.db.value.Value.convertTo(Value.java:876)
	at org.lealone.db.table.Column.convert(Column.java:149)
	at org.lealone.sql.dml.MerSert$YieldableMerSert.createNewRow(MerSert.java:170)
	at org.lealone.sql.dml.Insert$YieldableInsert.executeLoopUpdate(Insert.java:92)
	at org.lealone.sql.executor.YieldableLoopUpdateBase.executeInternal(YieldableLoopUpdateBase.java:30)
	at org.lealone.sql.executor.YieldableBase.run(YieldableBase.java:97)
	at org.lealone.db.session.ServerSession$YieldableCommand.run(ServerSession.java:1188)
	at org.lealone.server.Scheduler.executeNextStatement(Scheduler.java:224)
	at org.lealone.server.Scheduler.run(Scheduler.java:97)
Caused by: java.lang.IllegalArgumentException: aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e7050f142e1d361efb0078
	at org.lealone.common.util.DateTimeUtils.parseDateValue(DateTimeUtils.java:267)
	at org.lealone.db.value.ValueTimestamp.parseTry(ValueTimestamp.java:108)
	at org.lealone.db.value.ValueTimestamp.parse(ValueTimestamp.java:89)
	... 9 more

### The error may exist in com/example/lealoneboot/mapper/UserMapper.java (best guess)
### The error may involve com.example.lealoneboot.mapper.UserMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO sys_user  ( user_id, username, nickname, phone, gender, password, memo, created_by, created_at )  VALUES  ( ?, ?, ?, ?, ?, ?, ?, ?, ? )
### Cause: org.lealone.common.exceptions.JdbcSQLException: Cannot parse "TIMESTAMP" constant "aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e7050f142e1d361efb0078"; SQL statement:
INSERT INTO sys_user  ( user_id,
username,
nickname,
phone,
gender,
password,
memo,
created_by,
created_at )  VALUES  ( ?,
?,
?,
?,
?,
?,
?,
?,
? ) -- row #2 (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9) [22007-2]
	at org.lealone.common.exceptions.DbException.getJdbcSQLException(DbException.java:342)
	at org.lealone.common.exceptions.DbException.get(DbException.java:162)
	at org.lealone.db.value.ValueTimestamp.parse(ValueTimestamp.java:91)
	at org.lealone.db.value.Value.convertTo(Value.java:876)
	at org.lealone.db.table.Column.convert(Column.java:149)
	at org.lealone.sql.dml.MerSert$YieldableMerSert.createNewRow(MerSert.java:170)
	at org.lealone.sql.dml.Insert$YieldableInsert.executeLoopUpdate(Insert.java:92)
	at org.lealone.sql.executor.YieldableLoopUpdateBase.executeInternal(YieldableLoopUpdateBase.java:30)
	at org.lealone.sql.executor.YieldableBase.run(YieldableBase.java:97)
	at org.lealone.db.session.ServerSession$YieldableCommand.run(ServerSession.java:1188)
	at org.lealone.server.Scheduler.executeNextStatement(Scheduler.java:224)
	at org.lealone.server.Scheduler.run(Scheduler.java:97)
Caused by: java.lang.IllegalArgumentException: aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e7050f142e1d361efb0078
	at org.lealone.common.util.DateTimeUtils.parseDateValue(DateTimeUtils.java:267)
	at org.lealone.db.value.ValueTimestamp.parseTry(ValueTimestamp.java:108)
	at org.lealone.db.value.ValueTimestamp.parse(ValueTimestamp.java:89)
	... 9 more

; Cannot parse "TIMESTAMP" constant "aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e7050f142e1d361efb0078"; SQL statement:
INSERT INTO sys_user  ( user_id,
username,
nickname,
phone,
gender,
password,
memo,
created_by,
created_at )  VALUES  ( ?,
?,
?,
?,
?,
?,
?,
?,
? ) -- row #2 (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9) [22007-2]; nested exception is org.lealone.common.exceptions.JdbcSQLException: Cannot parse "TIMESTAMP" constant "aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e7050f142e1d361efb0078"; SQL statement:
INSERT INTO sys_user  ( user_id,
username,
nickname,
phone,
gender,
password,
memo,
created_by,
created_at )  VALUES  ( ?,
?,
?,
?,
?,
?,
?,
?,
? ) -- row #2 (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9) [22007-2]
	at org.lealone.common.exceptions.DbException.getJdbcSQLException(DbException.java:342)
	at org.lealone.common.exceptions.DbException.get(DbException.java:162)
	at org.lealone.db.value.ValueTimestamp.parse(ValueTimestamp.java:91)
	at org.lealone.db.value.Value.convertTo(Value.java:876)
	at org.lealone.db.table.Column.convert(Column.java:149)
	at org.lealone.sql.dml.MerSert$YieldableMerSert.createNewRow(MerSert.java:170)
	at org.lealone.sql.dml.Insert$YieldableInsert.executeLoopUpdate(Insert.java:92)
	at org.lealone.sql.executor.YieldableLoopUpdateBase.executeInternal(YieldableLoopUpdateBase.java:30)
	at org.lealone.sql.executor.YieldableBase.run(YieldableBase.java:97)
	at org.lealone.db.session.ServerSession$YieldableCommand.run(ServerSession.java:1188)
	at org.lealone.server.Scheduler.executeNextStatement(Scheduler.java:224)
	at org.lealone.server.Scheduler.run(Scheduler.java:97)
Caused by: java.lang.IllegalArgumentException: aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e7050f142e1d361efb0078
	at org.lealone.common.util.DateTimeUtils.parseDateValue(DateTimeUtils.java:267)
	at org.lealone.db.value.ValueTimestamp.parseTry(ValueTimestamp.java:108)
	at org.lealone.db.value.ValueTimestamp.parse(ValueTimestamp.java:89)
	... 9 more


	at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:104)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:79)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:79)
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:91)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)
	at com.sun.proxy.$Proxy71.insert(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:272)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:59)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
	at com.sun.proxy.$Proxy74.insert(Unknown Source)
	at com.example.lealoneboot.LealoneBootApplicationTests.contextLoads(LealoneBootApplicationTests.java:28)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: org.lealone.common.exceptions.JdbcSQLException: Cannot parse "TIMESTAMP" constant "aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e7050f142e1d361efb0078"; SQL statement:
INSERT INTO sys_user  ( user_id,
username,
nickname,
phone,
gender,
password,
memo,
created_by,
created_at )  VALUES  ( ?,
?,
?,
?,
?,
?,
?,
?,
? ) -- row #2 (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9) [22007-2]
	at org.lealone.common.exceptions.DbException.getJdbcSQLException(DbException.java:342)
	at org.lealone.common.exceptions.DbException.get(DbException.java:162)
	at org.lealone.db.value.ValueTimestamp.parse(ValueTimestamp.java:91)
	at org.lealone.db.value.Value.convertTo(Value.java:876)
	at org.lealone.db.table.Column.convert(Column.java:149)
	at org.lealone.sql.dml.MerSert$YieldableMerSert.createNewRow(MerSert.java:170)
	at org.lealone.sql.dml.Insert$YieldableInsert.executeLoopUpdate(Insert.java:92)
	at org.lealone.sql.executor.YieldableLoopUpdateBase.executeInternal(YieldableLoopUpdateBase.java:30)
	at org.lealone.sql.executor.YieldableBase.run(YieldableBase.java:97)
	at org.lealone.db.session.ServerSession$YieldableCommand.run(ServerSession.java:1188)
	at org.lealone.server.Scheduler.executeNextStatement(Scheduler.java:224)
	at org.lealone.server.Scheduler.run(Scheduler.java:97)
Caused by: java.lang.IllegalArgumentException: aced00057372000d6a6176612e74696d652e536572955d84ba1b2248b20c00007870770e05000007e7050f142e1d361efb0078
	at org.lealone.common.util.DateTimeUtils.parseDateValue(DateTimeUtils.java:267)
	at org.lealone.db.value.ValueTimestamp.parseTry(ValueTimestamp.java:108)
	at org.lealone.db.value.ValueTimestamp.parse(ValueTimestamp.java:89)
	... 9 more

	at org.lealone.net.TransferConnection.parseError(TransferConnection.java:72)
	at org.lealone.net.TcpClientConnection.handleResponse(TcpClientConnection.java:96)
	at org.lealone.net.TransferConnection.handle(TransferConnection.java:130)
	at org.lealone.net.nio.NioEventLoop.read(NioEventLoop.java:224)
	at org.lealone.net.nio.NioEventLoopClient.run(NioEventLoopClient.java:75)
	at org.lealone.net.nio.NioEventLoopClient.lambda$0(NioEventLoopClient.java:47)
	at java.lang.Thread.run(Thread.java:750)
@zhoujin7
Copy link
Author

周边生态也很重要.

@zhoujin7
Copy link
Author

lealone-timestamp-jdbctype-map

看了postgressql 这个TIMESTAMP也是映射到java.util.Date 但是用LocalDateTime作为字段类型没报错.

@codefollower
Copy link
Member

lealone 支持三种日期时间类型,是严格遵循 jdbc 规范的
TIME 对应 java.sql.Time
DATE 对应 java.sql.Date
TIMESTAMP 对应 java.sql.Timestamp

mybatis plus 我不熟,不清楚它为什么全映射成 java.util.Date,哪怕是 DATE 类型,也是 java.sql.Date 啊。

@codefollower
Copy link
Member

错误提示是你在客户端传给 TIMESTAMP 字段的值是一个无法解析的字符串,是不是在客户端设置字段参数值时错了。

@codefollower
Copy link
Member

如果表字段是 TIMESTAMP 类型,然后用 java.time.LocalDateTime.now().toString() 变成字符串写入 TIMESTAMP 类型的字段是可以解析的,这个我刚试了,java.time.LocalDateTime.now().toString() 会返回 “2023-05-15T22:15:52.086” 这种格式,
你给出的错误提示显然字符串很特殊,并不是一个有效的格式。

@codefollower
Copy link
Member

我知道原因,肯定是 mybatis plus 在得到 PreparedStatement 后用 setObject(1, java.time.LocalDateTime.now()) 这种方式执行了,lealone 没有把 LocalDateTime 自动转成 java.sql.Timestamp,而是变成一个字节数组了,所以就错了。

java.time.LocalDateTime 是比较新的日期时间类。

@codefollower
Copy link
Member

lealone 目前不支持 java.time.LocalDateTime 这类 JSR 310 日期时间API

@codefollower
Copy link
Member

mybatis plus 我不知道是否可以给具体的数据库方言配置不同的参数,毕竟不是所有数据库都要支持各种 jdk 新的类的,
框架为了兼容各种数据库就得自己做适配,比如数据库不支持 JSR 310,那框架就用 setString、setLong 替换 setObject 即可。

@zhoujin7
Copy link
Author

lealone 目前不支持 java.time.LocalDateTime 这类 JSR 310 日期时间API

那我先研究一下mybatis 看怎么解决

@codefollower
Copy link
Member

lealone 目前不支持 java.time.LocalDateTime 这类 JSR 310 日期时间API

那我先研究一下mybatis 看怎么解决

mybatis-3.5.11\src\main\java\org\apache\ibatis\type
里面有 LocalDateTypeHandler、LocalDateTimeTypeHandler、LocalTimeTypeHandler
为不同的数据库微调一下,使用不同的 TypeHandler,把里面的 setObject 换成 setString 或 setLong 即可,getObject 也要改一下。

@zhoujin7
Copy link
Author

lealone 目前不支持 java.time.LocalDateTime 这类 JSR 310 日期时间API

那我先研究一下mybatis 看怎么解决

mybatis-3.5.11\src\main\java\org\apache\ibatis\type 里面有 LocalDateTypeHandler、LocalDateTimeTypeHandler、LocalTimeTypeHandler 为不同的数据库微调一下,使用不同的 TypeHandler,把里面的 setObject 换成 setString 或 setLong 即可,getObject 也要改一下。

下午试了一下自定义LocalDateTimeTypeHandler可以跑通.

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.LocalDateTimeTypeHandler;
import org.apache.ibatis.type.MappedTypes;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.Optional;


@MappedTypes(LocalDateTime.class) //需要通过配置类或者配置文件注册该TypeHandler
public class CustomLocalDateTimeTypeHandler extends LocalDateTimeTypeHandler {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType) throws SQLException {
        if ("Lealone".equals(ps.getConnection().getMetaData().getDatabaseProductName())) {
            ps.setString(i, Optional.ofNullable(parameter).map(LocalDateTime::toString).orElse(null));
        } else {
            ps.setObject(i, parameter);
        }
    }
}

mybatis 以前应该是支持的, 后面代码被人改了:
https://github.com/mybatis/mybatis-3/pull/1478/files#diff-d2d4ee62d8c770943401ac9a8a5498b1b3b6afd8643588de93acdf230b7f5415
然后后面又有人想改回之前的版本:
mybatis/mybatis-3#1752

@zhoujin7 zhoujin7 reopened this May 16, 2023
@codefollower
Copy link
Member

它可能想省事直接让数据库的 jdbc 驱动在 setObject 里自己去转换,mysql、postgresql 新一点的 jdbc 驱动在 setObject 方法内部就对 java.time 包中的各种类做了转换,还是挺繁琐的。

@codefollower
Copy link
Member

我看了一下 h2 数据库的新版本,它也支持 java.time 的类了,技术难度不大,就是很繁琐,这是它的其中一个工具类 JSR310Utils

lealone 的后续小版本再看看要不要支持 java.time,目前大多数应用还是用 java.sql 中的日期时间 api 多一些。

@zhoujin7
Copy link
Author

zhoujin7 commented May 17, 2023

我看了一下 h2 数据库的新版本,它也支持 java.time 的类了,技术难度不大,就是很繁琐,这是它的其中一个工具类 JSR310Utils

lealone 的后续小版本再看看要不要支持 java.time,目前大多数应用还是用 java.sql 中的日期时间 api 多一些。

mybatis plus已添加对Lealone数据库的支持
baomidou/mybatis-plus#5335

这个问题根源在mybatis, 还是希望可以支持jsr310

  • Since mybatis version 3.5.0, this type handler(LocalDateTimeTypeHandler) requires a driver that supports JDBC 4.2 API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants