mybaits 在ORM 框架中,可算是半壁江山了,由于它是轻量级,半自动加载,灵活性和易拓展性。深受广大公司的喜爱,所以我们程序开发也离不开mybatis 。但是我们有对mabtis 源码进行研究吗?或者想看但是不知道怎么看的苦恼吗?
归根结底,我们还是需要知道为什么会有mybatis ,mybatis 解决了什么问题?
想要知道mybatis 解决了什么问题,就要知道传统的JDBC 操作存在哪些痛点才促使mybatis 的诞生。
我们带着这些疑问,再来一步步学习吧。 原始JDBC 存在的问题
所以我们先来来看下原始JDBC 的操作:
我们知道最原始的数据库操作。分为以下几步:
1、获取connection 连接
2、获取preparedStatement
3、参数替代占位符
4、获取执行结果resultSet
5、解析封装resultSet 到对象中返回。
如下是原始JDBC 的查询代码,存在哪些问题?
public static void main(String[] args) { String dirver="com.mysql.jdbc.Driver"; String url="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"; String userName="root"; String password="123456"; Connection connection=null; List<User> userList=new ArrayList<>(); try { Class.forName(dirver); connection= DriverManager.getConnection(url,userName,password); String sql="select * from user where username=?"; PreparedStatement preparedStatement=connection.prepareStatement(sql); preparedStatement.setString(1,"张三"); System.out.println(sql); ResultSet resultSet=preparedStatement.executeQuery(); User user=null; while(resultSet.next()){ user=new User(); user.setId(resultSet.getInt("id")); user.setUsername(resultSet.getString("username")); user.setPassword(resultSet.getString("password")); userList.add(user); } } catch (Exception e) { e.printStackTrace(); }finally { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if (!userList.isEmpty()) { for (User user : userList) { System.out.println(user.toString()); } } }小伙伴们发现了上面有哪些不友好的地方?
我这里总结了以下几点:
1、数据库的连接信息存在硬编码,即是写死在代码中的。
2、每次操作都会建立和释放connection 连接,操作资源的不必要的浪费。
3、sql 和参数存在硬编码。
4、将返回结果集封装成实体类麻烦,要创建不同的实体类,并通过set方法一个个的注入。
存在上面的问题,所以mybatis 就对上述问题进行了改进。
对于硬编码,我们很容易就想到配置文件来解决。mybatis 也是这么解决的。
对于资源浪费,我们想到是用连接池,mybatis 也是这个解决的。
对于封装结果集麻烦,我们想到是用JDK的反射机制,好巧,mybatis 也是这么解决的。
既然如此,我们就来写一个自定义吃持久层框架,来解决上述问题,当然是参照mybatis 的设计思路,这样我们在写完之后,再来看mybatis 的源码就恍然大悟,这个地方这样配置原来是因为这样啊。
我们分为使用端和框架端两部分。
我们在使用mybatis 的时候是不是需要使用SqlMapConfig.xml 配置文件,用来存放数据库的连接信息,以及mapper.xml 的指向信息。mapper.xml 配置文件用来存放sql 信息。
所以我们在使用端来创建两个文件SqlMapConfig.xml 和mapper.xml。
框架端要做哪些事情呢?如下:
1、获取配置文件。也就是获取到使用端的SqlMapConfig.xml 以及mapper.xml的 文件
2、解析配置文件。对获取到的文件进行解析,获取到连接信息,sql,参数,返回类型等等。这些信息都会保存在configuration 这个对象中。
3、创建SqlSessionFactory,目的是创建SqlSession的一个实例。
4、创建SqlSession ,用来完成上面原始JDBC 的那些操作。
那在SqlSession 中 进行了哪些操作呢?
1、获取数据库连接
2、获取sql,并对sql 进行解析
3、通过内省,将参数注入到preparedStatement 中
4、执行sql
5、通过反射将结果集封装成对象
好了,上面说了一下,大概的设计思路,主要也是仿照mybatis 主要的类实现的,保证类名一致,方便我们后面阅读源码。我们先来配置好使用端吧,我们创建一个maven 项目。
在项目中,我们创建一个User实体类