为什么使用Mybatis对JDBC进行包装探究

一、原生JDBC在实际生产中使用存在的影响性能的问题

  首先分析使用JDBC的代码:

   Connection connection = null;

   PreparedStatement preparedStatement = null;

   ResultSet resultSet = null;

   try{

    //加载数据库驱动
    Class.forName("com.mysql.cj.jdbc.Driver");
    //通过驱动获取链接
    connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC", "root", "root");
    //定义SQL语句?表示占位符
    String sql = "select * from user where username=?";
    //获取预处理语句
    preparedStatement = connection.prepareStatement(sql);
    //设置参数
    preparedStatement.setString(1, "张三");
    //获取结果
    resultSet = preparedStatement.executeQuery();
    //遍历结果
    while (resultSet.next()){
        int id = resultSet.getInt("id");
        String username = resultSet.getString("username");
        //封装User实例
        User.setId(id);
        User.setUsername(username);

    }
}catch (Exception e){
    e.printStackTrace();
}finally {
    //释放资源
    resultSet.close();
    preparedStatement.close();
    connection.close();
}
  这段代码中存在的问题:
  1)数据库在使用频繁链接,释放容易造成系统资源浪费,从而影响系统的性能。
  2)从sql,到预处理语句,到结果集的处理都存在硬编码的情况。实际生产中业务sql的变动可能性还是比较大的,频繁修改代码将导致系统不容易维护。
二、如何解决上面的问题使生产上的系统更加有效率
  1、对于数据库频繁链接释放,采用数据库连接池初始化的方式解决。
  2、对于sql语句的硬编码问题,采用xml配置文件的方式解决。即将sql语句从业务逻辑代码中分离。
  3、对于结果集的硬编码,使用java的反射、自省的技术,实现数据库表字段与实例类属性的自动映射。
三、Mybatis解决JDBC效率问题的实现
  1、数据库链接及释放:mybatis提供非池化及池化的数据源,在xml配置文件中datasource type可以指定。具体实现在datasource包中。
  2、sql语句的硬编码:与实体类对应mapper下XXXmapper.xml文件解决。
  以上二个具体实现逻辑为:mybatis提供保存配置文件的缓存Configuration和MappedStatement,其中MappedStatement作为Configuration的属性。
MappedStatement保存mapper.xml映射文件解析后的sql语句,Configuration保存datasource、mappedstatement等其他信息。
具体解析由ConfigurationBuilder和MappedStatementBuilder完成。
  3、对于结果集由ResulMap等相关类使用反射或内省实现。

  总结:mybatis封装JDBC的大致逻辑为:客户端将数据源、sql语句、返回结果类型等信息保存在xml文件中(也可以是注解),mybatis将这些信息读取到Configuration中保存,
然后通过Executor执行sql,并将返回结果集映射回实体对象。客户端就可以直接使用实体对象即可。总之即客户端需要完成的工作仅为配置即获取结果后使用,
其他中间工作均交由mybatis完成。
  如果mybatis是一颗树,那么可以认为mybatis封装JDBC的逻辑即为mybatis的树干。后续分析这颗树干的具体实现。