无法使用Java动态地使用setNull将空值插入到MySql数据库中?

时间:2017-04-13 14:05:28

标签: java mysql jdbc

我想在运行时设置null值,具体取决于我得到的类型

这是我的代码

@SuppressWarnings("rawtypes")
// input can be Intger,Date, BigInt etc which Mysql supports
String input = "."+st.getType();
// param :- java.sql.Types.Integer or java.sql.Types.BigInt
Class clazz = Class.forName("java.sql.Types");
Field field = clazz.getField(input);
int val = field.getInt(null);
pstmt.setNull(1,val);

1 个答案:

答案 0 :(得分:0)

我将在这个答案中略微挑战你的问题。我不相信你需要做你正在做的事情,但由于有点不清楚,我会竭尽所能帮助你。

首先,根据变量名pstmt,我猜这是一个PreparedStatement看起来像这样:

INSERT INTO my_table (my_int, my_date, my_varchar, my_bool) VALUES (?, ?, ?, ?);

如果是这种情况,那么您根本不需要进行任何反射,因为参数1 总是INTEGER,参数2将始终< / em>是DATE等等。所以你知道在setNull中使用什么类型,因为你已经知道了这个位置(因为你必须这样,因为它是setNull的第一个参数),你知道这个陈述。如果您只是执行明显的操作并设置值,通常会更容易遵循您的代码。

if (myInt != null) {
    pstmt.setInt(1, myInt);
} else {
    pstmt.setNull(1, Types.INTEGER);
}
pstmt.setDate(2, myDate);  // already handles null
// and so on

现在,如果您因某种原因尝试在循环中设置列,这可能会有点棘手。我建议你这是一个坏主意,因为对于未来的开发人员来说,你所做的事情就不那么明显了。

但是,JDBC API仅适用于setObjectsetObject将允许null个值,因此您无需单独处理nullnot-null个案。甚至还有setObject的版本允许您在没有指定类型的情况下执行此操作。在这种情况下,它只是:

for (int i = 0; i < myObjects.size(); ++i) {
    Object obj = myObjects.get(i);
    pstmt.setObject(i, obj);
}

没有铸造,不记住类型,不需要反射。 documentation表示并不是每个数据库都支持它,但是在你做反思之前我会给它一个镜头。

现在回答你的问题

如果由于某种原因,需要使用反射执行此操作(因为您是不幸的少数数据库之一,其数据库不支持未键入的空值),您实际上非常接近

public void apply(PreparedStatement pstmt, int param, String typeName, Object value) {
    try {
        Class<?> types = Types.class;
        Field field = types.getField(typeName);
        int typeValue = field.getInt(null);

        pstmt.setObject(param, obj, typeValue);
    } catch (Exception e) {
        // handle exceptions
    }
}

那么你和你的尝试有何不同?首先,字段名称前面没有.。这不是字段名称的一部分。其次,此处的typeName参数必须与java.sql.Types字段名称完全匹配。这是一个区分大小写的String。因此,例如,"INTEGER"不是"int"。在您的评论中,您表示您的st.getType()方法有ArrayList。我假设这个方法根据它对查询的了解返回一个字符串。只需确保您的类型名称与java.sql.Types使用的名称相同,并且相关对象实际上可以用作(转换/转换为)该类型。