1.用戶使用
1.提供 xxMapper接口
public interface UserMapper {
@Select(value = "select * from user where id=#{id}")//(1)注解方式
public User getUser(Long id);
}
2.在xml里配置(可選配置)(2)
<mapper namespace="org.wangying.dao.UserDao">
<select id="getUser" resultType="org.wangying.entity.User" parameterType="Long">
select * from user where id=#{id}
</select>
</mapper>
2.mybatis實(shí)現(xiàn)
在調(diào)用sqlSession.getMapper(Class)發(fā)生了一些神奇的事情
DefaultSqlSession.getMapper(type)
Configuration.getMapper(type,sqlSession)
MapperRegistry.getMapper(type,sqlSession) //存放鍵值對type(接口)-MapperProxyFactory
MapperProxyFactory.newInstance(sqlSession)
mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);//代理對象
MapperProxyFactory.newInstance(mapperProxy)
Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy)//生成了一個代理實(shí)例匪傍,返回
1.實(shí)現(xiàn)了對應(yīng)的接口
mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
2.使用Proxy生成了一個代理實(shí)例
Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy)
動態(tài)代理實(shí)現(xiàn)
MapperProxy 實(shí)現(xiàn)InvocationHandler
在invoke方法中從sqlSession的configuration中獲取sql語句俩垃,
根據(jù)sql語句生成方法(jdbc的prepareStatement)
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
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);//從sqlSession的configuration中獲取sql語句,根據(jù)sql語句生成方法(jdbc的prepareStatement)
return mapperMethod.execute(sqlSession, args);//執(zhí)行映射成的方法
}