我正在使用MySQL将大约10000个条目上传到数据库中。这是我的代码:
public void addChests(HashMap<Location, ChestGeneratorType> map) {
java.sql.PreparedStatement statement;
try {
statement = plugin.sql.openConnection().prepareStatement("INSERT INTO chests (Location, Generator, ToAdd) VALUES (?,?,?)");
for (Location l : map.keySet()) {
map.get(l).chests.add(new Chests(l, map.get(l), 0));
statement.setString(1, Utils.locationToString(l));
statement.setString(2, map.get(l).configName);
statement.setInt(3, 0);
statement.addBatch();
}
statement.executeBatch();
} catch (SQLException sqlE) {
sqlE.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
这段代码应该通过我的地图并为地图中的每个值插入一个新行。这个地图有大约10000个条目,我通过将地图转储成一个文本文件来测试,每行一个,我有9800多个条目。所以我知道我的HashMap已满。但正在发生的事情是它只投入了1513个条目,而不是9800+。并且在所有这些条目中都是奇怪的,“发电机”值是“发电机”。如果ChestGeneratorType.configName是irongenerator,它只会插入它吗?为什么呢?
MySQL数据库:https://gyazo.com/5a0686a48a6238d2d958f7a7411696b2
更好的解释(我在bukkit插件中工作):https://www.spigotmc.org/threads/mysql-mass-insert-acting-weird.99373/
由于
答案 0 :(得分:1)
我发现了这个问题..
我有另一个任务,它将TRUNCATE表再次插入值。在插入所有的铁生成器之后,它会立即对表进行TRUNCATE,这就解释了为什么列生成器都是相同的。
谢谢你们。
答案 1 :(得分:0)
您可能在FOREIGN KEY
列上有约束(CHECK
或Generator
),或者VARCHAR
类型的其他值太长,或者值为null Generator
为NOT NULL
。
这导致某些INSERT
语句失败,但允许executeBatch()
继续(自Java 1.3以来的功能),并将执行所有语句,然后抛出BatchUpdateException
(SQLException
的子类)。
然后可以调用BatchUpdateException.getUpdateCounts()
方法来获取int[]
,并且迭代该数组将让您知道哪些语句失败(值EXECUTE_FAILED
)。
但是,你抓住了那个例外,打电话给printStackTrace()
(你应该看到这个),然后( OH HORROR!)正常继续,让addChests()
正常返回,并提交所有成功的插入。的 OOPS!强>
相依
您在循环中呼叫map.get(l)
3 次。非常低效。分配给变量,或者更好的是迭代映射条目,而不是键:
for (Map.Entry<Location, ChestGeneratorType>> entry : map.entrySet()) {
Location loc = entry.getKey();
ChestGeneratorType type = entry.getValue();
type.chests.add(new Chests(loc, type, 0));