mybatis执行时原理的简单分析
- 前置知识:mybatis中配置文件的解析
- 自定义实现类的方式
- 动态代理生成代理类的方式
mybatis中配置文件的解析
解析xml文件的技术有很多,我们不需要全部去掌握,但是我们要知道我们的xml文件通过解析可以得到什么
可以发现通过我们解析得到的这2个信息就可以实现我们jdbc的操作了。我们可以通过映射信息,通过方法名寻找他要执行的sql语句,然后将找到的sql语句放到预处理对象的方法中去执行就可以了
构建者模式创建sqlSessionFactory
构建者模式可以将我们对象的构建和表示隔离开来,一般用于复杂对象的创建
自定义dao实现类
在这种方式下由我们自己去完成dao的实现类
SqlSesson接口是我们mybatis框架中数据库操作的核心接口,它里面定义了关于操作数据库的一些列方法,包含获取/关闭连接,增删改查方法等等,
-
执行过程分析
-
实现类举例
public class UserDaoImpl implements UserDao {
//定义工厂用于创建sqlSession对象
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public List<User> findAll() {
//工厂创建sqlSession对象
final SqlSession sqlSession = sqlSessionFactory.openSession();
final List<User> users = sqlSession.selectList("com.atheima.dao.UserDao.findAll");//参数是映射的key
sqlSession.close();
return users;
}
我们的sqlSession中定义了增删改查的方法,所以我们需要在实现类中调用sqlSession中的方法完成我的操作。在这之前需要解析配置文件,然后完成相关数据的封装(主要为连接信息的封装和映射信息的封装),从上面执行流程的分析可以看到sqlSession.selectList("com.atheima.dao.UserDao.findAll");//参数是映射的key
通过映射找到相应的sql,然后将需求一层层向下传递,最终还是交给了jdbc的preparedStatement对象执行,并封装相应的结果集
动态代理生成代理类的方式
和自定义dao实现类最大的区别是由动态代理生成实现类,此时我们的代理类就是实现类。这样我们就可以不写实现类,也是用到最多的
这张图主要是分析动态代理的过程,因为后面就和前面一样的了。我们通过getMapper()
生成代理对象。我们不需要使用sqlSession
对象调用相应的方法,这一切都通过动态代理在其内部帮我们实现了
是否可以认为我们的映射文件所表示的映射关系就是我们的代理对象
- 也不知道我理解的是不是正确的?
代理对象中的方法的内容是,1.调用被代理类中被代理的方法2。执行增强部分的逻辑。而我们的映射文件所表示的信息是.
Map((具体方法),(方法中执行的sql语句和返回类型)),而这个关系简直就和我们的代理类中的结构一摸一样。所以我们也将dao接口和映射文件都称为mapper。因为他们从本质上来说就是一个映射关系
将映射关系认为是代理对象这样的想法毫无意义。以后不要这样认为了。对于dao可以被称为mapper完全是历史遗留问题。对于映射关系:只是对应这一个方法他需要执行的sql语句
对于spring中使用切面的理解以及和mybatis的联系
spring的aop是基于动态代理实现的,在动态代理中,我们需要将方法的增强部分都写在实现了InvocationHander接口的invoke方法中,然后去调用被代理的方法。
但是当我们的代理的方法过多时,这将会是非常繁琐的过程。我们可能有多个方法会有相同的增强逻辑,如果都在invoke方法都体现,这将导致大量的代码冗余
于是spring将我们的增强逻辑(方法)和被代理方法(切入点方法)的对应关系建立了一个切面的概念,并把他们的对应关系封装在切面类中。此时我们在invoke方法中就不需要写增强逻辑了,我们的invoke方法会根据他们的方法名去寻找到对应的增强方法去执行。而且我们可以根据切入点表达式解决了很多方法对应相同的增强逻辑的表示问题
- 和mybatis的联系
在mybatis中映射文件中描述的是接口中的方法和他需要执行的sql语句的对应关系。我认为这和切面所表达的意思基本是一致的。mybatis在代理的时候执行过程基本和前面是类似的