一、原生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的树干。后续分析这颗树干的具体实现。