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
39 public final class ResultSetLogger extends BaseJdbcLogger implements InvocationHandler {
40
41 private static final Set<Integer> BLOB_TYPES = new HashSet<>();
42 private boolean first = true;
43 private int rows;
44 private final ResultSet rs;
45 private final Set<Integer> blobColumns = new HashSet<>();
46
47 static {
48 BLOB_TYPES.add(Types.BINARY);
49 BLOB_TYPES.add(Types.BLOB);
50 BLOB_TYPES.add(Types.CLOB);
51 BLOB_TYPES.add(Types.LONGNVARCHAR);
52 BLOB_TYPES.add(Types.LONGVARBINARY);
53 BLOB_TYPES.add(Types.LONGVARCHAR);
54 BLOB_TYPES.add(Types.NCLOB);
55 BLOB_TYPES.add(Types.VARBINARY);
56 }
57
58 private ResultSetLogger(ResultSet rs, Log statementLog, int queryStack) {
59 super(statementLog, queryStack);
60 this.rs = rs;
61 }
62
63 @Override
64 public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
65 try {
66 if (Object.class.equals(method.getDeclaringClass())) {
67 return method.invoke(this, params);
68 }
69 Object o = method.invoke(rs, params);
70 if ("next".equals(method.getName())) {
71 if ((Boolean) o) {
72 rows++;
73 if (isTraceEnabled()) {
74 ResultSetMetaData rsmd = rs.getMetaData();
75 final int columnCount = rsmd.getColumnCount();
76 if (first) {
77 first = false;
78 printColumnHeaders(rsmd, columnCount);
79 }
80 printColumnValues(columnCount);
81 }
82 } else {
83 debug(" Total: " + rows, false);
84 }
85 }
86 clearColumnInfo();
87 return o;
88 } catch (Throwable t) {
89 throw ExceptionUtil.unwrapThrowable(t);
90 }
91 }
92
93 private void printColumnHeaders(ResultSetMetaData rsmd, int columnCount) throws SQLException {
94 StringJoiner row = new StringJoiner(", ", " Columns: ", "");
95 for (int i = 1; i <= columnCount; i++) {
96 if (BLOB_TYPES.contains(rsmd.getColumnType(i))) {
97 blobColumns.add(i);
98 }
99 row.add(rsmd.getColumnLabel(i));
100 }
101 trace(row.toString(), false);
102 }
103
104 private void printColumnValues(int columnCount) {
105 StringJoiner row = new StringJoiner(", ", " Row: ", "");
106 for (int i = 1; i <= columnCount; i++) {
107 try {
108 if (blobColumns.contains(i)) {
109 row.add("<<BLOB>>");
110 } else {
111 row.add(rs.getString(i));
112 }
113 } catch (SQLException e) {
114
115 row.add("<<Cannot Display>>");
116 }
117 }
118 trace(row.toString(), false);
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 }