001
014
015 package com.liferay.portal.upgrade;
016
017 import com.liferay.portal.kernel.util.ProxyUtil;
018 import com.liferay.portal.util.PropsValues;
019
020 import java.lang.reflect.InvocationHandler;
021 import java.lang.reflect.Method;
022
023 import java.sql.Connection;
024 import java.sql.DatabaseMetaData;
025 import java.sql.PreparedStatement;
026 import java.sql.SQLException;
027
028
031 public class AutoBatchPreparedStatementUtil {
032
033 public static PreparedStatement autoBatch(
034 PreparedStatement preparedStatement)
035 throws SQLException {
036
037 Connection connection = preparedStatement.getConnection();
038
039 DatabaseMetaData databaseMetaData = connection.getMetaData();
040
041 if (databaseMetaData.supportsBatchUpdates()) {
042 return (PreparedStatement)ProxyUtil.newProxyInstance(
043 ClassLoader.getSystemClassLoader(), _interfaces,
044 new BatchInvocationHandler(preparedStatement));
045 }
046
047 return (PreparedStatement)ProxyUtil.newProxyInstance(
048 ClassLoader.getSystemClassLoader(), _interfaces,
049 new NoBatchInvocationHandler(preparedStatement));
050 }
051
052 private AutoBatchPreparedStatementUtil() {
053 }
054
055 private static final Method _addBatchMethod;
056 private static final Method _executeBatch;
057 private static final Class<?>[] _interfaces =
058 new Class<?>[] {PreparedStatement.class};
059
060 static {
061 try {
062 _addBatchMethod = PreparedStatement.class.getMethod("addBatch");
063 _executeBatch = PreparedStatement.class.getMethod("executeBatch");
064 }
065 catch (NoSuchMethodException nsme) {
066 throw new ExceptionInInitializerError(nsme);
067 }
068 }
069
070 private static class BatchInvocationHandler implements InvocationHandler {
071
072 @Override
073 public Object invoke(Object proxy, Method method, Object[] args)
074 throws Throwable {
075
076 if (method.equals(_executeBatch)) {
077 if (_count > 0) {
078 _count = 0;
079
080 return _preparedStatement.executeBatch();
081 }
082
083 return new int[0];
084 }
085
086 if (!method.equals(_addBatchMethod)) {
087 return method.invoke(_preparedStatement, args);
088 }
089
090 _preparedStatement.addBatch();
091
092 if (++_count >= PropsValues.HIBERNATE_JDBC_BATCH_SIZE) {
093 _preparedStatement.executeBatch();
094
095 _count = 0;
096 }
097
098 return null;
099 }
100
101 private BatchInvocationHandler(PreparedStatement preparedStatement) {
102 _preparedStatement = preparedStatement;
103 }
104
105 private int _count;
106 private final PreparedStatement _preparedStatement;
107
108 }
109
110 private static class NoBatchInvocationHandler implements InvocationHandler {
111
112 @Override
113 public Object invoke(Object proxy, Method method, Object[] args)
114 throws Throwable {
115
116 if (method.equals(_addBatchMethod)) {
117 _preparedStatement.executeUpdate();
118
119 return null;
120 }
121
122 if (method.equals(_executeBatch)) {
123 return new int[0];
124 }
125
126 return method.invoke(_preparedStatement, args);
127 }
128
129 private NoBatchInvocationHandler(PreparedStatement preparedStatement) {
130 _preparedStatement = preparedStatement;
131 }
132
133 private final PreparedStatement _preparedStatement;
134
135 }
136
137 }