1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package net.smartlab.web.page;
25
26 import java.sql.Connection;
27 import java.sql.ResultSet;
28 import java.sql.ResultSetMetaData;
29 import java.sql.SQLException;
30 import java.sql.Statement;
31
32 import javax.sql.DataSource;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36
37
38
39
40
41
42 public class SQLPaginator extends Paginator {
43
44
45
46
47 protected final Log logger = LogFactory.getLog(SQLPaginator.class);
48
49
50
51
52 private final static int DEFAULT_ISOLATION_LEVEL = -1;
53
54
55
56
57 private DataSource pool;
58
59
60
61
62 private String query;
63
64
65
66
67 private int isolation;
68
69
70
71
72
73
74
75
76
77
78
79 public SQLPaginator(DataSource pool, String query) throws SQLException {
80 this(pool, query, 0);
81 }
82
83
84
85
86
87
88
89
90
91
92
93 public SQLPaginator(DataSource pool, String query, int size) throws SQLException {
94 this(pool, query, size, Paginator.UNLIMITED_PAGES);
95 }
96
97
98
99
100
101
102
103
104
105
106
107 public SQLPaginator(DataSource pool, String query, int size, int pages) throws SQLException {
108 this(pool, query, size, pages, DEFAULT_ISOLATION_LEVEL);
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122
123 public SQLPaginator(DataSource pool, String query, int size, int pages, int isolation) throws SQLException {
124 super(size, pages);
125 this.pool = pool;
126 this.query = query;
127 this.isolation = isolation;
128 Connection connection = null;
129 try {
130 connection = pool.getConnection();
131 if (isolation != DEFAULT_ISOLATION_LEVEL) {
132 connection.setTransactionIsolation(isolation);
133 }
134 Statement statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
135 statement.setFetchDirection(ResultSet.TYPE_FORWARD_ONLY);
136 ResultSet rows = connection.createStatement().executeQuery(query);
137 rows.last();
138 super.setCount(rows.getRow());
139 } finally {
140 try {
141 connection.close();
142 } catch (SQLException sqle) {
143 logger.warn("SQLPaginator(pool = " + pool + ", query = " + query + ", size = " + size + ", pages = " + pages + ", isolation = "
144 + isolation + ") - failed connection close", sqle);
145 }
146 }
147 }
148
149
150
151
152 protected void setArray() {
153 if (logger.isTraceEnabled()) {
154 logger.trace("setArray() - start");
155 }
156 Connection connection = null;
157 try {
158 connection = pool.getConnection();
159 if (isolation != DEFAULT_ISOLATION_LEVEL) {
160 connection.setTransactionIsolation(isolation);
161 }
162 Statement statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
163 ResultSet rows = statement.executeQuery(query);
164 rows.absolute(((this.getPage() - 1) * array.length) + 1);
165 for (int i = 0; i < array.length; i++) {
166 array[i] = this.getObject(rows);
167 if (!rows.next() && !(i == array.length - 1)) {
168 array[i + 1] = null;
169 break;
170 }
171 }
172 } catch (SQLException sqle) {
173 throw new PaginationException(sqle);
174 } finally {
175 try {
176 connection.close();
177 } catch (SQLException sqle) {
178 logger.warn("setArray() - failed connection close", sqle);
179 }
180 }
181 }
182
183
184
185
186
187
188
189 protected Object[] getObject(ResultSet rows) {
190 if (logger.isTraceEnabled()) {
191 logger.trace("getObject(rows = " + rows + ") - start");
192 }
193 try {
194 ResultSetMetaData info = rows.getMetaData();
195 Object[] values = new Object[info.getColumnCount()];
196 for (int i = 0; i < values.length; i++) {
197 values[i] = rows.getObject(i + 1);
198 }
199 return values;
200 } catch (SQLException sqle) {
201 logger.error("getObject(rows = " + rows + ") - error", sqle);
202 return null;
203 }
204 }
205 }