??xml version="1.0" encoding="utf-8" standalone="yes"?>
http://fd.itedu-g.cn/login.php
]]>
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 用户数据库访问的c?br /> *@作者Administrator
*@createTime 2011-12-5 上午11:55:18
*@version 1.0
*/
public class DButil1 {
private Connection conn;
private Statement st;
private PreparedStatement pps;
private ResultSet rs;
public String url="jdbc:oracle:thin:@localhost:1521:orcl";
private String user="hyl";
private String password="hyl";
//加蝲驱动、放在静态代码块中,保证驱动在整个项目中只加载一ơ,提高效率
static{
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取q接的方?br /> * @return Connection 一个有效的数据库连?br /> */
public Connection getConnection()
{
try {
//注意链接Ӟ要换成自q数据库名Q数据库用户名及密码
Connection con=DriverManager.getConnection(url,user,password);
return con;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 用于执行更新的方?包括Qinsert delete updateQ操?br /> * @param sql String cd的SQL语句
* @return Integer 表示受媄响的行数
*/
public int update(String sql)
{
//定义变量用来判断更新操作是否成功Q如果返?1说明没有影响到更新操作的数据库记录条敎ͼx新操作失?br /> int row=-1;
try {
//如果数据库链接被关闭了,p既得一个新的链?br /> if(conn==null||conn.isClosed()){
conn=getConnection();
}
//使用Connection对象conn的createStatement()创徏StatementQ数据库语句对象Qst
st=conn.createStatement();
//执行更新操作Q返回媄响的记录条数row
row=st.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}
finally{
close();
}
return row;
}
/**
* ZPreparedStatement的修Ҏ?PreparedStatement:表示预编译的 SQL 语句的对?br /> * @param sql String cd的SQL语句Qinsert delete updateQ?br /> * @param obj 存放动态参数的数组
* @return Integer 表示受媄响的行数
*/
public int update(String sql,Object ...obj)
{
try {
//获取链接
if(conn==null||conn.isClosed()){
conn=getConnection();
}
//创徏预编译的 SQL 语句对象
pps=conn.prepareStatement(sql);
//定义变量length代表数组长度Q也是预处理的sql语句中的参数个数
int length=0;
//ParameterMetaDataQ用于获取关?PreparedStatement 对象中每个参数的cd和属性信息的对象
ParameterMetaData pmd=pps.getParameterMetaData();
length=pmd.getParameterCount();
//循环sql语句中的?讄为obj数组中对应的|注意?开始,所以i要加1
for(int i=0;i<length;i++)
{
pps.setObject(i+1, obj[i]);
}
//执行更新操作
return pps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
close();
}
return -1;
}
/**
* 获取一条记录的ҎQ要依赖于下面的queryToListҎQ注意泛型的使用
* @param sql
* @return Map<String,Object>
*/
public Map<String,Object> getOneRow(String sql)
{
//执行下面的queryToListҎ
List<Map<String,Object>> list=queryToList(sql);
//三目q算Q查询结果list不ؓI回list中第一个对?否则q回null
return list.size()>0?list.get(0):null;
}
/**
* q回查询l果列表QŞ如:[{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}, {TEST_NAME=bbb, TEST_NO=3, TEST_PWD=bbb}...]
* @param sql
* @return List<Map<String,Object>>
*/
public List<Map<String,Object>> queryToList(String sql)
{
//创徏集合列表用以保存所有查询到的记?br /> List<Map<String, Object>> list=new LinkedList<Map<String, Object>>();
try {
if(conn==null||conn.isClosed()){
conn=getConnection();
}
st=conn.createStatement();
rs=st.executeQuery(sql);
//ResultSetMetaData 是结果集元数据,可获取关?ResultSet 对象中列的类型和属性信息的对象 例如Q结果集中共包括多少列,每列的名U和cd{信?br /> ResultSetMetaData rsmd=rs.getMetaData();
//获取l果集中的列?br /> int columncount=rsmd.getColumnCount();
//while条g成立表明l果集中存在数据
while(rs.next())
{
//创徏一个HashMap用于存储一条数?br /> HashMap<String, Object> onerow=new HashMap<String, Object>();
//循环获取l果集中的列名及列名所对应的|每次循环都得C个对象,形如Q{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}
for(int i=0;i<columncount;i++)
{
//获取指定列的名称Q注意orcle中列名的大小?br /> String columnName=rsmd.getColumnName(i+1);
onerow.put(columnName, rs.getObject(i+1));
}
//获取到的对象onewrow={TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}攑ֈ集合列表?br /> list.add(onerow);
}
}catch (SQLException e) {
e.printStackTrace();
}
finally{
close();
}
return list;
}
/**
* q回查询l果列表,使用的是预编lSQL 语句对象PreparedStatement
* 形如Q[{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}, {TEST_NAME=bbb, TEST_NO=3, TEST_PWD=bbb}]
* @param sql
* @param paramValues
* @return List<Map<String,Object>>
*/
public List<Map<String,Object>> queryWithParam(String sql,Object ...paramValues){
//创徏集合列表用以保存所有查询到的记?br /> List<Map<String, Object>> list=new LinkedList<Map<String, Object>>();
try {
if(conn==null||conn.isClosed()){
conn=getConnection();
}
pps = conn.prepareStatement(sql);
for (int i = 0; i < paramValues.length; i++) {
pps.setObject(i + 1, paramValues[i]);
}
rs = pps.executeQuery();
//ResultSetMetaData 是结果集元数据,可获取关?ResultSet 对象中列的类型和属性信息的对象 例如Q结果集中共包括多少列,每列的名U和cd{信?br /> ResultSetMetaData rsmd=rs.getMetaData();
//获取l果集中的列?br /> int columncount=rsmd.getColumnCount();
//while条g成立表明l果集中存在数据
while (rs.next()) {
//创徏一个HashMap用于存储一条数?br /> HashMap<String, Object> onerow=new HashMap<String, Object>();
//循环获取l果集中的列名及列名所对应的|每次循环都得C个对象,形如Q{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}
for(int i=0;i<columncount;i++)
{
//获取指定列的名称Q注意orcle中列名的大小?br /> String columnName=rsmd.getColumnName(i+1);
onerow.put(columnName, rs.getObject(i+1));
}
//获取到的对象onewrow={TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}攑ֈ集合列表?br /> list.add(onerow);
}
}catch (SQLException e) {
e.printStackTrace();
}
finally{
close();
}
return list;
}
/**
* 实现oracle分页功能
* @param sql
* @param pagesize
* @param pagenow
* @return PageBean
*/
public PageBean getPage(String sql,int pagesize,int pagenow)
{
PageBean pb=new PageBean();
int end=pagenow*pagesize;
int start=end-pagesize+1;
String exesql="select a.* from (select t.*,rownum as rowindex from ("+sql+") t where rownum<="+end+" ) a where a.rowindex>="+start;
String countsql="select count(*) as rowcount from ("+sql+")";
pb.setResult(queryToList(exesql));
pb.setPagenow(pagenow);
pb.setPagesize(pagesize);
Map<String,Object> map=this.getOneRow(countsql);
int rows=Integer.parseInt(map.get("ROWCOUNT").toString());
pb.setRows(rows);
int pages=rows%pagesize==0?rows/pagesize:rows/pagesize+1;
pb.setPages(pages);
pb.setSql(sql);
return pb;
}
/**
* 关闭数据库各U资源Connection Statement PreparedStatement ResultSet的方?br /> */
private void close()
{
if(rs!=null)
{
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null)
{
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(pps!=null){
try {
pps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
try {
if(conn!=null&&!conn.isClosed())
{
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Ҏ二、可以用服务器环境变量
log4j的配|文件支持服务器的vm的环境变量,格式cM${catalina.home}
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.home}/logs/logs_tomcat.log
log4j.appender.R.MaxFileSize=10KB
其中?{catalina.home}qwindowspȝ的环境变量,q个环境变量׃需要在Windowspȝ的环境变量中讄。之所以这P你可以看看tomcat\bin\catalina.bat(startup,shutdown都是调用q个)里面自带?Dcatalina.home= "%CATALINA_HOME%" 。承这个思想Q所以你也可以自p定一个参?Dmylog.home="D:/abc/log"到对应的服务器java启动的vm参数?
Ҏ三、通过servlet初始化init()Ҏ中加载file属性实现相对\?
具体实现:做一个servlet,在系l加载的时?把properties的文件读C个properties文g?那个file的属性?我用的是相对目?Ҏ(前面加上pȝ的根目录),让后把这个properties对象讄到propertyConfig中去,q样初始化了log的设|?在后面的使用中就用不着再配|了
一般在我们开发项目过E中,log4j日志输出路径固定到某个文件夹,q样如果我换一个环?日志路径又需要重C?比较不方?目前我采用了动态改变日志\径方法来实现相对路径保存日志文g
(1).在项目启动时,装入初始化类:
public class Log4jInit extends HttpServlet {
static Logger logger = Logger.getLogger(Log4jInit.class);
public Log4jInit() {
}
public void init(ServletConfig config) throws ServletException {
String prefix = config.getServletContext().getRealPath("/");
String file = config.getInitParameter("log4j");
String filePath = prefix + file;
Properties props = new Properties();
try {
FileInputStream istream = new FileInputStream(filePath);
props.load(istream);
istream.close();
//toPrint(props.getProperty("log4j.appender.file.File"));
String logFile = prefix + props.getProperty("log4j.appender.file.File");//讄路径
props.setProperty("log4j.appender.file.File",logFile);
PropertyConfigurator.configure(props);//装入log4j配置信息
} catch (IOException e) {
toPrint("Could not read configuration file [" + filePath + "].");
toPrint("Ignoring configuration file [" + filePath + "].");
return;
}
}
public static void toPrint(String content) {
System.out.println(content);
}
}
实际上log4j的配|文件log4j.properties如ؓ默认名,可放|在JVM能读到的classpath里的L地方Q一般是攑֜WEB- INF/classes目录下。当log4j的配|文件不再是默认名,则需要另外加载ƈl出参数Q如?“ropertyConfigurator.configure(props);//装入log4j配置信息”
(2).Web.xml中的配置
<servlet>
<servlet-name>log4j-init</servlet-name>
<servlet-class>Log4jInit</servlet-class>
<init-param>
<param-name>log4j</param-name>
<param-value>WEB-INF/classes/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
注意Q上面的load-on-startup设ؓ0Q以便在Web容器启动时即装入该Servlet。log4j.properties文g攑֜根的properties子目录中Q也可以把它攑֜其它目录中。应该把.properties文g集中存放Q这h便管理?
(3).log4j.properties中即可配|log4j.appender.file.File为当前应用的相对路径.
以上是网上log4j日志文g的相对\径配|的三种ҎQ我能找到的׃U)Q分析:
Ҏ一主要是扩展了log4j的RollingFileAppenderc,其他的FileAppender同样道理。扩展的ҎQ就是用一个子cd覆盖setFileҎQ这个方法在log4jd配置文g生成appender的时候调用,传入的就是配
|文件中的\径,q样我就可以按照自己的想法在路径前面加上根\径了。这U方法可以在log4j.properties中用相对路径自由配置log4j.appender.A1.File属性来军_生成的日志相对web应用?
目录的位|?
Ҏ二是利用服务器vm中已l存在的环境变量?{catalina.home}来设|相对于${catalina.home}的日志\径,日志只能攑ֈ服务器子目录里,而且如果是用的其它服务器Q则要改对应的环境变量。此Ҏq_UL不方ѝ?
Ҏ三是扩展ActionServletc,覆盖其init()ҎQ新Ҏ中蝲入log4j.properties位置的参敎ͼ可以自由配置log4j的配|文件的名字和存放位|。也可自由配|log4j日志文g的相对于当前应用的\径。详
l代码如下:
E序代码
package wbb.bysxxglxt.util;
import org.apache.struts.action.*;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import javax.servlet.ServletException;
import java.util.Properties;
import java.io.InputStream;
import org.apache.log4j.PropertyConfigurator;
import java.io.FileInputStream;
import java.io.IOException;
public class ExtendedActionServlet extends ActionServlet {
private Log log = LogFactory.getLog(this.getClass().getName());
public ExtendedActionServlet() {}
public void init() throws ServletException {
log.info(
"Initializing, My MyActionServlet init this System's Const Variable");
String prefix = this.getServletConfig().getServletContext().getRealPath(
"/");
String file = this.getServletConfig().getInitParameter("log4j");
String filePath = prefix + file;
Properties props = new Properties();
System.out.println(prefix);
System.out.println(file);
System.out.println(filePath);
try {
FileInputStream log4jStream = new FileInputStream(filePath);
props.load(log4jStream);
log4jStream.close();
String logFile = prefix +
props.getProperty("log4j.appender.A1.File"); //讄路径
System.out.println(logFile);
props.setProperty("log4j.appender.A1.File", logFile);
PropertyConfigurator.configure(props); //装入log4j配置信息
} catch (IOException e) {
e.printStackTrace();
}
log.info("Initializing, end My Init");
super.init();//应用了struts,此方法不能省QActionServlet覆盖了的此方法中有很多重要操?
}
}
**********************应用web.xml 关键部分***************************
E序代码
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>wbb.bysxxglxt.util.ExtendedActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>log4j</param-name>
<param-value>properties\log4j.properties</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>application</param-name>
<param-value>ApplicationResources</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
注意log4j参数中相对\径的斜杠U的写法Q而且log4j属性文件如攄在web-inf/classes目录或web-inf{目录中最好改名,因ؓ在加载此Servlet之前Q服务器如tomcat启动时会自动搜烦web-inf目录和web-inf/classes目录中log4j.properties文gQ如有则自动加蝲。log4j属性文件加载后,׃该属性文件中log4j.appender.A1.File的值用的是相对路径Q自动加载配|便会出错:
log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: WEB-INF\logs\bysxxglxt.log (pȝ找不到指定的路径?
不知道log4jZ么会q么早自动启动。尽后面加载扩展的ActionServlet中正设|了log4j属性文件ƈ正常加蝲了,但报的这个错q是怪不爽的Q于是只有更改log4j属性文件名字或者更改其存放位置Q让其不能自动加载了Q不q还是有两个警告Q?
log4j:WARN No appenders could be found for logger (org.apache.commons.digester.Digester.sax).
log4j:WARN Please initialize the log4j system properly.
q样做就是掩耳盗铃了Q如果你有更好的解决办法Q希望能在此贴出来,大家一LI?
********************log4j.properties*****************************
### 讄loggerU别 ###
E序代码
log4j.rootLogger=DEBUG,stdout,A1
### appender.stdout输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= [%5p] [BYSXXGLXT] %d{yyyy-MM-dd HH:mm:ss}: %-4r [%-5p] [%t] ( %F,%L ) - %m%n
### appender.A1输出到日志文?###
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=WEB-INF\\logs\\bysxxglxt.log
##注意上面日志文g相对应用根目录\径的写法
log4j.appender.A1.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.A1.Append=true
## 输出DEBUGU别以上的日?
log4j.appender.A1.Threshold=DEBUG
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern= [%5p] [BYSXXGLXT] %d{yyyy-MM-dd HH:mm:ss}: %-4r [%t] ( %F,%L ) - %m%n
在src下编??properties文g
1.log4j.properties 下面是内?/p>
##LOGGERS
#define a logger
log4j.rootLogger=INFO,console,file
##APPENDERS
#define an appender named console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#define an appender named file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=d:/demo_log.txt
#set the log's size
log4j.appender.file.MaxFileSize=1000KB
log4j.appender.file.MaxBackupIndex=20
##LAYOUTS
#assign a SimpleLayout to console appender
log4j.appender.console.layout=org.apache.log4j.SimpleLayout
#assign a PatternLayout to file appender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH:mm:ss}]%m%n
2.
simplelog.properties下面是内?/p>
log.apache.commons.logging.simplelog.defaultlog=info
3.
commons-logging.properties下面是内?/p>
##set Log as Log4J
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
一、什么是log4j
Log4j 是Apache的一个开放源代码目Q通过使用Log4jQ我们可以控制日志信息输送的目的地是控制台、文件、GUIlg、甚x套接口服务器、NT的事件记录器、UNIX Syslog守护q程{;我们也可以控制每一条日志的输出格式Q通过定义每一条日志信息的U别Q我们能够更加细致地控制日志的生成过E。最令h感兴的是Q这些可以通过一个配|文件来灉|地进行配|,而不需要修改应用的代码?
二、日志简?br />日志指在E序中插入语句以提供调试信息。用日志能够监视程序的执行。例如,用户利用日志可以获得关于应用E序故障的完整信息。用户可以将调试语句Q如 System.out.printlnQ插入到E序中以获得详细的调试信息?
三、项目中Z么要用log4j
大家在编E时l常不可避免地要使用C些日志操作,比如开发阶D늚调试信息、运行时的日志记录及审计。调查显C,日志代码占代码总量?Q。通常大家可以单地使用System.out.println()语句输出日志信息Q但是往往会有一些判断,比如Q?
if (someCondition)
{
System.out.println("some information.");
}
q些判断造成正常的程序逻辑中杂了大量的输句。而在开发阶D写下的q些判断仅ؓ了调试的语句Q在开发完成时需要查扑ƈU除。部|运行后Q尤其是在一些企业应用系l中Q还l常需要进一步调试,q时遇C更大的麻烦。所以,我们需要一套完备的、灵zȝ、可配置的日志工具log4J是优秀的选择?
四、log4jlg
Log4j ?logger、appender ?layout 三个lgl成。可以通过同名?Java c访?Log4j 的这三个lg?/font>
Logger - 在执行应用程序时Q接收日志语句生成的日志h。它是一U重要的日志处理lgQ?可以通过 log4j API ?logger cd其进行访问。它的方法有Qdebug、info、warn、error、fatal ?log。这些方法用于记录消息?
Appender - 理日志语句的输出结果。执行日志语句时QLogger 对象接收来自日志语句的记录h。此h是通过 logger 发送至 appender 的。然后,Appender 输出结果写入到用户选择的目的地。对于不同的日志目的圎ͼ提供不同?appender cd。这?appender 包括Q用于文件的 file appender、用于数据库?JDBC appender 和用?SMTP 服务器的 SMTP appender?
Layout - 用于指定 appender 日志语句写入日志目的地所采用的格式。appender 可以用来格式化输出结果的各种布局包括Q简单布局、模式布局?HTML 布局?/font>