[英]Dynamic population of SQL in Java from array with nulls
举一个简单的问题例子:
//Create database table allowing nulls.
CREATE TABLE test(one int not null, two int null, three int not null);
现在,在Java中,我有一个与数据库内容匹配的对象数组。 我需要使用数组值为此数据库表创建insert / update / delete语句。
Object[] arr = { 4, null, 1 };
String sql = GenereateInsert(arr);
这很难,因为我需要事先从插入中省略空字段。 例如,如果以上两个不为null:
INSERT INTO test(4, 2, 1);
一切都很容易。 但如果它为null,我需要声明为:
INSERT INTO test(one, three) values(4, 1);
我正在处理的表是50列以上,所以我不想手动执行此操作,它将无法管理。 那么,人们如何解决这个问题呢? 这一定是一种常见的情况。
PS:我不想使用完整的ORM库,这看起来有点过分。
一个高级算法:
allColumnNames
称为该类的字段。 List<String>
,一个用于表示列名,一个用于表示值 - 让我们调用这些columnNamesList
和columnValuesList
。 allColumnNames[i]
添加到columnNamesList
,将values[i]
到columnValuesList
。 INSERT INTO tablename
连接在一起来构建插入语句, INSERT INTO tablename
是columnNames
, VALUES
中每个值的逗号分隔列表,以及columnValuesList
中每个值的逗号分隔列表。 我会建议这样的事情:
运行SELECT * FROM <TABLE_NAME> LIMIT 1
类的查询。 使用ResultSetMetaData
检索columnNames及其columnType。 将其存储在HashMap中,并将其存储在ArrayList中
现在使用ArrayList中的键作为columnNames创建PreparedStatement
。 我想这并不难
现在给出数组中的数据,事实上你知道它们来自HashMap的SQL类型,你可以轻松地使用这些信息来映射你从数组中得到的值?
您生成的PreparedStatement。
现在的问题是如何处理null
。 好吧,因为你知道列的类型,如果你得到的值是null
那么你可以使用PreparedStatement.setNull(...)
将它们设置为null。
另外,只是想指出, 根据这个文档 ,有一个关于JDBC的setXXX(...)的重要指南:
6.1.5将JDBC NULL作为IN参数发送
setNull方法允许程序员将JDBC NULL(通用SQL NULL)值作为IN参数发送到数据库。 但请注意,仍必须指定参数的JDBC类型。
当Java null值传递给setXXX方法时(如果它将Java对象作为参数),JDBC NULL也将被发送到数据库。 但是,只有指定了JDBC类型,方法setObject才能获取空值。
这意味着你可以发送null作为setXX(...)
方法的参数值,你真的不必显式调用setNull(..)
方法。
我希望这对你有用!
不确定其他数据库系统,但在postgres中,您可以插入一个空值,如下所示:
CREATE TABLE test(
id SERIAL PRIMARY KEY,
val1 INTEGER DEFAULT NULL,
val2 INTEGER DEFAULT NULL,
val3 INTEGER DEFAULT NULL
);
INSERT INTO test(val1, val2, val3) VALUES(DEFAULT, DEFAULT, DEFAULT);
您也可以以相同的方式执行set语句:
UPDATE test SET val1 = DEFAULT, val2 = 123, val3 = DEFAULT WHERE id = 3;
从而,
Stringbuilder sqlStmt = new StringBuilder();
sqlStmt.append("INSERT INTO test(val1, val2, val3) VALUES(");
sqlStmt.append(((val1 == null) ? "DEFAULT" : val1.toString()));
sqlStmt.append(" , ");
sqlStmt.append(((val2 == null) ? "DEFAULT" : val2.toString()));
sqlStmt.append(" , ");
sqlStmt.append(((val3 == null) ? "DEFAULT" : val3.toString()));
sqlStmt.append(";");
statement.execute(sqlStmt.toString());
如果你有很多这些,那么用for-each循环做这件事可能更有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.