美文网首页java jvmjava学习springbootMybatis
别怕看源码,一张图搞定Mybatis的Mapper原理

别怕看源码,一张图搞定Mybatis的Mapper原理

作者: 肥朝 | 来源:发表于2017-02-06 18:54 被阅读5529次

    提到看源码,很多同学内心的恐惧的,其实这个从人性的角度来说是非常正常的,因为人们对未知的事物,都是非常恐惧的,其次,你内心可能始终觉得,好像不会原理也还是能工作啊,你的潜意识里没有强烈的欲望.从阅读源码的经历来说,Java三大框架SSM中,Mybatis的源码是最适合入门的.

    简单使用

    这是一个简单的Mybatis保存对象的例子

    @Test
    public void testSave() throws Exception {
        //创建sessionFactory对象
        SqlSessionFactory sf = new SqlSessionFactoryBuilder().
                build(Resources.getResourceAsStream("mybatis-config.xml"));
        //获取session对象
        SqlSession session = sf.openSession();
        //创建实体对象
        User user = new User();
        user.setUsername("toby");
        user.setPassword("123");
        user.setAge(23);
        //保存数据到数据库中
        session.insert("com.toby.mybatis.domain.UserMapper.add", user);
        //提交事务,这个是必须要的,否则即使sql发了也保存不到数据库中
        session.commit();
        //关闭资源
        session.close();
    }
    
    <mapper namespace="com.toby.mybatis.domain.UserMapper">
        <!--#{}在传入的对象中找对应的属性值-->
        <!--parameterType传入的参数是什么类型-->
        <insert id="add" parameterType="com.toby.mybatis.domain.User">
            INSERT INTO USER (username,password,age) VALUES (#{username},#{password},#{age})
        </insert>
    </mapper>
    

    引出主题

    但是在实际中,我们都不是这样操作的,我们是通过Mapper接口,调用接口方法,就能实现CRUD操作,那么关键是,这个接口究竟做了什么事,才是我们关心的.

    只要把下面这段代码究竟发生了什么事弄明白,就明白,这个Mapper接口究竟做了什么事.

    public void testGetObject() throws Exception {
        SqlSession session = MybatisUtil.openSession();
    
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.get(5L);
    
        System.out.println(user);
        session.close();
    }
    
    public interface UserMapper {
    
        public void add(User user);
        public User get(Long id);
    }
    

    看图

    但是我认为,一张流程图就能够看明白这期间所发生的事

    mapper接口的原理.png

    心血来潮再补上一张时序图


    mapper时序图.png

    想了解Mybatis缓存的移步Hibernate和Mybaitis缓存

    相关文章

      网友评论

      • xs杨:把图里面的文字写出来一步一步的,比较容易看清,图里面的文字有的看不清
      • FinalFantasyXX:这张图非常清楚,但是如果有一张mybatis-spring 自动扫描并注入Mapper的图就完整了
      • 陶朝阳:帮帮的,就这么多。非规矩的动态代理:stuck_out_tongue_winking_eye:
      • 09cad230be55:把序列图每一步的作用介绍出来,更好。
        这里面用了哪些模式等等,分析下原因。 对作者将来底层系统设计有帮助。
      • 帅气的你称:楼主,以前看了你的这个图,对图里面3和4的流程是在么转换的不了解,3返回了一个新的代理,invoke方法是在什么时候执行的?执行过程是在么样的,对这个不懂?
        751162c05b8b:@帅气的你称 debug感受一下
        帅气的你称:@肥朝 谢谢:pray:
        肥朝:1.invoke方法什么时候执行的?
        jdk动态代理创建代理对象的时候需要传入三个参数,分别为(1)类加载器,(2)为哪些接口做代理(拦截什么方法),(3)把这些方法拦截到哪里处理,从图中我们得知,他是要把执行的方法拦截到MapperProxy类中的invoke方法处理,换句话说,该动态代理对象执行接口中的方法,都会调到MapperProxy类的invoke方法处理,这也就是为什么调用get方法的时候会调用invoke
        2.执行过程
        图中已经比较明显,那我还是文字给你简单描述一下原理.mapper文件中要定位到sql,需要两个条件,一个是namespace,一个是sql id.要想用这种mapper接口的方式调用也必须遵循一个约定,那就是namespace等于接口的权限定名.接口的方法名等于xml文件中的sql id,这就是为什么图中封装MapperMethod的时候,需要把这两个传进去的原因.确定了sql,传入参数mapperMethod.execute(args),拼接成一条完成sql,执行之.
      • b96d77dbf049:想知道你最后一图的做图工具是哪个?
        肥朝:看这里 http://www.jianshu.com/p/d92ff3f6b00c
      • WJL3333:亲,数字标号大一点就好了。
        徐长跃:新标签页打开图片,最后参数/w/700 把700换成1200 1300 1500 。。。。查看高清大图
        肥朝:标号已经放大了,你点击图片放大看看是否合适,另外刚写了一篇Hibernate和Mybatis缓存对比的文章你可以看看

      本文标题:别怕看源码,一张图搞定Mybatis的Mapper原理

      本文链接:https://www.haomeiwen.com/subject/jvbeittx.html