我希望存储三个对象之间的关系列表,其中两个相关对象将仅存在于列表中的一个关系中,第三个是我可以递增的计数。它不是很普遍,但你可以看到我在这里做什么
public class Transaction implements AutoCloseable {
private final Connection conn;
private final Map<String, Map.Entry<PreparedStatement, Integer>> sts = new HashMap<>();
Transaction(final Connection conn) throws SQLException {
conn.setAutoCommit(false);
this.conn = conn;
}
<T> void batch(final String st, final List<T> ts,
final BatchingInstructions<T> bi) throws SQLException {
final PreparedStatement stat;
int counter;
// if statement has already been created, retrieve statement and batch count
if (sts.containsKey(st)) {
final Map.Entry<PreparedStatement, Integer> m = sts.get(st);
stat = m.getKey();
counter = m.getValue();
} else {
// else create statement and batch count
stat = conn.prepareStatement(getInsert(st));
counter = 0;
sts.put(st, // Can't do a new Map.Entry, really
}
for (final T t : ts) {
bi.batch(stat, t);
stat.addBatch();
// increment how many times a batch has been added to the statement.
// execute batch if necessary.
if (++counter > 5000) {
stat.executeBatch();
}
}
}
@Override
public void close() throws Exception {
for (final Map.Entry<PreparedStatement, Integer> m : sts.values()) {
if (m.getValue() > 0) {
m.getKey().executeBatch();
}
m.getKey().close();
}
conn.commit();
}
Guava的表并不完全正常,而且Map<String, Map<Statement, Integer>>
也不理想,并且由于需要增加其中一个值而变得复杂(尽管为此我可能会使用此处找到的mutableInt解决方案) Most efficient way to increment a Map value in Java)。
我想知道是否有人知道这个问题的任何直接解决方案,可能在第三方图书馆?
使用接受的答案,我可以让新课做许多其他有用的事情。
class BatchPreparedStatement implements AutoCloseable {
private final PreparedStatement st;
private int counter = 0;
BatchPreparedStatement(final PreparedStatement st) {
this.st = st;
}
<T> void addBatch(final BatchingInstructions<T> bi, final T t)
throws SQLException {
bi.batch(st, t);
st.addBatch();
executeBatch(10000);
}
void executeBatch(final int count) throws SQLException {
if (counter++ > count) {
st.executeBatch();
counter = 0;
}
}
void finished() throws SQLException {
executeBatch(0);
}
@Override
public void close() throws Exception {
st.close();
}
}
答案 0 :(得分:1)
为什么不创建一个包含Statement,count和处理所有addBatching以及其他杂项活动的Class。
class BatchPreparedStatementHolder {
private int batchCount;
private PreparedStatement ps;
public BatchPreparedStatementHolder(PreparedStatement statement){
batchCount = 0;
ps = statment;
}
public void addBatch(){
ps.addBatch();
// increment how many times a batch has been added to the statement.
// execute batch if necessary.
if (++batchCount> 5000) {
ps.executeBatch();
batchCount = 0;
}
}
....
}
答案 1 :(得分:0)
课堂建议非常好,但如果你只需要一些简单的东西,那就有点重。我会使用类似 HashMap 的东西。 (其他语言称这些“词典”)。我没有时间阅读您的所有代码,但看起来您可能正在使用Google地图?
无论如何,您可以将密钥设置为自动递增的值(如在数据库中),并且值可以是,例如其他两个值的元组或数组。有关HashMaps的好建议,请参阅以下链接:
http://java67.blogspot.com/2013/02/10-examples-of-hashmap-in-java-programming-tutorial.html
或者只是创建一个数组,其中索引引用自动递增的函数,而内容是另一个数组?
不确定您需要什么,但这些可能有效!
答案 2 :(得分:0)
不是将Map.Entry保留在地图中,而是可以保留嵌套类..这样很容易处理......就像那样...
class Transaction implements AutoCloseable {
private final Connection conn;
class MapValue {
PreparedStatement p;
int index ;
public MapValue(){}
public MapValue(PreparedStatement p , int i)
{
index= i;
this.p=p;
}
}
private final Map<String, MapValue> sts = new HashMap<>();
Transaction(final Connection conn) throws SQLException {
conn.setAutoCommit(false);
this.conn = conn;
}
<T> void batch(final String st, final List<T> ts,
final BatchingInstructions<T> bi) throws SQLException {
final PreparedStatement stat;
int counter;
// if statement has already been created, retrieve statement and batch count
if (sts.containsKey(st)) {
MapValue m = sts.get(st);
stat = m.p;
counter = m.index;
} else {
// else create statement and batch count
stat = conn.prepareStatement(getInsert(st));
MapValue m = new MapValue(stat, 0);
sts.put(st, m);
}
for (final T t : ts) {
bi.batch(stat, t);
stat.addBatch();
// increment how many times a batch has been added to the statement.
// execute batch if necessary.
if (++counter > 5000) {
stat.executeBatch();
}
}
@Override
public void close() throws Exception {
for (final Map.Entry<PreparedStatement, Integer> m : sts.values()) {
if (m.getValue() > 0) {
m.getKey().executeBatch();
}
m.getKey().close();
}
conn.commit();
}
}