mybatis有两种访问mapper对象去操作数据的方式。
1.新建mapper接口,在里面定义一些操作数据库的方法,不用实现,加上@Repository告诉mybatis这是个map层,例如
@Repository
public interface MainMap {
public List
}
2.获取SqlSession,通过SqlSession执行增删改查的方法。例如:
@Autowired
private SqlSessionFactoryBean sqlSessionFactoryBean;
public List
List
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
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最核心的类,数据库的增删改查都是通过它来实现,大家可以下去看下资料。