MyBatis动态代理

先看一个MyBatis的使用demo

    @Resource
    SqlSessionFactory sqlSessionFactory;

    @RequestMapping(value = "/query", method = RequestMethod.GET)
    public String query(@RequestParam("name") String name) {
        //获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取代理对象
        MapperProxyFactory<UserDao> proxyFactory = new MapperProxyFactory<>(UserDao.class);
        UserDao userDao = proxyFactory.newInstance(sqlSession);
        //执行并判断结果
        return userDao.queryByName(name) != null ? "success" : "fail";
    }

DAO如图 

@Mapper
public interface UserDao {
    @Select("select id from tb_passbook_user where `user_id`=#{name}")
    Long queryByName(@Param("name")String name);
}

其中 
1.MapperProxyFactory  是生成代理对象的工厂类
2.MapperProxy是InvocationHandler的实现类,invoke方法里面执行真正的逻辑。MapperProxy中维护了Dao接口中的方法的Method对象与MapperMethod对象的映射关系

  protected T newInstance(MapperProxy<T> mapperProxy) {
//生成代理对象
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  public T newInstance(SqlSession sqlSession) {
    //初始化动态代理相应的InvocationHandler
    final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
    //生成代理对象
    return newInstance(mapperProxy);
  }

MapperProxy.invoke方法里面的核心逻辑:

//1.取出方法对应的sql语句
final MapperMethod mapperMethod = cachedMapperMethod(method);
//2.传入sqlSession并执行,如下代码可知执行的是MapperMethod.execute方法
return mapperMethod.execute(sqlSession, args);


3.MapperMethod是实际执行sql逻辑的类
 MapperMethod.execute里面的逻辑

 switch (command.getType()) {
    //插入
      case INSERT: {
      Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.insert(command.getName(), param));
        break;
      }
      //更新
      case UPDATE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.update(command.getName(), param));
        break;
      }
      //删除
      case DELETE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.delete(command.getName(), param));
        break;
      }
      //查询
      case SELECT:
        if (method.returnsVoid() && method.hasResultHandler()) {
          executeWithResultHandler(sqlSession, args);
          result = null;
        } else if (method.returnsMany()) {
          result = executeForMany(sqlSession, args);
        } else if (method.returnsMap()) {
          result = executeForMap(sqlSession, args);
        } else if (method.returnsCursor()) {
          result = executeForCursor(sqlSession, args);
        } else {
          Object param = method.convertArgsToSqlCommandParam(args);
          result = sqlSession.selectOne(command.getName(), param);
        }
        break;
      case FLUSH:
        result = sqlSession.flushStatements();
        break;
      default:
        throw new BindingException("Unknown execution method for: " + command.getName());
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值