MyBatis和数据库的交互有两种方式:
方式一、原始的dao调用mybatis
1.需要定义dao接口
2.需要实现dao接口
3.在dao接口实现类上注入sqlSessionFactory,创建sqlSessionFactory时需要读取mapper.xml到内存
4.然后通过创建sqlSession对象来调用mapper中的sql语句(sqlSession.insert(statementId,sql)),在操作结束后需要手工进行提交,释放资源,返回结果
这种方式存在的问题:
(1)dao接口实现类方法中存在大量模板方法,如:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法。
(2)调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码。
(3)调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
方式二、Mapper动态代理:
1.需要定义mapper接口
2.在定义mapper.xml时,需要遵守几条原则(路径,方法,参数,返回结果都要一致)
a.xml中的namespace要和mapper接口的路径相同
b.xml中的statementID要和mapper接口中定义的方法相同
c.xml中的参数类型paramerType要和mapper接口中定义的参数类型相同
d.xml中的返回结果resultType要和mapper接口中定义的返回结果相同
3.在整合spring时,spring初始化就已经把mapper接口类注入了,在注入过程中实际上使用的是动态代理的方式进行的实例化了。
4.动态代理:创建动态代理类MapperProxy需要实现InvocationHandler接口,然后把真实被代理类传入。
5.mybatis代理类的实现过程,会调用动态代理类MapperProxy中invoke方法,接着会调用MapperMethod.execute(),在构造MapperMethod类时,有sqlCommand和MethodSignature两个内部类用来绑定sql和填充参数,然后再调用execute方法最终还是会回到sqlSession上。
这种方式其实是将原始的调用dao的方式优化了,使用动态代理在sqlSession这一步封装了一层,可以不需要传递statementID和参数,而直接通过传递类型来实例化接口。例如:Mapper mapper = getMapper(Mapper.class);