mybatis mapper接口不用去实现就能处理业务原理

mybatis有两种访问mapper对象去操作数据的方式。

1.新建mapper接口,在里面定义一些操作数据库的方法,不用实现,加上@Repository告诉mybatis这是个map层,例如

@Repository
public interface MainMap {
public List getUserInfo(); 
}


2.获取SqlSession,通过SqlSession执行增删改查的方法。例如:

@Autowired
private SqlSessionFactoryBean sqlSessionFactoryBean;

public List getUserInfo() {
List result=null;
try {
SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBean.getObject();
SqlSession sqlSession=sqlSessionFactory.openSession();
result=sqlSession.selectList("com.hbut.inspiration.map.MainMap.getUserInfo",null);

}

}

在这里有我们来分析第一种方式,每个人初识mybatis的时候是不是都有一个疑惑就是,map定义一个接口不用去实现,然后注入到service层就可以处理业务逻辑了,其实不然,下面我来解析:

当我们在service层注入一个map接口例如

package com.hbut.inspiration.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hbut.inspiration.map.MainMap;
import com.hbut.inspiration.service.MainService;


@Service
public class MainServiceImpl implements MainService{

   @Autowired
   private MainMap mainMap;

}

其实spring依赖注入了mainMap它的代理类,其实所有的map接口都有一个代理类,是通过java的动态代理生成的

我们来看看源码:

publicstatic T newMapperProxy(Class mapperInterface, SqlSession sqlSession) {      

 ClassLoaderclassLoader = mapperInterface.getClassLoader();

 Class[] interfaces = new Class[{mapperInterface}; 

 MapperProxyproxy = new MapperProxy(sqlSession); 

 return (T) Proxy.newProxyInstance(classLoader,interfaces, proxy); 

}  

mapperInterface参数就是我们的map接口,它通过Proxy.newProxyInstance()生层MapperProxy代理对象。

对象被代理之后,执行对象的所有方法都将进入到代理对象的invoke方法去执行,我们来看下MapperProxy的invoke方法:

public Objectinvoke(Object proxy, Method method, Object[] args) throws Throwable{

 if (method.getDeclaringClass()== Object.class) {  

  return method.invoke(this, args); 

 } 

  finalMapperMethod mapperMethod = newMapperMethod(declaringInterface, method, sqlSession);   final Objectresult = mapperMethod.execute(args); 

  if (result ==null && method.getReturnType().isPrimitive()&& !method.getReturnType().equals(Void.TYPE)) {      

   thrownewBindingException("Mapper method '" + method.getName() + "'(" + method.getDeclaringClass()                   + ") attempted toreturn null from a method with a primitive return type (" + method.getReturnType() + ").");    

  }   

   return result; 

  }  

map接口的执行都将在执行MapperProxy的invoke方法,它是实现了invocationhandler接口实现了动态代理。然后就是mybatis内部一系列的方法了,invoke把执行权转交给了MapperMethod,MapperMethod就像是一个分发者,他根据参数和返回值类型选择不同的sqlsession方法来执行。sqlsession是mybatis最核心的类,数据库的增删改查都是通过它来实现,大家可以下去看下资料。






你可能感兴趣的:(mybatis mapper接口不用去实现就能处理业务原理)