当我在日期栏中设置空值时,我得到" 1900-01-01 00:00:00.000"我的表中的值,我期望该列中的NULL。 因为我在jdbc中正确处理,如果我这样放
preparedStatement.setBindParam(Types.TIMESTAMP, 12, startdate);
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<CustomLevels>
<CustomLevel name="TESTLOG" intLevel="552" />
</CustomLevels>
<Appenders>
<JDBC name="myAppender" tableName="MYTABLE">
<DataSource jndiName="java:MyDataSource" />
<Column name="ID" pattern="%X{ID}" isUnicode="false"/>
<Column name="startdate" pattern="%X{startdate}" isUnicode="false"/>
<Column name="enddate" pattern="%X{enddate}" isUnicode="false"/>
</JDBC>
</Appenders>
<Loggers>
<Root level="trace" includeLocation="false">
<AppenderRef ref="myAppender" level="TESTLOG" />
</Root>
</Loggers>
</Configuration>
列startdate和enddate的数据类型为 datetime
ThreadContext.put("startdate", startdate != null ? startdate.toString() : null);
ThreadContext.put("enddate", a_reportEndDate != null ? enddate.toString() : null);
final Logger LOGGER = LogManager.getLogger();
LOGGER.log(Level.forName("TESTLOG", 552), "");
对于具有空值的String也是如此。
答案 0 :(得分:2)
插入空
我认为使用null
这样的模式可以将JDBCAppender
放入任何类型的任何列中。
简短版本是在模式和预准备语句之间使用StringBuilder
,因此INSERT
总是获得非空字符串,即使(在您的示例中)null
是ThreadContext
中的值。因此可以插入空字符串或字符串"null"
,但似乎无法插入值 null
。
1900年1月1日
当我针对MySQL数据库运行您的示例时,插入失败,因为MySQL不知道如何从空字符串构造DATETIME
。
我猜你正在使用SQL Server,它会很乐意将空字符串转换为1900-01-01 00:00:00.000
,因为当然就是你的意思。
无论您使用何种数据库,JDBCAppender
都会使用非空字符串填充INSERT
语句。从那里发生的事情因DB而异。
<强>为什么吗
首先,框架将您的值(null
)更改为另一个值(空字符串)似乎很奇怪。但是,在其核心,记录是关于文本字符串。
是的,有一个将这些字符串写入数据库的appender。是的,您的数据库可以将这些字符串转换为DATETIME
或INTEGER
等类型。但对于任何给定的appender,它都只是操纵和输出字符串。
可能的解决方法
如果您真的想使用null
将JDBCAppender
导入数据库,您可以write a trigger。
最终观察
不确定这是否有帮助,但我也可以提供我的所有发现:
在log4j配置中使用ColumnMapping
代替Column
可以指定类名。此类名称的存在(或不存在)和值确实会更改插入到数据库中的值。例如,使用SQL Server Express 2014:
<ColumnMapping name="startdate" pattern="%X{startdate}" type="java.sql.Timestamp"/>
当startdate
为空时,将导致记录当前日期和时间,而不是1900-01-01。使用java.sql.Date
代替将记录当前日期。