Sring + mybatis + log4j没有日志 spring默认jcl
因为OLD jcl+log4j有日志 NEW jcl+log4j没有日志===》使用jcl+jul
jul日志级别不允许改变:spring 默认jcl—>jul实现--->集成mybatis之后不能打印sql,因为jul级别info-up, 但是sm中是info-down
old jcl+log4j有日志log4j进行实例化 看源码可以看到
Mybatis中Logfactory类
static {
tryImplementation(new Runnable() {
@Override
public void run() {
useSlf4jLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useCommonsLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useLog4J2Logging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useLog4JLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useJdkLogging();
}
});
tryImplementation(new Runnable() {
@Override
public void run() {
useNoLogging();
}
});
}
mybatis解析mapper有几种方式?四种
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
.. <mapper url="org/mybatis/example/BlogMapper.xml"/>
.. <mapper class="org/mybatis/example/BlogMapper.xml"/>
.. <package name=""></package>
mybatis与sm是完全不同的代理实现
mybatis使用defaultSqlSession(sqlSession.getMapper(BookMapper.class)方法打断点进去查看,使用)
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
spring使用sqlsessionTemplate
2.mybatis的缓存
2.1mybatis的一级缓存
sm中mapper的实现都是MapperFactoryBean类中的getObject方法产生的代理对象,调用sqlSessionTemplate的getSqlSession方法,mapperProxy实现invocationHandler接口,执行mapperProxy类invoke方法
public T getObject() throws Exception {
return getSqlSession().getMapper(this.mapperInterface);
}
|
public <T> T getMapper(Class<T> type) {
return getConfiguration().getMapper(type, this);
}
|
return mapperProxyFactory.newInstance(sqlSession);
|
最后
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);}
调用MapperProxy的invoke方法,其中MapperMethod 类似于Spring中的beandefinition
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);
return mapperMethod.execute(sqlSession, args);
}
MapperMethod 类executeForMany方法
result = sqlSession.<E>selectList(command.getName(), param);
之后调用SqlSessionTemplate中的方法,method为SqlSession.selectList() sqlSession为DefaultSqlSession 关闭sqlSession使一级缓存失效
private class SqlSessionInterceptor implements InvocationHandler {
.....
Object result = method.invoke(sqlSession, args);
.....
finally {
if (sqlSession != null) {
closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
}
}
}
mybatis和spring的集成包扩展了类 SqlSessionTemplate,这个类在spring容器启动的时候注入给了mapper,增强了defaultSqlSession,SqlSessionTemplate当中的查询方法不是直接查询而是经过一个代理对象,增强查询方法,主要是关闭session
一级缓存sqlSession,放在了线程中
二级缓存sqlSessionFactory跟sql命名空间有关系,不支持分布式缓存
spring+mybatis -->sqlSession-->sqlsessiontemplate-->sqlsessiontemplate.select-->(通过代理对象进行增强主要关闭sqlsession ) sqlsessionProxy.select-->proxy.invoke-->selectList
写在接口中的SQL语句的初始化,是mapper被实例化之后,立刻放在MappedStatement中
mybatis与spring整合的流程,利用spring中的InitializingBean接口(MapperFactoryBean实现)中的afterPropertiesSet()方法->调用checkDaoConfig(),调用实现mybatis的初始化
初始化过程中先调用PostConstruct,再调用afterPropertiesSet
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName); }
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);}
mubatis-->sqlSession-->defaultSqlSession-->defaultSqlSession.select-->(近似jdbc连接)executor.query-->sql