Mybatis获取代理对象

  • mybatis-config.xml里标签可以放置多个environment,这里可以切换test和develop数据源
  • databaseIdProvider提供多种数据库,在xml映射文件里选择databaseId即可使用对应的数据库
  • Oracle的自增是使用Sequence实现的,若要获取插入数据的主键,在xml映射里写上selectKey标签,select seq.nextval from dual;
  • 哪些地方不能使用占位符?比如分表时表名,orderby,desc
  • @Mapkey("id")指定返回类型为map时,将id作为key

    1. mybatis参数绑定的过程

    我们写一个UserMapper接口,Mybatis会为改接口创建一个MapperProxy对象。

    1.1 MapperRegistry

    在继续之前,先来了解一下MapperRegistry。

  1. MapperRegistry是mapper的注册类,提供了注册一个包下面的所有Mapper接口。内部维护了一个private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<Class<?>, MapperProxyFactory<?>>();map以mapper接口类为key,value是接口类对应的代理工厂。
    void addMapper(Class<T> type)方法简单的将type放进knownMappers里面。不过,这里面还有
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();

这样一个解析操作,暂不做分析。

  1. <T> T getMapper(Class<T> type, SqlSession sqlSession)该方法是本类最重要的一个方法了,获取Mapper接口的代理对象也正是从该方法获取的。
    该方法实现就是,knownMappers.get(type)得到代理对象工厂mapperProxyFactory,返回的是mapperProxyFactory.newInstance(sqlSession)
    进入该方法发现过程也比较简单,构造了一个MapperProxy对象
   public T newInstance(SqlSession sqlSession) {
    final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

再进去看

  protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

发现这就是标准的JDK面向接口的动态代理啊。要问对应的InvocationHandler在哪里?mapperProxy就是啦。
至此,Mybatis如何获取Mapper接口的代理对象已经解决。
再梳理一下整个流程:

sqlsession.getMapper->configuration.getMapper->mapperRegistry.getMapper->获取Mapper代理对象

1.2

创建好MapperProxy对象之后,调用Mapper.xx方法时就会走MapperProxy的invoke方法

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {//如果方法是在Object里面的,放行
        return method.invoke(this, args);
      } else if (isDefaultMethod(method)) {
        return invokeDefaultMethod(proxy, method, args);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
    final MapperMethod mapperMethod = cachedMapperMethod(method);//缓存method方法
    return mapperMethod.execute(sqlSession, args); // 执行
  }

发现关键点在于mapperMethod.execute(sqlSession, args)方法

原文地址:https://www.cnblogs.com/studentytj/p/10428572.html

时间: 2024-10-04 03:32:06

Mybatis获取代理对象的相关文章

在spring中获取代理对象代理的目标对象工具类

问题描述:: 我现在遇到个棘手的问题,要通过spring托管的service类保存对象,这个类是通过反射拿到的,经过实验发现这个类只能反射取得sservice实现了接口的方法,而extends类的方法一律不出现,debug后发现这个servie实例被spring替换成jdkdynmicproxy类,而不是原始对象了,,它里面只有service继承的接口方法,而没有extends 过的super class方法,怎么调用原生对象的方法!!!!! 用托管的spring service类调用getCl

6、Spring+Struts2+MyBatis(mybatis有代理)整合增删改查

1.创建如下的oracle脚本 1 create table userinfo 2 (id number(4), 3 name varchar2(50), 4 password varchar2(20 5 telephone varchar2(15), 6 isadmin varchar2(5)); 7 8 --4.2 用户表序列 9 create sequence seq_userinfo; 10 11 alter table userinfo add constraint pk_userin

Mybatis 接口代理的实现

相信在开发中,尤其是mybatis 配置操作中,我们只需要提供一个mapper 接口,然后注入到service 中,就可以进行调用. 按我们的一般逻辑来说,我们并没有进行接口的实现,应该会报空指针异常,那么Mybatis 是如何进行操作的呢? 这主要是得于Spring 强大的扩展机制,进入正题: 1. Spring 提供了 BeanDefinitionRegistryPostProcessor 接口,通过这个接口的实现,可以自定义一些我们bean ,让Spring 在初始化的时候进行bean 的

dubbo源码分析三:consumer注册及生成代理对象

本章我们将分析一下consumer向注册中心注册,并获取服务端相应的信息,根据这些信息生产代理对象的过程和源码. 1.类图 上图展示了部分消费者注册及生成代理对象过程中需要使用到的类和接口,其中: spring适配涉及到的类:DubboNamespaceHandler.DubboBeanDefinitionParser.ReferenceBean; 配置信息存储:ReferenceConfig.RegistryConfig.MonitorConfig.ProtocolConfig.Consume

Mybatis 映射器接口代理对象的方式 运行过程debug分析

查询一张表的所有数据. 环境: 使用工具IntelliJ IDEA 2018.2版本. 创建Maven工程不用骨架 1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

获取SPRING 代理对象的真实实例,可以反射私有方法,便于测试

/** * 获取 目标对象 * @param proxy 代理对象 * @return * @throws Exception */ public static Object getTarget(Object proxy) throws Exception { if(!AopUtils.isAopProxy(proxy)) { return proxy;//不是代理对象 } if(AopUtils.isJdkDynamicProxy(proxy)) { return getJdkDynamicP

获取JDK动态代理/CGLIB代理对象代理的目标对象。

问题描述:: 我现在遇到个棘手的问题,要通过spring托管的service类保存对象,这个类是通过反射拿到的,经过实验发现这个类只能反射取得sservice实现了接口的方法,而extends类的方法一律不出现,debug后发现这个servie实例被spring替换成jdkdynmicproxy类,而不是原始对象了,,它里面只有service继承的接口方法,而没有extends 过的super class方法,怎么调用原生对象的方法!!!!! 用托管的spring service类调用getCl

android binder 进程间通信机制5-Service注册和代理对象的获取

ServiceManager,其实也是一个Service,不过它的Server端实现并未使用Binder库的结构实现,而是直接打开binder/dev进行通信的,不具有普遍性. 下面以MediaServer中的MediaPlayService为例,说明更加普遍的使用binder通信机制的Service的实现. 一.Service组件的启动 Service组件是在Server进程中运行的,Server进程通常从其main函数启动,启动时通常做两件事: 1.首先将它里面的Service组件注册到Se

4.MyBatis Mapper代理开发方式(推荐使用)

1 Mapper代理开发方式(推荐) Mapper代理的开发方式,程序员只需要编写mapper接口(相当于dao接口)即可.Mybatis会自动的为mapper接口生成动态代理实现类. 不过要实现mapper代理的开发方式,需要遵循一些开发规范. 1.1  Mapper开发规范 1. mapper接口的全限定名要和mapper映射文件的namespace的值相同. 2. mapper接口的方法名称要和mapper映射文件中的statement的id相同: 3. mapper接口的方法参数只能有一