mybatis基础及原理

IDEA创建mybatis配置文件模板

IDEA提供了spring框架的配置模板,但是未提供mybatis配置文件模板,因此需要自己创建模板,创建步骤如下:

settings -> Editor -> File and Code template -> Files 然后点击加号,文件后缀名为xml,文件名为mybatis-config,文件内容如下(mybatis配置基础版,根据个人需求添加)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <!--环境配置,连接的数据库,这里使用的是MySQL-->
    <environments default="mysql">
        <environment id="mysql">
            <!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
            <transactionManager type="JDBC"></transactionManager>
            <!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybbs"></property>
                <property name="username" value="root"></property>
                <property name="password" value="root"></property>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--这是告诉Mybatis区哪找持久化类的映射文件,对于在src下的文件直接写文件名,
            如果在某包下,则要写明路径,如:com/mybatistest/config/User.xml-->
        <mapper resource="User.xml"></mapper>
    </mappers>
</configuration>

这样在新建文件的菜单中就能够看到mybatis配置文件的模板了

mybatis基础工程

1、连接数据库,创建table,通过EasyCode插件创建entity类、mapper接口、mapper映射文件(前面说过,不细说)

2、创建mybatis配置文件

3、main方法如下:

public static void main(String[] args) throws IOException {
    String config = "mybatis-config.xml";

    Reader reader = Resources.getResourceAsReader(config);

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    TableStudentDao mapper = sqlSession.getMapper(TableStudentDao.class);

    TableStudent tableStudent = mapper.queryById("bale");
    System.out.println(tableStudent);
}

4、执行结果如下:

mybatis主要构件及层次结构

mybatis运行解析基本原理 

1、构造SqlSessionFactory

通过解析mybatis配置文件以及mapper映射文件,构造了SqlSessionFactory,很重要的一点,这一步构造了一个很重要的Configuration对象;

Configuration对象包含了所有的配置解析信息

2、SqlSession

通过SqlSessionFactory以及配置的数据源,可以得到一个SqlSession对象,SqlSession作为sql会话访问的顶层API接口,提供完整的CRUD方法

带着问题来了解SqlSession;

问题1:怎么获取到SqlSession?

默认情况下,SqlSessionFactory的实现类为DefaultSqlSessionFactory

DefaultSqlSessionFactory提供了如下方法来获取SqlSession:

其中入参有如下几个:是否自动提交、ExecutorType、事务隔离级别、数据库连接对象;例子中使用的是:自动提交

问题2:getMapper方法获取的mapper对象到底是什么?

DefaultSqlSession通过Configuration对象获取mapper,而Configuration类通过mapperRegistry获取mapper

进一步跟踪源码,可以看到:mapperRegistry先从knownMappers中获取到MapperProxyFactory,然后调用MapperProxyFactory的newInstance方法获取到mapper;

再进一步看,MapperProxyFactory的newInstance方法创建了一个MapperProxy对象,而MapperProxy类继承了InvocationHandler接口,到这里能够清晰知道,mapper实际上是一个JDK动态代理对象

问题3:获取到mapper对象后,为什么指定mapper接口中定义的方法就能操作数据库?

前面说到,mapper对象的实质是JDK动态代理对象,对应的InvocationHandler接口实现类为MapperProxy,所以调用mapper接口中的任意方法实质是调用MapperProxy的invoke方法;MapperProxy的invoke方法如下:

前面的判断主要是为了保证toString等方法也能正常调用;实际的数据库操作要看else分支;

由于java8增加了default方法,因此cachedInvoker方法兼容了default方法的处理:

非default方法调用逻辑见PlainMethodInvoker类的invoke方法,PlainMethodInvoker为MapperProxy的一个静态内部类

PlainMethodInvoker的invoke方法的实质是调用了MapperMethod的execute方法:

以insert操作为例,一路跟进(调用过程很简单,不一一列出),最终定格到了SimpleStatementHandler类的update方法:

这里调用了MySql驱动类的execute方法,到此找到了数据库操作的代码;

问题4:mapper接口类和xml文件如何形成映射关系?

Configuration对象存有一个Map对象,key为方法名,value为MappedStatement;MappedStatement存有xml文件的解析信息,在指行数据库操作的方法中调用获取;

问题5:我们知道JDBC操作离不开Connection对象,那么在mybatis中,Connection对象体现在哪里呢?

BaseExecutor类的getConnection方法中通过Transaction对象获取;

 

posted @ 2020-08-10 22:51  光头用沙宣  阅读(272)  评论(0编辑  收藏  举报