<返回更多

MyBatis源码解读 | 使用SqlRunner操作数据库

2022-07-05    嗨皮汪小成
加入收藏

简介

SqlRunner,一个非常实用的、用于操作数据库的工具类。该类对JDBC进行了很好的封装,结合SQL工具类,能够很方便地通过JAVA代码执行SQL语句并检索SQL执行结果。

SqlRunner提供了如下同个用于操作数据库的方法:

示例

SqlRunner使用示例:

try {
    // 数据库连接
    Connection connection = DriverManager.getConnection("jdbc:MySQL://127.0.0.1/MyBatis?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC", "root", "abc123");
    // 创建SqlRunner实例
    SqlRunner sqlRunner = new SqlRunner(connection);
    // 要执行的SQL语句
    String sql = "select * from t_transfer_log";
    // 执行SQL语句,获取返回结果
    List<Map<String, Object>> resultList = sqlRunner.selectAll(sql);
    // 遍历并输出返回结果内容
    for (Map<String, Object> itemMap : resultList) {
        System.out.println(new Gson().toJson(itemMap));
    }
} catch (Exception e) {
    e.printStackTrace();
}

源码

selectAll()方法源码:

public List<Map<String, Object>> selectAll(String sql, Object... args) throws SQLException {
  try (PreparedStatement ps = connection.prepareStatement(sql)) {
    // 为SQL中的参数赋值
    setParameters(ps, args);
    // 执行查询操作
    try (ResultSet rs = ps.executeQuery()) {
      // 将查询结果转换为List
      return getResults(rs);
    }
  }
}

setParameters()方法源码:

private void setParameters(PreparedStatement ps, Object... args) throws SQLException {
  for (int i = 0, n = args.length; i < n; i++) {
    if (args[i] == null) {
      throw new SQLException("SqlRunner requires an instance of Null to represent typed null values for JDBC compatibility");
    } else if (args[i] instanceof Null) {
      ((Null) args[i]).getTypeHandler().setParameter(ps, i + 1, null, ((Null) args[i]).getJdbcType());
    } else {
      // 根据参数类型获取对应的类型处理器
      TypeHandler typeHandler = typeHandlerRegistry.getTypeHandler(args[i].getClass());
      if (typeHandler == null) {
        throw new SQLException("SqlRunner could not find a TypeHandler instance for " + args[i].getClass());
      } else {
        // 调用类型处理器的setParameter()方法设置参数值
        typeHandler.setParameter(ps, i + 1, args[i], null);
      }
    }
  }
}

setParameters()方法处理逻辑:根据参数类型获取对应的类型处理器,如果没有对应的类型处理器会抛异常,获取到类型处理器后会调用类型处理器的setParameter()方法设置参数值。

getResults()方法源码:

private List<Map<String, Object>> getResults(ResultSet rs) throws SQLException {
  // 返回结果
  List<Map<String, Object>> list = new ArrayList<>();
  List<String> columns = new ArrayList<>();
  List<TypeHandler<?>> typeHandlers = new ArrayList<>();
  // 获取ResultSetMetaData对象
  ResultSetMetaData rsmd = rs.getMetaData();
  // 遍历获取列名、类型处理器
  for (int i = 0, n = rsmd.getColumnCount(); i < n; i++) {
    columns.add(rsmd.getColumnLabel(i + 1));
    try {
      Class<?> type = Resources.classForName(rsmd.getColumnClassName(i + 1));
      TypeHandler<?> typeHandler = typeHandlerRegistry.getTypeHandler(type);
      if (typeHandler == null) {
        typeHandler = typeHandlerRegistry.getTypeHandler(Object.class);
      }
      typeHandlers.add(typeHandler);
    } catch (Exception e) {
      typeHandlers.add(typeHandlerRegistry.getTypeHandler(Object.class));
    }
  }
  // 遍历ResultSet将SQL执行结果转换成List<Map<String, Object>>,列名小写
  while (rs.next()) {
    Map<String, Object> row = new HashMap<>();
    for (int i = 0, n = columns.size(); i < n; i++) {
      String name = columns.get(i);
      TypeHandler<?> handler = typeHandlers.get(i);
      row.put(name.toUpperCase(Locale.ENGLISH), handler.getResult(rs, name));
    }
    list.add(row);
  }
  return list;
}
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>