Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
使用步骤
1、新建一个maven项目导入相关依赖
2、在src/main/resources下新建properties配置文件
这里注意的是,配置文件名必须使用log4j.properties
log4j.rootCategory=DEBUG, stdout , R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=E:\\tools\\log\\qc.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
参数介绍:
log4j.rootCategory=DEBUG, stdout , R
意思是将等级为DEBUG(不分大小写)的日志信息输出到stdout和R这两个目的地,stdout和R的定义在下面的代码,可以任意起名。
日志等级:可分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL(从右至左,日志等级增大
)
如果配置OFF则不会打印任何信息,如果配置为INFO,这样只显示INFO、WARN、ERROR的log信息,而DEBUG信息不会被显示
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
定义名为stdout的输出端是哪种类型,可以是
org.apache.log4j.ConsoleAppender(控制台),
org.apache.log4j.FileAppender(文件),
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
定义名为stdout的输出端的layout是哪种类型,可以是
org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
log4j.appender.stdout.layout.ConversionPattern= [QC] %p [%t] %C.%M(%L) | %m%n
使用pattern布局就要指定的打印信息的具体格式ConversionPattern,打印参数如下:
%m 输出代码中指定的消息;
%M 输出打印该条日志的方法名;
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL;
%r 输出自应用启动到输出该log信息耗费的毫秒数;
%c 输出所属的类目,通常就是所在类的全名;
%t 输出产生该日志事件的线程名;
%n 输出一个回车换行符,Windows平台为"rn”,Unix平台为"n”;
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy-MM-dd HH:mm:ss,SSS},输出类似:2002-10-18 22:10:28,921;
%l 输出日志事件的发生位置,及在代码中的行数;
[QC]是log信息的开头,可以为任意字符,一般为项目简称
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
定义名为R的输出端的类型为每天产生一个日志文件。
log4j.appender.R.File=D:\Tomcat 5.5\logs\qc.log
定义名为R的输出端的文件名为E:\tools\log\qc.log可以自行修改。
log4j.appender.R.layout=org.apache.log4j.PatternLayout
使用pattern布局就要指定的打印信息的具体格式ConversionPattern
log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
%m 输出代码中指定的消息;
%M 输出打印该条日志的方法名;
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL;
%r 输出自应用启动到输出该log信息耗费的毫秒数;
%c 输出所属的类目,通常就是所在类的全名;
%t 输出产生该日志事件的线程名;
%n 输出一个回车换行符,Windows平台为"rn”,Unix平台为"n”;
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy-MM-dd HH:mm:ss,SSS},输出类似:2002-10-18 22:10:28,921;
%l 输出日志事件的发生位置,及在代码中的行数;
3、定义接口
package org.zhouym.dao;
import java.util.List;
import com.zhouym.javabean.User;
public interface IUserDao {
public List<User> query();
public int addUser(User user);
public int updateUser(User user);
public int deleteById(Integer id);
public List<User> queryById(Integer id);
}
4、创建一个以接口命名的xml文件
这里注意的是文件中的id要与接口中的方法名要一致
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 利用接口实现,namespace必须为接口的全路径 -->
<mapper namespace="org.zhouym.dao.IUserDao">
<!-- 将数据库查询的结果保存到对象中 -->
<select id="query" resultType="com.zhouym.javabean.User">
<!-- 书写sql语句,没有分号 -->
select * from tb_user
</select>
<!-- 增加数据 -->
<insert id="addUser" parameterType="com.zhouym.javabean.User">
insert into tb_user(name,age,address,hobby) values(#{name},#{age},#{address},#{hobby})
</insert>
<!-- 修改数据 -->
<update id="update" parameterType="com.zhouym.javabean.User">
update tb_user set name=#{name},age=#{age},address=#{address} where id=#{id}
</update>
<!-- 删除数据 -->
<delete id="delete" parameterType="int">
delete from tb_user where id=#{id}
</delete>
</mapper>
mybatis.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入数据库信息的配置文件 -->
<properties resource="db.properties"></properties>
<!-- 引入类型处理器 -->
<typeHandlers>
<typeHandler handler="org.zhouym.typehandlers.MyTypeHandler"></typeHandler>
</typeHandlers>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<!-- 配置数据源信息 -->
<dataSource type="POOLED">
<!-- 引入配置文件中的内容 -->
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- 与映射文件建立联系 -->
<mappers>
<!-- 这里注意的是,资源路径是映射文件的地址,不能以点分隔 -->
<mapper resource="org/zhouym/dao/IUserDao.xml" />
</mappers>
</configuration>
工具类
package org.zhouym.dbutils;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class DButils {
private static InputStream in;
private static SqlSessionFactory factory = null;
public static SqlSessionFactory getSqlSessionFactory() {
try {
in = Resources.getResourceAsStream("mybaties-config.xml");
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
return factory;
}
}
使用动态代理进行数据操作
package com.zhouym.junit;
import static org.junit.Assert.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.zhouym.dao.IUserDao;
import org.zhouym.dbutils.DButils;
import com.zhouym.javabean.User;
public class InterfaceJunitTest {
@Test
public void test() {
IUserDao proxy = (IUserDao)Proxy.newProxyInstance(IUserDao.class.getClassLoader(), new Class[] {IUserDao.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
SqlSession sqlSession = DButils.getSqlSessionFactory().openSession();
String methodName = method.getName();
String classPath = IUserDao.class.getName();
String statement = classPath+"."+methodName;
if (methodName.contains("query")) {
return sqlSession.selectList(statement, args);
}else if (methodName.contains("addUser")) {
return sqlSession.insert(statement, args);
}else if (methodName.contains("updateUser")) {
return sqlSession.update(statement, args);
}else if (methodName.contains("deleteById")) {
return sqlSession.delete(statement, args);
}else if (methodName.contains("queryById")) {
return sqlSession.selectList(statement, args);
}
return null;
}
});
//查询数据
List<User> list = proxy.query();
for (User user : list) {
System.out.println(user);
}
}
}
测试类
package com.zhouym.junit;
import java.util.ArrayList;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.zhouym.dao.IUserDao;
import org.zhouym.dbutils.DButils;
import com.zhouym.javabean.User;
public class JunitTestInterface {
private static Logger logger = Logger.getLogger(JunitTestInterface.class);
@Test
public void test() {
SqlSessionFactory factory = DButils.getSqlSessionFactory();
SqlSession sqlSession = factory.openSession();
//获取的IUserDao的实现 其实就是一个代理类
IUserDao iUserDao = sqlSession.getMapper(IUserDao.class);
//调用接口中的方法
List<User> list = iUserDao.query();
for (User user : list) {
logger.info(user);
}
}
@Test
public void test1() {
SqlSessionFactory factory = DButils.getSqlSessionFactory();
SqlSession sqlSession = factory.openSession();
//获取的IUserDao的实现 其实就是一个代理类
IUserDao iUserDao = sqlSession.getMapper(IUserDao.class);
User user = new User();
user.setName("老胡");
user.setAge(28);
user.setAddress("河南");
List<String> list = new ArrayList<>();
list.add("篮球");
list.add("跑步");
list.add("游泳");
user.setHobby(list);
int result = iUserDao.addUser(user);
if (result > 0) {
logger.info("增加成功!!!");
}
sqlSession.commit();
}
}
测试结果
注意点:
1、映射文件中的namespace的值必须是接口的全路径,例如:org.zhouym.dao.IUserDao
2、接口中的方法名在映射文件中必须要有一个id与之对应,意思就是id值与方法名相同
3、映射文件的名称与接口的名称一致