1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.logging.jdbc;
17
18 import java.lang.reflect.InvocationHandler;
19 import java.lang.reflect.Method;
20 import java.lang.reflect.Proxy;
21 import java.sql.ResultSet;
22 import java.sql.ResultSetMetaData;
23 import java.sql.SQLException;
24 import java.sql.Types;
25 import java.util.HashSet;
26 import java.util.Set;
27 import java.util.StringJoiner;
28
29 import org.apache.ibatis.logging.Log;
30 import org.apache.ibatis.reflection.ExceptionUtil;
31
32
33
34
35
36
37
38 public final class ResultSetLogger extends BaseJdbcLogger implements InvocationHandler {
39
40 private static final Set<Integer> BLOB_TYPES = new HashSet<>();
41 private boolean first = true;
42 private int rows;
43 private final ResultSet rs;
44 private final Set<Integer> blobColumns = new HashSet<>();
45
46 static {
47 BLOB_TYPES.add(Types.BINARY);
48 BLOB_TYPES.add(Types.BLOB);
49 BLOB_TYPES.add(Types.CLOB);
50 BLOB_TYPES.add(Types.LONGNVARCHAR);
51 BLOB_TYPES.add(Types.LONGVARBINARY);
52 BLOB_TYPES.add(Types.LONGVARCHAR);
53 BLOB_TYPES.add(Types.NCLOB);
54 BLOB_TYPES.add(Types.VARBINARY);
55 }
56
57 private ResultSetLogger(ResultSet rs, Log statementLog, int queryStack) {
58 super(statementLog, queryStack);
59 this.rs = rs;
60 }
61
62 @Override
63 public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
64 try {
65 if (Object.class.equals(method.getDeclaringClass())) {
66 return method.invoke(this, params);
67 }
68 Object o = method.invoke(rs, params);
69 if ("next".equals(method.getName())) {
70 if ((Boolean) o) {
71 rows++;
72 if (isTraceEnabled()) {
73 ResultSetMetaData rsmd = rs.getMetaData();
74 final int columnCount = rsmd.getColumnCount();
75 if (first) {
76 first = false;
77 printColumnHeaders(rsmd, columnCount);
78 }
79 printColumnValues(columnCount);
80 }
81 } else {
82 debug(" Total: " + rows, false);
83 }
84 }
85 clearColumnInfo();
86 return o;
87 } catch (Throwable t) {
88 throw ExceptionUtil.unwrapThrowable(t);
89 }
90 }
91
92 private void printColumnHeaders(ResultSetMetaData rsmd, int columnCount) throws SQLException {
93 StringJoiner row = new StringJoiner(", ", " Columns: ", "");
94 for (int i = 1; i <= columnCount; i++) {
95 if (BLOB_TYPES.contains(rsmd.getColumnType(i))) {
96 blobColumns.add(i);
97 }
98 row.add(rsmd.getColumnLabel(i));
99 }
100 trace(row.toString(), false);
101 }
102
103 private void printColumnValues(int columnCount) {
104 StringJoiner row = new StringJoiner(", ", " Row: ", "");
105 for (int i = 1; i <= columnCount; i++) {
106 try {
107 if (blobColumns.contains(i)) {
108 row.add("<<BLOB>>");
109 } else {
110 row.add(rs.getString(i));
111 }
112 } catch (SQLException e) {
113
114 row.add("<<Cannot Display>>");
115 }
116 }
117 trace(row.toString(), false);
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131
132 public static ResultSet newInstance(ResultSet rs, Log statementLog, int queryStack) {
133 InvocationHandler handler = new ResultSetLogger(rs, statementLog, queryStack);
134 ClassLoader cl = ResultSet.class.getClassLoader();
135 return (ResultSet) Proxy.newProxyInstance(cl, new Class[] { ResultSet.class }, handler);
136 }
137
138
139
140
141
142
143 public ResultSet getRs() {
144 return rs;
145 }
146
147 }