Mybatis工具—数据库操作器(SqlRunner)

  MyBatis提供了一个用于操作数据库的SqlRunner工具类,对JDBC做了很好的封装。结合工具类SQL,能够很方便地通过Java代码执行SQL语句并检索SQL执行结果。如下示例代码所示:

String sql = new SQL()
    .SELECT("*")
	.FROM("user_info")
	.WHERE("id = #{id}", "name = #{name}")
	.toString();
Connection connection = DriverManager.getConnection("数据库连接");
SqlRunner sqlRunner = new SqlRunner(connection);
Map<String, Object> result = sqlRunner.selectOne(sql, 1, "Jason");

  SqlRunner不仅提供了上述selectOne()方法,还提供了:

  • SqlRunner#closeConnection():用于关闭Connection对象。
  • SqlRunner#selectOne(String sql, Object… args):执行SELECT语句,SQL语句中可以使用占位符,如果SQL中包含占位符,则可变参数用于为参数占位符赋值,该方法只返回一条记录。若查询结果行数不等于一,则会抛出SQLException异常。
  • SqlRunner#selectAll(String sql, Object… args):该方法和selectOne()方法的作用相同,只不过该方法可以返回多条记录,方法返回值是一个List对象,List中包含多个Map对象,每个Map对象对应数据库中的一行记录。
  • SqlRunner#insert(String sql, Object… args):执行一条INSERT语句,插入一条记录。
  • SqlRunner#update(String sql, Object… args):执行更新SQL语句。
  • SqlRunner#delete(String sql, Object… args):执行删除SQL语句。
  • SqlRunner#run(String sql):执行任意一条SQL语句,最好为DDL语句。

selectAll

  这里以最具代表性的selectAll(String sql, Object… args)方法为例,来进一步剖析SqlRunner类源代码逻辑。

public List<Map<String, Object>> selectAll(String sql, Object... args) throws SQLException {
    try (PreparedStatement ps = connection.prepareStatement(sql)) {
      setParameters(ps, args);
      try (ResultSet rs = ps.executeQuery()) {
        return getResults(rs);
      }
    }
}

  如源代码所示,selectAll详细处理逻辑如下,

  1. 调用Connection对象的prepareStatement()方法获取PreparedStatement对象后;
  2. 调用setParameters()方法为SQL中的参数占位符赋值;
  3. 调用PreparedStatement的executeQuery()方法执行查询操作,并获取查询结果;
  4. 调用getResults()方法,将ResultSet对象转换为List对象,其中List对象中的每个Map对象对应数据库中的一条记录。

setParameters占位符赋值

  在通过Connection对象获取到PreparedStatement对象后,首先调用setParameters方法来对SQL语句中的占位符进行赋值,源代码详情如下,

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 {
          typeHandler.setParameter(ps, i + 1, args[i], null);
        }
      }
    }
}

  如源代码所示,setParameters方法首先会对可变参数args进行遍历,并将得到的值进行如下处理:

  1. 如果该值为null,直接抛出SQLException;
  2. 如果该值为枚举类Null,则寻找Null对应的TypeHandler对象进行参数赋值;
  3. 如果该值不为null,也不为枚举类Null,则寻找该值对应的TypeHandler对象进行参数赋值。

getResults处理结果集

  在组装好SQL语句,并通过PreparedStatement的executeQuery()方法获得查询结果后,此时就该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));
      }
    }
    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;
}

  如上述源代码所示,

  1. 通过ResultSet类的getMetaData()方法获取ResultSetMetaData对象;
  2. 通过ResultSetMetaData对象遍历获取所有列的名称和对应的TypeHandler对象,并将其所有遍历来的结果放入集合中待后续使用;
  3. 遍历ResultSet对象,根据步骤2获取的列名和TypeHandler对象,调用TypeHandler对象的getSesult()方法,将JDBC类型转换为Java类型,然后将ResultSet对象中的记录行转换为Map对象,再将结果放入结果集中以待遍历完后返回。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MyBatis 是一个开源的持久层框架,它可以帮助开发者简化数据库操作。下面是使用 MyBatis 操作数据库的一般步骤: 1. 配置数据库连接:在 MyBatis 的配置文件中,设置数据库连接信息,包括数据库驱动、URL、用户名和密码等。 2. 定义数据模型:创建 Java 类来表示数据库中的表,每个类对应一个表,类的属性对应表的列。 3. 编写 SQL 映射文件:创建一个 XML 文件,定义 SQL 语句和映射关系。在文件中,可以使用 MyBatis 提供的标签来编写 SQL 语句,还可以使用动态 SQL 来实现条件查询等功能。 4. 配置 SQL 映射文件:在 MyBatis 的配置文件中,引入 SQL 映射文件,告诉 MyBatis 哪些 SQL 语句对应哪些方法。 5. 创建 SqlSessionFactory:通过 MyBatis 提供的 SqlSessionFactoryBuilder 类,读取配置文件并创建 SqlSessionFactory 对象。SqlSessionFactory 是一个线程安全的类,用于创建 SqlSession。 6. 创建 SqlSession:通过 SqlSessionFactory 的 openSession 方法创建 SqlSession 对象。SqlSession 是一个用于执行 SQL 语句的接口,它提供了多种方法来操作数据库。 7. 执行 SQL 语句:通过 SqlSession 对象调用相应的方法,执行 SQL 语句。例如,可以使用 selectOne 方法执行查询操作,使用 insert、update 或 delete 方法执行增删改操作。 8. 提交事务和关闭资源:在操作完成后,需要调用 SqlSession 的 commit 方法提交事务,并调用 close 方法关闭资源。 以上是使用 MyBatis 操作数据库的一般步骤,具体的实现方式可以根据项目的需求进行调整和扩展。希望对你有帮助!如果有其他问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐只乐之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值