简体   繁体   English

无法使用Java快速将使用setNull的空值插入MySql数据库?

[英]Unable to insert null values using setNull into the MySql database using Java on the fly?

I want to the set null values on runtime depending on the type I get 我想根据我得到的类型在运行时设置null值

Here is my code 这是我的代码

@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);

I'm going to slightly challenge your question in this answer. 我将在此答案中稍微挑战您的问题。 I do not believe that you need to do what you are doing, but as it's somewhat unclear, I'll do what I can to help you out. 我不认为您需要做您正在做的事情,但是由于目前尚不清楚,我会尽力帮助您。

First, based on the variable name pstmt I'm going to guess that this is a PreparedStatement that looks something like this: 首先,基于变量名pstmt我猜这是一个PreparedStatement ,看起来像这样:

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

If this is the case, then you don't need to do any reflection at all, because Parameter 1 will always be an INTEGER , Parameter 2 will always be a DATE and so on. 如果是这种情况,那么您根本不需要进行任何反射,因为参数1 始终INTEGER ,参数2 始终DATE ,依此类推。 So you know what type to use in setNull because you know the position already (because you have to, because it's the first argument to setNull ), and you know the statement. 因此,您知道在setNull使用哪种类型,因为您已经知道位置(因为必须知道,因为它是setNull的第一个参数),并且您知道该语句。 It's generally going to be much easier to follow your code if you just do the obvious thing and set the values. 如果您只是做显而易见的事情并设置值,那么遵循代码通常会容易得多。

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

Now, this might get a tad trickier if you're trying to set the columns in a loop for some reason. 现在,如果由于某种原因试图将列设置为循环,这可能会有点棘手。 I suggest to you that this is a bad idea because it'll be less obvious to future developers what you're up to. 我向您建议这是个坏主意,因为这对将来的开发人员来说作用不大。

However, the JDBC API has setObject for just such an occasion. 但是,在这种情况下,JDBC API具有setObject setObject will allow null values, so you don't have to handle the null and not-null cases separately. setObject将允许null值,因此您不必分别处理nullnot-null情况。 There's even a version of setObject that will allow you to do this without specifying the type. 甚至有setObject的版本,您无需指定类型即可执行此操作。 In that case, it's just: 在这种情况下,它只是:

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

No casting, no remembering the type, no reflection needed. 无需强制转换,无需记住类型,无需反射。 The documentation says it's not supported by every database, but I'd give this a shot before you do reflection. 文档说并不是每个数据库都支持它,但是在进行反思之前,我会先试一下。

Now to Answer Your Question 现在回答您的问题

If, for some reason, you need to do this with reflection (because you're one of the unlucky few whose database doesn't support un-typed nulls), you were actually pretty close. 如果出于某种原因,您需要通过反射进行此操作(因为您是不幸的少数数据库之一,其数据库不支持非类型的null),那么您实际上就很接近了。

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
    }
}

So what's different here from what you were trying? 那么,这里与您尝试的有什么不同? First, the field name doesn't have a . 首先,字段名称没有. in front of it. 在它前面。 That's not part of the field name. 这不是字段名称的一部分。 Secondly, the typeName parameter here must exactly match the java.sql.Types field name. 其次,此处的typeName参数必须与java.sql.Types字段名称完全匹配。 This is a case-sensitive String . 这是区分大小写的String So, for example it's "INTEGER" not "int" . 因此,例如,它是"INTEGER"而不是"int" In your comment, you indicated that your st.getType() method had an ArrayList . 在您的评论中,您指出您的st.getType()方法具有ArrayList I've assumed that this method returns a single string, based on its knowledge of the query. 我已经假设此方法基于对查询的了解返回一个字符串。 Just make sure that your type names are the same as the names used by java.sql.Types and that the object in question can actually be used as (cast / converted to) that type. 只需确保您的类型名称与java.sql.Types使用的名称相同,并且所讨论的对象实际上可以用作 (转换/转换为)该类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM