最近写了一个关于将对象通过log4j的形式保存到数据库的例子,因对这个log4j正在入门,所以做之前查过很多资料,不过网上的信息比较简单,如下:
1.所有信息几乎全部在配置文件中进行获取,如:数据库相关的连接、用户名、密码、sql语句;日志相关的appender、输出、格式化、参数;
2.写到数据库中的仅是一个字符串而不是一个对象,如:将一个对象本身以及它的各个数据作为一条记录存到数据库
3.代码的灵活性较低,如:只能存比较简单的数据类型,如保存一个对象及属性的话,就不太容易做了。
当然,网上的这些资料当然是为了最基础的入门而做的,因此简单了些,但也不乏比较深奥的资料,比如穿件连接池,考虑缓存等等。。
二、我的做法
1.通过继承JDBCAppender实现日志的写入的
2.通过JDBC连接数据库(也可通过HIBERNATE)
3.数据库和log4j的基本信息配置到properties中,但数据库可以自由选择多种数据库(在配置文件中配置即可)
4.将对象的属性存到库中
三、项目例子
1.项目结构图:见附件,项目结构图.png
2. 数据库:MYSQL 库名:LOG4J 表名:LogMessage/StudentMessage
表结构请看附件:LogMessage.png/StudentMessage.png
3.代码及说明
log4j.properties:分别输出指定为:控制台、文件(log.log)、数据库
log4j.rootLogger=INFO,appender1,appender2,DATABASE # console log4j.appender.appender1=org.apache.log4j.ConsoleAppender log4j.appender.appender1.layout=org.apache.log4j.PatternLayout log4j.appender.appender1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss:SSS}[%p]: %m%n # file log4j.appender.appender2=org.apache.log4j.FileAppender log4j.appender.appender2.File=log.log log4j.appender.appender2.layout=org.apache.log4j.PatternLayout log4j.appender.appender2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss:SSS}[%p]: %m%n # mysql dbappender test log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver log4j.appender.DATABASE.URL=jdbc:mysql://192.168.199.132:3306/mind log4j.appender.DATABASE.username=root log4j.appender.DATABASE.password=root log4j.appender.DATABASE=control.DbAppender log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n %L
Conorl包——DbAppender.java:日志提交中转站,提取日志信息,处理后进行数据库操作插入对应的表中
package com.lovell.javatest.log4jtest.control; import com.lovell.javatest.log4jtest.bean.HashMapping; import com.lovell.javatest.log4jtest.dao.JdbcUtils; import com.lovell.javatest.log4jtest.dao.StudentsUtil; import com.lovell.javatest.log4jtest.dao.UserUtil; import org.apache.log4j.jdbc.JDBCAppender; import org.apache.log4j.spi.LoggingEvent; import java.sql.Connection; import java.sql.SQLException; import java.util.Hashtable; /** * 日志提交中转站,提取日志信息,处理后进行数据库操作插入对应的表中 * Created by Lovell on 26/10/2016. */ /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@ @@ @@@@@@@ @@ @@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@ @@@ @@@@ @@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@@ @ @@@@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@ @@@@@@ @@@@@@ @@ @@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */ public class DbAppender extends JDBCAppender { /** * 关闭连接 * @param con */ protected void closeConnection(Connection con) { // TODO Auto-generated method stub // super.closeConnection(con); JdbcUtils.close(con); } /** * 执行sql语句 * @param sql * @throws SQLException */ @Override protected void execute(String sql) throws SQLException { // TODO Auto-generated method stub // super.execute(arg0); int flag = 0; int end = sql.lastIndexOf(")"); String sqls = sql.substring(0, end + 1); String beanname = sql.substring(end + 1); if (beanname.equals("UserBean")) { // 如果类名为UserBean flag = UserUtil.insertUser(sqls); } else if (beanname.equals("Students")) { // 如果类名为Students flag = StudentsUtil.insertStudent(sqls); } System.out.println(flag == 0 ? "insert fail!" : "insert successful!"); } /** * 获取连接 * @return * @throws SQLException */ @Override protected Connection getConnection() throws SQLException { // TODO Auto-generated method stub // return super.getConnection(); if (connection == null) { connection = JdbcUtils.getConnection(); } return connection; } /** * 获取Log声明 * @param event * @return */ @Override protected String getLogStatement(LoggingEvent event) { // TODO Auto-generated method stub // return super.getLogStatement(event); StringBuffer sbuf = new StringBuffer(); Hashtable hm = (Hashtable) event.getMessage(); String sql = null; if ((hm.get("beanname")).equals("UserBean")) { // 如果类名为UserBean sbuf.append(UserUtil.insertSql()); sql = sbuf.toString(); int end = sql.lastIndexOf("("); sql = sql.substring(0, end) + "('" + hm.get(HashMapping.USER_TIME) + "','" + event.getMessage() + "','" + hm.get(HashMapping.USER_USERNAME) + "','" + hm.get(HashMapping.USER_PASSWORD) + "')"; System.out.println("==>" + sql); return sql + hm.get("beanname"); } else if ((hm.get("beanname")).equals("Students")) { // 如果类型为Students sbuf.append(StudentsUtil.insertSql()); sql = sbuf.toString(); int end = sql.lastIndexOf("("); sql = sql.substring(0, end) + "('" + hm.get(HashMapping.STUDENT_NAME) + "','" + hm.get(HashMapping.STUDENT_AGE) + "','" + (((Integer) (hm.get(HashMapping.STUDENT_SEX))) == 1 ? "F" : "M") + "','" + hm.get(HashMapping.STUDENT_TIME) + "')"; System.out.println("==>" + sql); return sql + hm.get("beanname"); } return sql; } }
Bean包中的类——UserBean.java/Students.java:对LogMessage/studentMessage表及此对象持久化
package com.lovell.javatest.log4jtest.bean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 对student及时对象持久化 * Created by Lovell on 26/10/2016. */ /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@ @@ @@@@@@@ @@ @@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@ @@@ @@@@ @@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@@ @ @@@@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@ @@@@@@ @@@@@@ @@ @@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */ public class Students { private static Logger logger = LoggerFactory.getLogger(Students.class); private String name; // 姓名 private int age; // 年龄 private int sex; // 性别 private String time; // 时间 public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } }
package com.lovell.javatest.log4jtest.bean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * User表及此对象持久化 * Created by Lovell on 26/10/2016. */ /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@ @@ @@@@@@@ @@ @@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@ @@@ @@@@ @@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@@ @ @@@@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@ @@@@@@ @@@@@@ @@ @@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */ public class UserBean { private static Logger logger = LoggerFactory.getLogger(UserBean.class); private String username; // 用户名称 private String password; // 用户密码 private String Time; // 时间 private String Note; // 注释 public String getTime() { return Time; } public void setTime(String time) { Time = time; } public String getNote() { return Note; } public void setNote(String note) { Note = note; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
Dao中的包——GetObject.java:将对象放到hashtable中并发送到dbappender中
package com.lovell.javatest.log4jtest.dao; import com.lovell.javatest.log4jtest.bean.Students; import com.lovell.javatest.log4jtest.bean.UserBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Hashtable; /** * 将对象放到hashtable中并发送到db appender中 * Created by Lovell on 26/10/2016. */ /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@ @@ @@@@@@@ @@ @@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@ @@@ @@@@ @@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@@ @ @@@@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@ @@@@@@ @@@@@@ @@ @@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */ public class GetObject { private static Logger logger = LoggerFactory.getLogger(GetObject.class); private UserBean ub; // 用户对象 private Students st; // 学生对象 private SimpleDateFormat sf; // 保存对象 public UserBean insertInfo(String username, String password) { ub = new UserBean(); ub.setUsername(username); // 用户名称 ub.setPassword(password); // 用户密码 return ub; } public Logger getLogger() { return logger; } public void setLogger(Logger logger) { this.logger = logger; } public UserBean getUb() { return ub; } public void setUb(UserBean ub) { this.ub = ub; } public Students getSt() { return st; } public void setSt(Students st) { this.st = st; } public SimpleDateFormat getSf() { return sf; } public void setSf(SimpleDateFormat sf) { this.sf = sf; } /** * 插入一个学生信息 * @param name * @param age * @param sex * @return */ public Students insertInfo(String name, int age, int sex) { st = new Students(); st.setName(name); st.setAge(age); st.setSex(sex); return st; } // bean key-value public void getMethod(Object obj) { // 简单的日期格式 sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); // PropertyConfigurator.configure("log4jtest.properties"); InputStream in = GetObject.class.getClass().getResourceAsStream("/log4jtest.properties"); Hashtable ht = new Hashtable(); ht.clear(); if (obj instanceof UserBean) { ht.put("username", ub.getUsername()); // 用户名 ht.put("password", ub.getPassword()); // 密码 ht.put("time", sf.format(new Date())); // 时间日期 ht.put("beanname", "UserBean"); // 类名 } else if (obj instanceof Students) { ht.put("name", st.getName()); // 姓名 ht.put("age", st.getAge()); // 年龄 ht.put("sex", st.getSex()); // 性别 ht.put("time", sf.format(new Date())); // 时间 ht.put("beanname","Students"); // 学生 } logger.info(String.valueOf(ht)); } }
Dao中的包——JdbcUtils.java:数据库的动态链接
package com.lovell.javatest.log4jtest.dao; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Iterator; import java.util.Properties; import java.util.Set; /** * JDBC数据库动态链接 * Created by Lovell on 26/10/2016. */ /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@ @@ @@@@@@@ @@ @@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@ @@@ @@@@ @@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@@ @ @@@@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@ @@@@@@ @@@@@@ @@ @@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */ public final class JdbcUtils { private static String url = null; // 地址 private static String driver = null; // 驱动器 private static String username = null; // 用户名称 private static String password = null; // 密码 private JdbcUtils() { } static{ try { getProperties(); // 获取属性 Class.forName(driver); // 驱动器 } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 获取连接 * @return * @throws SQLException */ public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } /** * 关闭 * @param conn */ public static void close(Connection conn) { try { if (conn != null) conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 获取属性 */ public static void getProperties() { Properties props = new Properties(); // FileInputStream istream = null; try { // 加载属性文件 // istream = new FileInputStream("log4j.properties"); InputStream istream = JdbcUtils.class.getClass().getResourceAsStream("/log4jtest.properties"); props.load(istream); Set s = props.keySet(); Iterator it = s.iterator(); while (it.hasNext()) { String id = (String) it.next(); String value = props.getProperty(id); if(id.equals("log4j.appender.DATABASE.driver")){ // 驱动器 driver = value; }else if(id.equals("log4j.appender.DATABASE.URL")){ // 数据库地址 url = value; }else if(id.equals("log4j.appender.DATABASE.username")){ // 用户名称 username = value; }else if(id.equals("log4j.appender.DATABASE.password")){ // 用户密码 password = value; } // System.out.println(id + ":=" + value); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // finally { // try { // istream.close(); // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // } } }
Dao中的包——StudentsUtil.java/UserUtil.java:对各自的表进行数据库的操作
package com.lovell.javatest.log4jtest.dao; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; /** * 对Student表进行数据库操作 * Created by Lovell on 26/10/2016. */ /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@ @@ @@@@@@@ @@ @@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@ @@@ @@@@ @@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@@ @ @@@@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@ @@@@@@ @@@@@@ @@ @@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */ public class StudentsUtil { public static int insertStudent(String sql) { Connection conn = null; Statement sm = null; int flag = 0; try { conn = JdbcUtils.getConnection(); sm = conn.createStatement(); sm.execute(sql); flag = 1; } catch (SQLException e) { // TODO Auto-generated catch block System.out.println("insert fail!"); } finally { if (sm != null) { try { sm.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } JdbcUtils.close(conn); // 关闭连接 } return flag; } public static String insertSql() { return "INSERT INTO StudentMessage(Name,Age,Sex,Time) values("; } }
package com.lovell.javatest.log4jtest.dao; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; /** * 对User表进行数据库操作 * Created by Lovell on 26/10/2016. */ /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@ @@ @@@@@@@ @@ @@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@ @@@ @@@@ @@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@@ @ @@@@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@ @@@@@@ @@@@@@ @@ @@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */ public class UserUtil { public static int insertUser(String sql) { Connection conn = null; Statement sm = null; int flag = 0; try { conn = JdbcUtils.getConnection(); // 获取连接 sm = conn.createStatement(); // 创建声明 sm.execute(sql); // 执行sql语句 flag = 1; } catch (SQLException e) { // TODO Auto-generated catch block System.out.println("insert fail!"); } finally { if (sm != null) { try { sm.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } JdbcUtils.close(conn); } return flag; } /** * 插入sql语句 * @return */ public static String insertSql(){ return "INSERT INTO LogMessage(Time,Note,Username,Password) values("; } }
test包——test.java:测试类
package com.lovell.javatest.log4jtest.test; import com.lovell.javatest.log4jtest.bean.UserBean; import com.lovell.javatest.log4jtest.dao.GetObject; /** * 测试类 * Created by Lovell on 26/10/2016. */ /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@ @@ @@@@@@@ @@ @@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@ @@@@@ @@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@ @@@ @@@@ @@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@@@@@@@ @@@@ @@@@@ @ @@@@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@@@ @@@@ @@ @@@@@@ @@@@@@ @@ @@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */ public class Test { public static void main(String[] args) { Test dbt = new Test(); dbt.testUser(); } public void testUser() { try { GetObject go = new GetObject(); // 获取对象接口创建 UserBean ub = go.insertInfo("EE-YY", "YY-12345"); // user中插入一行数据 go.getMethod(ub); // 将对象放到hashtable中并发送到db appender中 // Students st = go.insertInfo("YY", 21, 2); // go.getMethod(st); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
参考:http://damon-zhang.iteye.com/blog/1458929