lealone / Lealone

比 MySQL 和 MongoDB 快10倍的 OLTP 关系数据库和文档数据库
Other
2.44k stars 513 forks source link

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

Open zhoujin7 opened 1 year ago

zhoujin7 commented 1 year ago

测试项目 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 commented 1 year ago

周边生态也很重要.

zhoujin7 commented 1 year ago

lealone-timestamp-jdbctype-map

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

codefollower commented 1 year ago

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

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

codefollower commented 1 year ago

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

codefollower commented 1 year ago

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

codefollower commented 1 year ago

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

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

codefollower commented 1 year ago

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

codefollower commented 1 year ago

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

zhoujin7 commented 1 year ago

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

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

codefollower commented 1 year ago

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 commented 1 year ago

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 然后后面又有人想改回之前的版本: https://github.com/mybatis/mybatis-3/pull/1752

codefollower commented 1 year ago

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

codefollower commented 1 year ago

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

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

zhoujin7 commented 1 year ago

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

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

mybatis plus已添加对Lealone数据库的支持 https://github.com/baomidou/mybatis-plus/pull/5335

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