灵魂腐蚀 发表于 2015-1-18 11:11:38

JAVA网页设计怎样给 Log4j 配上数据库毗连池

主要缺点就是:速度比较慢,没有C和C++快数据|数据库|数据库毗连  我们都晓得log4j是一个优异的开源日记纪录项目,我们不但能够对输入的日记的格局自界说,还能够本人界说日记输入的目标地,好比:屏幕,文本文件,数据库,乃至能经由过程socket输入。
  
  如今让我们对日记输入到数据库来举行设置
  
  设置以下:
  
  #---JDBC---输入到数据库
  #JDBCAppenderlog4j.propertiesfile
  #log4j.rootCategory=WARN,JDBC
  #APPENDERJDBC
  log4j.appender.JDBC=org.apache.log4j.jdbc.JDBCAppender
  log4j.appender.JDBC.driver=com.mysql.jdbc.Driver
  log4j.appender.JDBC.URL=jdbc:mysql://localhost:3306/test
  log4j.appender.JDBC.user=use
  log4j.appender.JDBC.password=password
  log4j.appender.JDBC.layout=org.apache.log4j.PatternLayout
  log4j.appender.JDBC.sql=INSERTINTOLOGGING(log_date,log_level,location,message)VALUES(%d{ISO8601},%-5p,%C,%L,%m)
  
  表布局以下:
  
  log_date varchar2(50)
  log_level varchar2(5)
  location varchar2(100)
  message  varchar2(1000)
  
  笔者照做,但没有运转乐成,并且此种办法是使用传统的数据库毗连办法,关于数据库的办理和效力严峻不敷,在如今这个毗连池横行的时期,为何我们不克不及给给Log4j配上毗连池,让Log4j使用数据毗连池的毗连和数据库举行通信。现检察Log4j的Api,发明JDBCAppender这个类有以下几段话:WARNING:ThisversionofJDBCAppenderisverylikelytobecompletelyreplacedinthefuture.Moreoever,itdoesnotlogexceptions.TheJDBCAppenderprovidesforsendinglogeventstoadatabase.
  
  Foruseasabaseclass:
  
  OverridegetConnection()topassanyconnectionyouwant.Typicallythisisusedtoenableapplicationwideconnectionpooling.
  OverridecloseConnection(Connectioncon)--ifyouoverridegetConnectionmakesuretoimplementcloseConnectiontohandletheconnectionyougenerated.Typicallythiswouldreturntheconnectiontothepoolitcamefrom.
  OverridegetLogStatement(LoggingEventevent)toproducespecializedordynamicstatements.Thedefaultusesthesqloptionvalue.
  
  本来log4j倡议我们把其供应的JDBCAppender作为基类来利用,然后Override三个父类的办法:getConnection(),closeConnection(Connectioncon)和getLogStatement(LoggingEventevent)。
  
  本来云云,那就写一个子类JDBCPoolAppender来替换这个JDBCAppender
  
  JDBCPoolAppender代码和其相干代码以下:
  
  JDBCPoolAppender.java:
  
  packagecommon.log;
  importjava.sql.Connection;
  importorg.apache.log4j.spi.LoggingEvent;
  importjava.sql.SQLException;
  importjava.sql.Statement;
  importjava.util.Iterator;
  importorg.apache.log4j.spi.ErrorCode;
  importorg.apache.log4j.PatternLayout;
  importcommon.sql.MyDB;
  importcommon.sql.GeneralDb;
  
  publicclassJDBCPoolAppenderextendsorg.apache.log4j.jdbc.JDBCAppender{
  
  privateMyDBmydb=null;
  protectedStringsqlname="";//增添一个数据库jndiName的属性
  
  protectedConnectionconnection=null;
  protectedStringsqlStatement="";
  /**
  *sizeofLoggingEventbufferbeforewrittingtothedatabase.
  *Defaultis1.
  */
  protectedintbufferSize=1;
  
  publicJDBCPoolAppender(){
  super();
  }
  
  /**
  *ArrayListholdingthebufferofLoggingEvents.
  */
  publicvoidappend(LoggingEventevent){
  buffer.add(event);
  if(buffer.size()>=bufferSize)
  flushBuffer();
  }
  
  /**
  *BydefaultgetLogStatementsendstheeventtotherequiredLayoutobject.
  *ThelayoutwillformatthegivenpatternintoaworkableSQLstring.
  *
  *OverridingthisprovidesdirectaccesstotheLoggingEvent
  *whenconstructingtheloggingstatement.
  *
  */
  protectedStringgetLogStatement(LoggingEventevent){
  returngetLayout().format(event);
  }
  
  /**
  *
  *Overridethistoprovideanalertnatemethodofgetting
  *connections(suchascaching). Onemethodtofixthisistoopen
  *connectionsatthestartofflushBuffer()andclosethematthe
  *end. IuseaconnectionpooloutsideofJDBCAppenderwhichis
  *accessedinanoverrideofthismethod.
  **/
  protectedvoidexecute(Stringsql)throwsSQLException{
  Connectioncon=null;
  Statementstmt=null;
  try{
  con=getConnection();
  stmt=con.createStatement();
  stmt.executeUpdate(sql);
  }catch(SQLExceptione){
  if(stmt!=null)
  stmt.close();
  throwe;
  }
  stmt.close();
  closeConnection(con);
  //System.out.println("Execute:"+sql);
  }
  
  /**
  *Overridethistoreturntheconnectiontoapool,ortocleanupthe
  *resource.
  *
  *Thedefaultbehaviorholdsasingleconnectionopenuntiltheappender
  *isclosed(typicallywhengarbagecollected).
  */
  protectedvoidcloseConnection(Connectioncon){
  mydb=null;
  try{
  if(connection!=null&&!connection.isClosed())
  connection.close();
  }catch(SQLExceptione){
  errorHandler.error("Errorclosingconnection",e,
  ErrorCode.GENERIC_FAILURE);
  }
  
  }
  
  /**
  *Override此函数来使用毗连池前往一个Connetion对象
  *
  */
  protectedConnectiongetConnection()throwsSQLException{
  try{
  mydb=GeneralDb.getInstance(sqlname);
  connection=mydb.getConnection();
  }catch(Exceptione){
  errorHandler.error("Erroropeningconnection",e,ErrorCode.GENERIC_FAILURE);
  }
  returnconnection;
  }
  
  /**
  *Closestheappender,flushingthebufferfirstthenclosingthedefault
  *connectionifitisopen.
  */
  publicvoidclose(){
  flushBuffer();
  
  try{
  if(connection!=null&&!connection.isClosed())
  connection.close();
  }catch(SQLExceptione){
  errorHandler.error("Errorclosingconnection",e,
  ErrorCode.GENERIC_FAILURE);
  }
  this.closed=true;
  }
  
  /**
  *loopsthroughthebufferofLoggingEvents,getsa
  *sqlstringfromgetLogStatement()andsendsittoexecute().
  *ErrorsaresenttotheerrorHandler.
  *
  *IfastatementfailstheLoggingEventstaysinthebuffer!
  */
  publicvoidflushBuffer(){
  //Dotheactuallogging
  removes.ensureCapacity(buffer.size());
  for(Iteratori=buffer.iterator();i.hasNext();){
  try{
  LoggingEventlogEvent=(LoggingEvent)i.next();
  Stringsql=getLogStatement(logEvent);
  execute(sql);
  removes.add(logEvent);
  }catch(SQLExceptione){
  errorHandler.error("Failedtoexcutesql",e,
  ErrorCode.FLUSH_FAILURE);
  }
  }
  
  //removefromthebufferanyeventsthatwerereported
  buffer.removeAll(removes);
  
  //clearthebufferofreportedevents
  removes.clear();
  }
  
  /**closestheappenderbeforedisposal*/
  publicvoidfinalize(){
  close();
  }
  
  /**
  *JDBCAppenderrequiresalayout.
  **/
  publicbooleanrequiresLayout(){
  returntrue;
  }
  
  /**
  *
  */
  publicvoidsetSql(Strings){
  sqlStatement=s;
  if(getLayout()==null){
  this.setLayout(newPatternLayout(s));
  }else{
  ((PatternLayout)getLayout()).setConversionPattern(s);
  }
  }
  
  /**
  *Returnspre-formatedstatementeg:insertintoLogTable(msg)values("%m")
  */
  publicStringgetSql(){
  returnsqlStatement;
  }
  
  publicvoidsetSqlname(Stringsqlname){
  sqlname=sqlname;
  }
  
  publicStringgetSqlname(){
  returnsqlname;
  }
  
  publicvoidsetBufferSize(intnewBufferSize){
  bufferSize=newBufferSize;
  buffer.ensureCapacity(bufferSize);
  removes.ensureCapacity(bufferSize);
  }
  
  publicintgetBufferSize(){
  returnbufferSize;
  }
  }
  
  MyDB.java:
  packagecommon.sql;
  importjava.sql.*;
  importcom.codestudio.sql.*; //引进开源项目Poolman数据库毗连池的包
  
  publicclassMyDB{
  publicstaticfinalStringmodule=MyDB.class.getName();
  privateStringdbName="";
  privatePoolManplmn=null;
  
  publicMyDB(StringdbName){
  try{
  if(plmn==null){
  plmn=(PoolMan)Class.forName("com.codestudio.sql.PoolMan").
  newInstance();
  }
  }catch(Exceptionec){
  System.out.println(ec.toString()+module);
  }
  this.dbName=dbName;
  }
  
  privateConnectiongetNewConnection(){
  Connectionconn=null;
  try{
  conn=plmn.connect("jdbc:poolman://"+dbName);
  conn.setAutoCommit(true);
  }catch(Exceptionec){
  System.out.println(ec.toString()+"First:Connectsqlseverfailed"+module);
  try{
  Thread.sleep(1000);
  conn=plmn.connect("jdbc:poolman://"+dbName);
  conn.setAutoCommit(true);
  }catch(Exceptionecs){
  System.out.println(ecs.toString()+"Again:Connectsqlseverfaile"+module);
  }
  }
  returnconn;
  }
  
  publicConnectiongetConnection(){
  returngetNewConnection();
  }
  }
  GeneralDb.java:
  
  packagecommon.sql;
  
  packagecommon.sql;
  importjava.util.*;
  
  publicclassGeneralDb{
  privatestaticHashtabledbPool;
  publicstaticMyDBgetInstance(Stringdbname){
  if(dbPool==null){
  dbPool=newHashtable();
  }
  MyDBdb=(MyDB)dbPool.get(dbname);
  if(db==null){
  db=newMyDB(dbname);
  dbPool.put(dbname,db);
  }
  returndb;
  }
  }
  
  Log4j数据库毗连池的设置以下:
  log4j.appender.JDBC=common.log.JDBCPoolAppender
  log4j.appender.JDBC.sqlname=log
  log4j.appender.JDBC.layout=org.apache.log4j.PatternLayout
  log4j.appender.JDBC.sql=INSERTINTOLOGGING(log_date,log_level,location,message)VALUES(%d{ISO8601},%-5p,%C,%L,%m)
  
  poolman.xml设置以下:
  
  〈?xmlversion="1.0"encoding="UTF-8"?>
  〈poolman>
  〈management-mode>local〈/management-mode>
  〈datasource>
  〈dbname>log〈/dbname>
  〈jndiName>log〈/jndiName>
  〈driver>com.mysql.jdbc.Driver〈/driver>
  〈url>jdbc:mysql://localhost:3306/test〈/url>
  〈username>use〈/username>
  〈password>password〈/password>
  〈minimumSize>0〈/minimumSize>
  〈maximumSize>10〈/maximumSize>
  〈logFile>logs/mysql.log〈/logFile>
  〈/datasource>
  
  〈/poolman>
  
  运转乐成!关于JDBCPoolAppender的属性(好比sqlname属性)我们能够使用Log4j的反射机制任意增加,只需在设置文件给其附上值便可使用,而本来的父类内里的一些属性(username甚么的)和其get,set办法因为在毗连池中不必要,以是删除。而在JDBCPoolAppender类中,我也只是将getConnection办法Override,在这个办法中我们能够依据必要天生我们的Connection对象,别的两个办法人人能够依据需求来决意如何Override。:)
还得说上一点,就java本质而言,是面相对象的,但是你有没有发现,java也不全是,比如说基本类型,int,那他就是整型而不是对象,转换类型是还得借助包装类。

愤怒的大鸟 发表于 2015-1-20 14:40:48

你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。

活着的死人 发表于 2015-1-29 09:39:37

J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。

若相依 发表于 2015-2-6 00:14:27

设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧

柔情似水 发表于 2015-2-19 20:19:24

还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。

海妖 发表于 2015-3-6 15:21:27

是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言

山那边是海 发表于 2015-3-6 15:21:27

其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。

若天明 发表于 2015-3-13 03:09:43

J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。

谁可相欹 发表于 2015-3-20 11:11:45

科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。
页: [1]
查看完整版本: JAVA网页设计怎样给 Log4j 配上数据库毗连池