主要思路:dom4j解析配置文件生成一个全局配置对象,利用jdk动态代理创建出接口的代理类,通过代理类完成crud的操作,从而间接完成接口方法中的crud操作(代理通过以接口方法名为id就可以拿到对应的sql语句,所以dao接口的接口方法其中一个作用就是代理类用来寻找对应的sql语句的)
//通过流的方式加载mybatis配置文件 InputStream in = Resource.getResourseAsStream("classpath:mybatis.xml") //创建sqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in) //创建sqlSession SqlSession session = sqlSessionFactory.openSession() //创建代理类 xxxDao dao = session.getMapper(xxxDao.class) //执行语句 dao.selectXXX()
//加载驱动 Class.forName("com.mysql.jdbc.Driver") //建立连接 Connection connection = DriverManager.getConnection(url,userName,password); //定义sql语句 String sql = ""; //创建语句对象 Statement statement = connection.PreparedStatement(sql); //参数设置 statement.setXXX(index,vlaue) //执行sql语句 ResultSet resultSet = statement.executeQuery() //解析结果数据集 while(resultSet.hasNext()){ ... ... } //关闭连接 statement.close(); connection.close();
众所周知,MyBatis的底层就是jdbc,正所谓哪有什么幸福和平,只是有人在负重前行。MyBatis是如何帮我们完成底层的jdbc的操作的呢?在这里先简单概括一下
JDBC | MyBatis |
加载驱动 | 直接加载到JVM,与JDBC加载一样 |
创建连接 | 执行器创建 |
创建语句对象 | 配置文件中的语句会被封装成语句对象 |
参数设置 | 参数处理器执行 |
执行 | 执行器执行 |
处理返回集 | 返回值处理器处理 |
顺便提一下:MyBatis拥有四大对象,分别是执行器executor,语句控制器statementHandler,参数控制器parameterHandler以及返回值处理器resultSetHandler,该框架正是利用这四大对象来完成sql语句的执行与返回。
1.解析MybatisConfig.xml,并封装成一个全局的Configuration对象,通过该对象来保存配置文件中的值
(1)实现逻辑:通过工具类Resource获取配置文件的输入流,然后利用SqlSessionFactoryBuilder解析xml文件生成的Configuration对象并以此为参数创建出SqlSessionFactory
(2)代码示例:
① 利用SqlSessionFactoryBuilder的build方法解析全局配置文件
② 利用build()里的parse方法进行解析
③利用parse里的parseConfiguration解析成configuration对象
④解析每一个标签结点(以mapper为例)
⑤ 进入到this.mapperElement()方法,最后其实就是解析完该单个标签的值后给this.configuration赋值,最终返回该configuration(这里也完成了接口方法与mapper文件中的sql语句的绑定(MappedStatement对象))
2.SqlSessionFactory创建出SqlSession(默认是defaultSqlSession)
3.SqlSession创建出对应接口的代理类(接口式编程)
(1)实现逻辑:Mybatis启动时会创建出以接口类型为key,MapperProcyFactory为Value的knownMappers,通过knownMappers就可以找到接口的MapperProxyFactory,进而创建出代理类的实例对象,而MapperProxyFactory的实例对象MapperProxy则是InvocationHandler接口实现类并实现了invoke方法(实际就是用反射创建了代理类)
(2)代码示例
①通过sqlSession的getMapper()创建出对应的代理类
② 实际调用的是Configuration的getMapper方法,从mapper注册中心拿到对应的mapperProxyFactory,进而创建出MapperPeoxy实例
③:创建出MapperProxy实例
4.调用dao层方法:MapperProxy的invoke方法中会执行已经被映射的sql方法
(1)实现逻辑:找到被绑定的sql语句,然后参数转换,参数设置等,然后利用执行器创建连接,创建语句对象,然后执行sql语句
(2)代码示例
①:MapperProxy的invoke方法
②:最终是调用内部类PlainMethodInvoker的invoke方法,进而调用mapperMethod的execute方法
③:execute方法,就是利用判断语句类型,通过sqlSession去执行底层的数据库CRUD操作,并通过返回值处理器等进行返回值处理
5.最后利用返回值处理器处理ResultSetHandler把查询结果处理,最后层层返回