• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mybatis / mybatis-3 / #2968

pending completion
#2968

push

github

web-flow
Merge pull request #2792 from hazendaz/formatting

[ci] Formatting

84 of 84 new or added lines in 23 files covered. (100.0%)

9412 of 10781 relevant lines covered (87.3%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.54
/src/main/java/org/apache/ibatis/jdbc/SqlRunner.java
1
/*
2
 *    Copyright 2009-2023 the original author or authors.
3
 *
4
 *    Licensed under the Apache License, Version 2.0 (the "License");
5
 *    you may not use this file except in compliance with the License.
6
 *    You may obtain a copy of the License at
7
 *
8
 *       https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *    Unless required by applicable law or agreed to in writing, software
11
 *    distributed under the License is distributed on an "AS IS" BASIS,
12
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *    See the License for the specific language governing permissions and
14
 *    limitations under the License.
15
 */
16
package org.apache.ibatis.jdbc;
17

18
import java.sql.Connection;
19
import java.sql.PreparedStatement;
20
import java.sql.ResultSet;
21
import java.sql.ResultSetMetaData;
22
import java.sql.SQLException;
23
import java.sql.Statement;
24
import java.util.ArrayList;
25
import java.util.HashMap;
26
import java.util.Iterator;
27
import java.util.List;
28
import java.util.Locale;
29
import java.util.Map;
30

31
import org.apache.ibatis.io.Resources;
32
import org.apache.ibatis.type.TypeHandler;
33
import org.apache.ibatis.type.TypeHandlerRegistry;
34

35
/**
36
 * @author Clinton Begin
37
 */
38
public class SqlRunner {
39

40
  public static final int NO_GENERATED_KEY = Integer.MIN_VALUE + 1001;
41

42
  private final Connection connection;
43
  private final TypeHandlerRegistry typeHandlerRegistry;
44
  private boolean useGeneratedKeySupport;
45

46
  public SqlRunner(Connection connection) {
1✔
47
    this.connection = connection;
1✔
48
    this.typeHandlerRegistry = new TypeHandlerRegistry();
1✔
49
  }
1✔
50

51
  public void setUseGeneratedKeySupport(boolean useGeneratedKeySupport) {
52
    this.useGeneratedKeySupport = useGeneratedKeySupport;
1✔
53
  }
1✔
54

55
  /**
56
   * Executes a SELECT statement that returns one row.
57
   *
58
   * @param sql
59
   *          The SQL
60
   * @param args
61
   *          The arguments to be set on the statement.
62
   *
63
   * @return The row expected.
64
   *
65
   * @throws SQLException
66
   *           If less or more than one row is returned
67
   */
68
  public Map<String, Object> selectOne(String sql, Object... args) throws SQLException {
69
    List<Map<String, Object>> results = selectAll(sql, args);
1✔
70
    if (results.size() != 1) {
1✔
71
      throw new SQLException("Statement returned " + results.size() + " results where exactly one (1) was expected.");
×
72
    }
73
    return results.get(0);
1✔
74
  }
75

76
  /**
77
   * Executes a SELECT statement that returns multiple rows.
78
   *
79
   * @param sql
80
   *          The SQL
81
   * @param args
82
   *          The arguments to be set on the statement.
83
   *
84
   * @return The list of rows expected.
85
   *
86
   * @throws SQLException
87
   *           If statement preparation or execution fails
88
   */
89
  public List<Map<String, Object>> selectAll(String sql, Object... args) throws SQLException {
90
    try (PreparedStatement ps = connection.prepareStatement(sql)) {
1✔
91
      setParameters(ps, args);
1✔
92
      try (ResultSet rs = ps.executeQuery()) {
1✔
93
        return getResults(rs);
1✔
94
      }
95
    }
96
  }
97

98
  /**
99
   * Executes an INSERT statement.
100
   *
101
   * @param sql
102
   *          The SQL
103
   * @param args
104
   *          The arguments to be set on the statement.
105
   *
106
   * @return The number of rows impacted or BATCHED_RESULTS if the statements are being batched.
107
   *
108
   * @throws SQLException
109
   *           If statement preparation or execution fails
110
   */
111
  public int insert(String sql, Object... args) throws SQLException {
112
    PreparedStatement ps;
113
    if (useGeneratedKeySupport) {
1✔
114
      ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
1✔
115
    } else {
116
      ps = connection.prepareStatement(sql);
×
117
    }
118

119
    try {
120
      setParameters(ps, args);
1✔
121
      ps.executeUpdate();
1✔
122
      if (useGeneratedKeySupport) {
1✔
123
        try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
1✔
124
          List<Map<String, Object>> keys = getResults(generatedKeys);
1✔
125
          if (keys.size() == 1) {
1✔
126
            Map<String, Object> key = keys.get(0);
1✔
127
            Iterator<Object> i = key.values().iterator();
1✔
128
            if (i.hasNext()) {
1✔
129
              Object genkey = i.next();
1✔
130
              if (genkey != null) {
1✔
131
                try {
132
                  return Integer.parseInt(genkey.toString());
1✔
133
                } catch (NumberFormatException e) {
×
134
                  // ignore, no numeric key support
135
                }
136
              }
137
            }
138
          }
139
        }
1✔
140
      }
141
      return NO_GENERATED_KEY;
×
142
    } finally {
143
      try {
144
        ps.close();
1✔
145
      } catch (SQLException e) {
×
146
        // ignore
147
      }
1✔
148
    }
149
  }
150

151
  /**
152
   * Executes an UPDATE statement.
153
   *
154
   * @param sql
155
   *          The SQL
156
   * @param args
157
   *          The arguments to be set on the statement.
158
   *
159
   * @return The number of rows impacted or BATCHED_RESULTS if the statements are being batched.
160
   *
161
   * @throws SQLException
162
   *           If statement preparation or execution fails
163
   */
164
  public int update(String sql, Object... args) throws SQLException {
165
    try (PreparedStatement ps = connection.prepareStatement(sql)) {
1✔
166
      setParameters(ps, args);
1✔
167
      return ps.executeUpdate();
1✔
168
    }
169
  }
170

171
  /**
172
   * Executes a DELETE statement.
173
   *
174
   * @param sql
175
   *          The SQL
176
   * @param args
177
   *          The arguments to be set on the statement.
178
   *
179
   * @return The number of rows impacted or BATCHED_RESULTS if the statements are being batched.
180
   *
181
   * @throws SQLException
182
   *           If statement preparation or execution fails
183
   */
184
  public int delete(String sql, Object... args) throws SQLException {
185
    return update(sql, args);
1✔
186
  }
187

188
  /**
189
   * Executes any string as a JDBC Statement. Good for DDL
190
   *
191
   * @param sql
192
   *          The SQL
193
   *
194
   * @throws SQLException
195
   *           If statement preparation or execution fails
196
   */
197
  public void run(String sql) throws SQLException {
198
    try (Statement stmt = connection.createStatement()) {
1✔
199
      stmt.execute(sql);
1✔
200
    }
201
  }
1✔
202

203
  /**
204
   * @deprecated Since 3.5.4, this method is deprecated. Please close the {@link Connection} outside of this class.
205
   */
206
  @Deprecated
207
  public void closeConnection() {
208
    try {
209
      connection.close();
×
210
    } catch (SQLException e) {
×
211
      // ignore
212
    }
×
213
  }
×
214

215
  private void setParameters(PreparedStatement ps, Object... args) throws SQLException {
216
    for (int i = 0, n = args.length; i < n; i++) {
1✔
217
      if (args[i] == null) {
1✔
218
        throw new SQLException(
×
219
            "SqlRunner requires an instance of Null to represent typed null values for JDBC compatibility");
220
      } else if (args[i] instanceof Null) {
1✔
221
        ((Null) args[i]).getTypeHandler().setParameter(ps, i + 1, null, ((Null) args[i]).getJdbcType());
1✔
222
      } else {
223
        TypeHandler typeHandler = typeHandlerRegistry.getTypeHandler(args[i].getClass());
1✔
224
        if (typeHandler == null) {
1✔
225
          throw new SQLException("SqlRunner could not find a TypeHandler instance for " + args[i].getClass());
×
226
        } else {
227
          typeHandler.setParameter(ps, i + 1, args[i], null);
1✔
228
        }
229
      }
230
    }
231
  }
1✔
232

233
  private List<Map<String, Object>> getResults(ResultSet rs) throws SQLException {
234
    List<Map<String, Object>> list = new ArrayList<>();
1✔
235
    List<String> columns = new ArrayList<>();
1✔
236
    List<TypeHandler<?>> typeHandlers = new ArrayList<>();
1✔
237
    ResultSetMetaData rsmd = rs.getMetaData();
1✔
238
    for (int i = 0, n = rsmd.getColumnCount(); i < n; i++) {
1✔
239
      columns.add(rsmd.getColumnLabel(i + 1));
1✔
240
      try {
241
        Class<?> type = Resources.classForName(rsmd.getColumnClassName(i + 1));
1✔
242
        TypeHandler<?> typeHandler = typeHandlerRegistry.getTypeHandler(type);
1✔
243
        if (typeHandler == null) {
1✔
244
          typeHandler = typeHandlerRegistry.getTypeHandler(Object.class);
1✔
245
        }
246
        typeHandlers.add(typeHandler);
1✔
247
      } catch (Exception e) {
×
248
        typeHandlers.add(typeHandlerRegistry.getTypeHandler(Object.class));
×
249
      }
1✔
250
    }
251
    while (rs.next()) {
1✔
252
      Map<String, Object> row = new HashMap<>();
1✔
253
      for (int i = 0, n = columns.size(); i < n; i++) {
1✔
254
        String name = columns.get(i);
1✔
255
        TypeHandler<?> handler = typeHandlers.get(i);
1✔
256
        row.put(name.toUpperCase(Locale.ENGLISH), handler.getResult(rs, name));
1✔
257
      }
258
      list.add(row);
1✔
259
    }
1✔
260
    return list;
1✔
261
  }
262

263
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc