首先应把相关的Log4J jar包复制到工程的lib目录下,本示例使用的是log4j-1.2.16.jar。
然后应创建log4j.properties文件,用以指定Log4J的行为,并放置到classpath中。在本示例中是将此文件放置在工程的src目录下,工程编译前会将此文件复制到classes目录中(详见工程的生成文件build.xml中的copy-resources target,从23行开始。点此处下载示例源码),而classes目录会被ant加载到classpath中(详见build.xml的37-39行,关于Log4J的日志级别请参见:http://www.51testing.com/?uid-225738-action-viewspace-itemid-212359;配置请参见:http://www.blogjava.net/zJun/archive/2006/06/28/55511.html):
执行的主程序如下:
package com.demo;
import org.springframework.context.ApplicationContext;
import com.abc.mapper.StudentMapper;
import com.abc.mapper.TeacherMapper;
import com.abc.domain.Teacher;
import com.abc.domain.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
publicclass CollectionDemo
{
privatestatic ApplicationContext ctx;
static
{
//在类路径下寻找resources/beans.xml文件
ctx = new ClassPathXmlApplicationContext("resources/beans.xml");
}
publicstaticvoid main(String[] args)
{
//从Spring容器中请求映射器,这里使用通过
//@Component注解指定的bean名称
TeacherMapper mapper =
(TeacherMapper)ctx.getBean("myTeacherMapper");
//查询id为1的教师
Teacher teacher = mapper.getById(1);
if(teacher == null)
{
System.out.println("未找到相关教师信息。");
}
else
{
//教师信息
System.out.println("**********************************************");
System.out.println("教师姓名:" + " " + teacher.getName());
System.out.println("教师职称:" + " " + teacher.getTitle());
System.out.println("**********************************************");
System.out.println("指导学生信息:");
//遍历指导的学生
for(Student s : teacher.getSupStudents())
{
System.out.println("**********************************************");
System.out.println( s.getName() + " " + s.getGender() + " " + s.getGrade()
+ " " + s.getMajor());
//从学生端访问教师
System.out.println("指导教师研究方向:" + s.getSupervisor().getResearchArea());
}
System.out.println("**********************************************");
}
}
}
由此可看出,程序的核心是调用TeacherMapper的getById方法。
1、若log4j.properties内容如下:
#全局日志配置
log4j.rootLogger=DEBUG, stdout
#MyBatis日志级别配置。以下是配置com.abc.mapper
#包下所有类的日志级别
log4j.logger.com.abc.mapper=DEBUG
#可用以下的10和11行分别配置TeacherMapper和TeacherMapper的getById
#方法的日志级别。log4j.logger.com.abc.mapper.TeacherMapper
#以log4j.logger.com.abc.mapper为前缀,表明
#log4j.logger.com.abc.mapper是其父logger。其他以此类推
#log4j.logger.com.abc.mapper.TeacherMapper=TRACE
#log4j.logger.com.abc.mapper.TeacherMapper.getById=INFO
#日志输出到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
#关闭Spring日志
log4j.category.org.springframework = OFF
运行结果如下:
可看出,已按DEBUG级别打印出了com.abc.mapper包下的日志。
2、若把com.abc.mapper包的日志级别调整为INFO,即:
log4j.logger.com.abc.mapper=INFO
则执行结果如下:
INFO级别高于DEBUG级别,改为INFO则应该不再打印DEBUG级别的日志,但实际情况是DEBUG日志仍然和上例一样被打印了出来。可见,作为rootLogger的子logger,即使log4j.logger.com.abc.mapper定义的日志级别高于rootLogger,也无法生效。
3、现在把com.abc.mapper的日志级别修改为TRACE(级别低于DEBUG),即:
log4j.logger.com.abc.mapper=TRACE
运行结果如下:
由上图可见,TRACE级别的日志已被打印出来,TRACE设置已生效。
4、若log4j.logger.com.abc.mapper的日志级别仍为TRACE,作为其子logger, log4j.logger.com.abc.mapper.TeacherMapper的级别设置为DEBUG(高于TRACE),即:
log4j.logger.com.abc.mapper.TeacherMapper=DEBUG
则运行结果如下:
可以看出,TRACE级别的日志已不再打印,作为子logger 的log4j.logger.com.abc.mapper.TeacherMapper的日志级别DEBUG虽然高于log4j.logger.com.abc.mapper的日志级别,但也生效了。
5、若log4j.logger.com.abc.mapper的日志级别为DEBUG,作为其子logger, log4j.logger.com.abc.mapper.TeacherMapper的级别设置为TRACE(低于DEBUG),即:
log4j.logger.com.abc.mapper=DEBUG
log4j.logger.com.abc.mapper.TeacherMapper=TRACE
则运行结果如下:
可以看出,正如我们所猜想的,作为子logger 的log4j.logger.com.abc.mapper.TeacherMapper,其TRACE级别的设置生效了。
结论:logger的级别若高于rootLogger的级别,则不生效,按rootLogger的级别算;在此前提下,各logger的级别按自己的设置生效。