<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    如鵬網(wǎng) 大學(xué)生計算機學(xué)習(xí)社區(qū)

    CowNew開源團隊

    http://www.cownew.com 郵件請聯(lián)系 about521 at 163.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      363 隨筆 :: 2 文章 :: 808 評論 :: 0 Trackbacks

    #

    作者楊中科

    CowNew 開源團隊網(wǎng)站 http://www.cownew.com

    論壇 http://www.cownew.com/newpeng/?

    轉(zhuǎn)載請保留此信息

    一、HQL代碼的構(gòu)建。
    (1)首先將hibernate中的src目錄下的代碼解壓。
    (2)安裝配置好antlr。
    (3)把grammar目錄下的三個.g文件(hql.g,hql-sql.g,sql-gen.g)解壓到一個目錄,然后從命令行進入此目錄,依次運行"java antlr.Tool hql.g","java antlr.Tool hql-sql.g","java antlr.Tool sql-gen.g",將生成的java代碼拷貝到源代碼的org.hibernate.hql.antlr下。
    二、讓我們從QueryTranslatorImpl開始分析,當調(diào)用session.find('...')的時候?qū){(diào)用QueryTranslatorImpl的compile方法來解析hql語句為sql語句。compile則主要是調(diào)用的doCompile方法。
    // PHASE 1 : Parse the HQL into an AST.
    HqlParser parser = parse( true );

    // PHASE 2 : Analyze the HQL AST, and produce an SQL AST.
    HqlSqlWalker w = analyze( parser, collectionRole );
    sqlAst = ( Statement ) w.getAST();
    generate( ( QueryNode ) sqlAst );
    queryLoader = new QueryLoader( this, factory, w.getSelectClause() );

    parse的主要代碼:
    private HqlParser parse(boolean filter)
    ?HqlParser parser = HqlParser.getInstance( hql );
    ?parser.statement();
    ?AST hqlAst = parser.getAST();
    ??return parser;
    }
    analyze的主要代碼:
    private HqlSqlWalker analyze(HqlParser parser, String collectionRole) throws QueryException, RecognitionException {
    ?HqlSqlWalker w = new HqlSqlWalker( this, factory, parser, tokenReplacements, collectionRole );
    ?AST hqlAst = parser.getAST();
    ?w.statement( hqlAst );
    ?return w;
    }
    generate的主要代碼:
    private void generate(AST sqlAst) throws QueryException, RecognitionException {
    ?SqlGenerator gen = new SqlGenerator(factory);
    ?gen.statement( sqlAst );
    ?sql = gen.getSQL();
    }

    可以看到主要是三步:調(diào)用parse方法將hql解析成AST,調(diào)用analyze根據(jù)上一步生成的AST生成SQLAST,調(diào)用generate根據(jù)上一步生成的SQL AST生成sql語句, 調(diào)用w.getSelectClause()就得到sql語句了。
    “用parser把ast抽取出來,再用treeparser進行動作的double pass builder模式,解耦了parser和generation,再配合template,是antlr推薦的最佳模式。”-《看Hibernate3如何解釋HQL語言》
    1、三個語法文件的作用:

    hibernate的hql grammar文件一共有三個,在/grammar目錄下:
    ?? 1.hql.g?? 定義token類和parser類,將hql解釋成hql的抽象語法樹(ast)
    ?? 2.hql-sql.g? 定義tree walker ,將hql ast轉(zhuǎn)化為sql ast,將生成模塊與hibernate解耦。
    ?? 3.sql-gen.g 定義tree walker,從sql ast生成sql
    ”-《看Hibernate3如何解釋HQL語言》
    2、
    逐步分析:
    (1)parse方法:
    HqlParser是從hql.g生成的HqlBaseParser繼承來的,主要實現(xiàn)了HqlBaseParser定義的幾個模版方法,傳入的是hql語句,傳出的是HQL AST。
    (2)analyze:
    HqlSqlWalker是從hql-sql.g生成的HqlSqlBaseWalker繼承來的,HqlSqlBaseWalker又是從TreeParser繼承的,主要實現(xiàn)了HqlSqlBaseWalker定義的幾個模版方法,傳入的是HQL AST,傳出的是SQL AST。
    hql-sql.g比hql.g簡單許多了,因為hql-sql.g已經(jīng)為我們生成了HQL AST了,hql-sql.g需要做的就是把HQL AST組裝成強類型的SQL AST,此處大量引用了hql.g中定義的Vocabulary。
    比如:
    query!
    ?: #( QUERY { beforeStatement( "select", SELECT ); }
    ???// The first phase places the FROM first to make processing the SELECT simpler.
    ???#(SELECT_FROM
    ????f:fromClause
    ????(s:selectClause)?
    ???)
    ???(w:whereClause)?
    ???(g:groupClause)?
    ???(o:orderClause)?
    ??) {
    ??// Antlr note: #x_in refers to the input AST, #x refers to the output AST
    ??#query = #([SELECT,"SELECT"], #s, #f, #w, #g, #o);
    ??beforeStatementCompletion( "select" );
    ??processQuery( #s, #query );
    ??afterStatementCompletion( "select" );
    ?}
    ?;
    這里主要就是在調(diào)用模版方法拼狀強類型的SQL AST(異構(gòu)AST)。所有的節(jié)點都定義在org.hibernate.hql.ast.tree中。
    與第一部的HqlParser用戶幾乎不用寫任何代碼相反,我們需要完成我們從HqlSqlBaseWalker繼承來的HqlSqlWalker的那些模版方法。
    (3)generate方法:
    遍歷SQL AST,輸出sql語句。SqlGenerator是從sql-gen.g生成的SqlGeneratorBase繼承來的。輸入的是SQL AST,輸出的是SQL語句。我個人認為這一步也可以通過全部書寫代碼完成,可能更清晰,更靈活。
    selectExpr
    ?: e:selectAtom { out(e); }
    ?| count
    ?| #(CONSTRUCTOR (DOT | IDENT) ( selectColumn )+ )
    ?| methodCall
    ?| aggregate
    ?| c:constant { out(c); }
    ?| arithmeticExpr
    ?| PARAM { out("?"); }
    ?| sn:SQL_NODE { out(sn); }
    ?| { out("("); } selectStatement { out(")"); }
    其中的out("(");就是在拼裝代碼。

    posted @ 2006-06-02 00:56 CowNew開源團隊 閱讀(4978) | 評論 (2)編輯 收藏

    ??? 初涉開源已經(jīng)一個月了,和Huihoo、SpringSide、EasyJF這樣的“老大哥”比起來還稚嫩的很。但是在這一個月中也體會到了酸甜苦辣。
    ?? 開源是需要雷鋒精神的。“時間就像海綿里的水,只要愿意擠,總還是有的。” (有人說這句話是魯迅說得,我沒時間去考證了)。哪怕公司的工作加班到了10點,回來還是可以為開源忙上一個小時的,不要給任何自己不要為之奮斗的理由,只要要求自己每天都為開源做一點事情,相信會有回報的。
    ??? 開源是孤獨的,特別是在中國。太多的人為了二斗米去奮斗,并以此給自己一個自己很忙,自己沒時間做開源的借口;太多的人認為開源是在為別人賣苦力,自己是傻大個;太多了人站在少數(shù)幾個開源者的旁邊,象看耍猴子一樣看熱鬧了;太多的人希望鉆進一個開源團隊,然后什么事情都不做,等著坐收漁利了;太多了人還沒開始做就想著項目商業(yè)運營之后到底能賺多少錢了。。。。。。
    ??? 開源是需要付出的。女朋友又想你了,你去不去?哥們又要你出去喝酒了,你去不去?周末朋友們又去蹦迪了,你去不去?開源有可能是付出了N多精力,卻無利可圖的,你干不干?。。。。。。
    ??? 開源是勞累的。忙完了白天的工作,晚上回來還要寫代碼;但別人都進入夢鄉(xiāng)的時候,你卻在為一個自己為自己分配的開源任務(wù)而奮斗。。。。。。??
    ??? 開源是需要鉆研精神的。開源一般做的都是業(yè)界先進的技術(shù),能夠參考的資料很少。你不能夠要求做開源的時候還有那么多被前仆后繼的編碼員都寫臭了街的所謂“××信息系統(tǒng)”的代碼可以參考。更多的需要自己去鉆研:鉆研國外的資料,與同行的高手共同探討,甚至要自己獨創(chuàng)一套東西。創(chuàng)新是開源的一個重要特征。這也決定了做開源的最終都會成為精英。
    ??? 開源是需要腳踏實地的。那些希望今天做開源明天就能成名發(fā)財?shù)娜耸潜貙⑹〉摹0蚕滦膩恚拖骂^來,走好腳下的每一步,相信成功就一定會在前方等著你。
    ??? 開源是為自己在努力的。開源項目中沒有老板,項目發(fā)起人也只是個組織者,你不是在為他工作,你是在為自己的明天奮斗。開源中付出多的就是老大。不要抱怨項目組織者今后一定會比普通的隊友成功,你來努力呀,你的成績你的付出超過他,你就是老大。記住:開源是為自己奮斗,那些認為是在為別人賣苦力的人還是回到公司,老老實實當你的小職員吧。
    ???
    ??? CowNew團隊過程中我們遇到了很多兢兢業(yè)業(yè)的朋友。項目經(jīng)驗豐富的BadBoy,為了做團隊網(wǎng)站差點累出病來的土豆,經(jīng)常為了SQL解析引擎而忙到凌晨2點的KingChou,為項目管理獻計獻策的Andrew、霉干菜,為產(chǎn)品書寫介紹文檔驗證bug的月光光、c2,經(jīng)驗豐富的Sephil,還有積極關(guān)注團隊發(fā)展的孤獨河馬、滾來滾去、熱血年華、宋笑癡、foxKnit等等朋友。EasyJF的大峽、船長也給我們提出了很多建議。有了他們才有了CowNew的現(xiàn)在。
    ??? 問題是很多的。現(xiàn)在JDBMonitor和SQL解析引擎組已經(jīng)正常運作了。原先策劃的MDA、進銷存組由于大家缺少大型項目的遠程協(xié)同能力,所以不得不暫時進行合并轉(zhuǎn)型為技術(shù)預(yù)研組。現(xiàn)在由孤獨河馬全權(quán)負責(zé)這個項目組的管理運營,希望他能帶領(lǐng)大家走出一條新路。前期花了太多的時間在討論團隊的建設(shè)問題,在曉之以理動之以情的給一些兄弟講開源的真諦,在為了能找到一個開發(fā)組負責(zé)人而游說各個成員。。。。。。浪費的時間太多了,干活的時間太少了,發(fā)的所謂“條例”太多了,但是卻缺乏實行這些“條例”的基本條件。所以以后在qq群里、在論壇上不會出現(xiàn)太多關(guān)于團隊發(fā)展的討論,不會再出現(xiàn)那些“管理條例”,不會再要求大家推薦帶頭人。團隊的發(fā)展是只有真正跑起來才知道的,如果連事情都沒做談什么發(fā)展;“管理條例”是需要以后慢慢探索的,帶頭人也會在今后的項目中浮山水面的。不能適應(yīng)、不能理解開源的朋友還是退出團隊吧,有更多更合適其他機會等著你。所以今后CowNew不會再有“討論”、“決議”,有的只是技術(shù)交流,有的只是干活,just do it!
    ???
    ?? 開源路漫漫,志同道合者更是少之又少,惟愿同路者以此句共勉“向雷鋒同志學(xué)習(xí)”。
    -----------------------------------
    CowNew開源團隊
    官方網(wǎng)站:http://www.cownew.com
    論壇:http://www.cownew.com/newpeng/
    posted @ 2006-05-30 01:31 CowNew開源團隊 閱讀(1215) | 評論 (7)編輯 收藏

    把JDBMonitor嵌入到poolman上面是有很大的實用意義的,這樣我們可以做成一個完整的數(shù)據(jù)庫連接和數(shù)據(jù)庫訪問的監(jiān)控.

    JDBMonitor和poolman一樣都是非入侵性的,所以用起來很簡單,這里我說一下用法:

    在安裝好poolman后,建立連接如下

    // load the PoolMan JDBC Driver
    ??????????

    Class.forName("com.codestudio.sql.PoolMan").newInstance();

    Connection con = DriverManager.getConnection("jdbc:poolman");

    再配置poolman.xml

    ?? <?xml version="1.0" encoding="UTF-8"?>
    ?????? <poolman>
    ????????? <datasource>
    ???????????? <dbname>default</dbname>
    ???????????? <jndiName>default</jndiName>
    ??????????? <driver>com.cownew.JDBMonitor.jdbc.DBDriver</driver>
    ??????????? <url>listenerconfig=c:/config.xml:url=jdbc:oracle:thin:@localhost:1521:Database</url>
    ??????????? <username>user</username>
    ??????????? <password>code</password>

    ??????????? <logfile>c:/test.txt</logfle>

    ?????? </datasource>

    ???? </poolman>

    再配置好JDBMonitor,就完成了JDBMonitor和poolman的結(jié)合

    工程向poolman(連接池)申請連接,poolman再向JDBMonitor申請連接,并生成連接日志

    poolman負責(zé)連接池的維護,當工程執(zhí)行數(shù)據(jù)庫訪問,JDBMonitor將記錄數(shù)據(jù)訪問日志,

    這樣我們就可以完全監(jiān)控數(shù)據(jù)庫的連接和訪問了
    作者月光光是CowNew開源團隊(www.cownew.com)JDBMonitor開發(fā)組、SQL解析引擎開發(fā)組的主力開發(fā)人員。
    更多內(nèi)容請見CowNew開源團隊網(wǎng)站 www.cownew.com
    論壇 http://www.cownew.com/newpeng/

    posted @ 2006-05-29 00:57 CowNew開源團隊 閱讀(1098) | 評論 (0)編輯 收藏

    今天做了個executeBatch的例子,可是輸?shù)慕Y(jié)果卻出乎我的意料,如下

    begintime:2006-05-25 09:58:11.0
    endtime:2006-05-25 09:58:11.14
    sqlType:executeBatch
    sql:insert into tmm_bill (billname, billdesc) values (?, ?);insert into tmm_bill (billname, billdesc) values (?, ?);
    paramters:[1, 2]

    為什么輸出的是兩個語句,而只有一組參數(shù)呢,于是我決定一探究竟.

    下面是我的例子

    ?? conn = DriverManager
    ???? .getConnection("listenerconfig=/com/cownew/JDBMonitor/demo/oracleconfig.xml:url=jdbc:oracle:thin:@zbw:1521:xinem8gg", "m8connect", "m8connect");
    ?? //for (int i = 0; i < 10; i++)
    ?? //{

    ??? ps = conn
    ????? .prepareStatement("insert into tmm_bill (billname, billdesc) values (?, ?)");
    ???
    ??? ps.setString(1,"songzho");
    ??? ps.setString(2, "yufn");
    ???
    ??? ps.addBatch();
    ???
    ??? ps.setString(1, "2");
    ??? ps.setString(2, "3");
    ???
    ??? ps.addBatch();
    ???
    ???
    ??? ps.executeBatch();
    ??? ps.close();

    原來我們輸出的內(nèi)容封裝在SQLInfo這個類中

    這個類中有一個get和set方法用來取值和付值,這個我就不多介紹了,主要說一下其中一個方法

    private List parameters = new ArrayList();

    ?public List getParameters()
    ?{
    ? return parameters;
    ?}

    public String toString()
    ?{
    ? StringBuffer sb = new StringBuffer();
    ? sb.append("begintime:").append(beginTime).append("\n");//設(shè)置開始執(zhí)行語句的時間
    ? sb.append("endtime:").append(endTime).append("\n");//設(shè)置結(jié)束執(zhí)行語句的時間
    ? sb.append("sqlType:").append(sqlType).append("\n");//設(shè)置語句的類型
    ? sb.append("sql:").append(sql).append("\n");//設(shè)置語句
    ? if(parameters.size()>0)
    ? {
    ????? sb.append("paramters:").append(parameters).append("\n");//設(shè)置參數(shù),就是這里有點問題
    ? }
    ? return sb.toString();
    ?}

    在這里大家可以看出來parameters就是用來傳入?yún)?shù)的arrayList,可是這里只能存一組參數(shù);

    我們再看一下 DBPreparedStatement 這個類,這個類的意義也不用多說了吧,主要看看兩個方法

    ?public int[] executeBatch() throws SQLException
    ?{
    ? SQLInfo info = new SQLInfo();
    ? info.setSqlType(SQLTypeEnum.executeBatch);//SQLInfo類設(shè)置SqlType的方法
    ? info.setBeginTime(JdbcUtils.getTimeStamp());//SQLInfo類設(shè)置BeginTime的方法
    ? info.setSql(sbAddBatch.toString());//SQLInfo類設(shè)置Sql的方法,sbAddBatch是一個StringBuffer

    ? int[] ret = stmt.executeBatch();

    ? info.setEndTime(JdbcUtils.getTimeStamp()); ());//SQLInfo類設(shè)置EndTime的方法
    ?
    ? if (params != null && paramCount != 0)//這里是設(shè)置參數(shù)的地方,就是這里出了一點問題,params只是保存一組參數(shù),也就是最后一組
    ????????? //對于只有一組參數(shù)是沒有問題的,可是如果有多組參數(shù)就會出現(xiàn)上面我說的那個現(xiàn)象了
    ? {
    ?? int i = 0;
    ?? for (int size = paramCount; i < size; i++)
    ??? info.getParameters().add(params[i]);
    ? }
    ? logSql(info);
    ? sbAddBatch.setLength(0);
    ? return ret;
    ?}

    我改動的方法是這樣的
    private ArrayList paramsList = new ArrayList();
    public class DBPreparedStatement extends DBStatement implements
    ??PreparedStatement
    {
    ?.
    ?.
    ?.
    ?public void addBatch() throws SQLException
    ?{
    ??//sbAddBatch.append(sql).append(";");
    ???? ArrayList pListTemp = new ArrayList();
    ???? for (int i = 0; i < paramCount; i ++)
    ???? {
    ???????? pListTemp.add(params[i]);//把每一組參數(shù)存到一個ArrayList里面
    ???? }
    ????
    ???? paramsList.add(pListTemp);//再把那個臨時的TempList存到一個ArrayList里面

    ??
    ??((PreparedStatement) stmt).addBatch();

    ?}

    ?.
    ?public int[] executeBatch() throws SQLException
    ?{
    ??
    ???? sbAddBatch.append(sql);
    ????
    ???? SQLInfo info = new SQLInfo();
    ??info.setSqlType(SQLTypeEnum.executeBatch);
    ??info.setBeginTime(JdbcUtils.getTimeStamp());
    ??info.setSql(sbAddBatch.toString());

    ??int[] ret = stmt.executeBatch();

    ??info.setEndTime(JdbcUtils.getTimeStamp());??
    ??
    ??if (paramsList != null && paramsList.size() != 0)
    ??{
    ???for (int i = 0; i < paramsList.size(); i ++)
    ???{
    ?????? info.getParameters().add(paramsList.get(i));//取到每一個TempList
    ???}

    ?????
    ??}
    ??logSql(info);
    ??sbAddBatch.setLength(0);
    ??return ret;
    ?}
    ?.
    ?.
    ?.
    }
    public class SQLInfo implements Serializable
    {
    ?.
    ?.
    ?.
    ?public String toString()
    ?{
    ??StringBuffer sb = new StringBuffer();
    ??sb.append("begintime:").append(beginTime).append("\n");
    ??sb.append("endtime:").append(endTime).append("\n");
    ??sb.append("sqlType:").append(sqlType).append("\n");
    ??sb.append("sql:").append(sql).append("\n");
    ??if(parameters.size()>0)
    ??{
    ????? for (int i = 0; i < parameters.size(); i ++)
    ????? {
    ????????? sb.append("paramters:").append((ArrayList)parameters.get(i)).append("\n");//循環(huán)取TempList里的參數(shù)
    ????? }

    ??}
    ??return sb.toString();
    ?}
    }
    得到的結(jié)果為
    begintime:2006-05-25 13:16:00.218
    endtime:2006-05-25 13:16:00.234
    sqlType:executeBatch
    sql:insert into tmm_bill (billname, billdesc) values (?, ?)
    paramters:[songzho, yufn]
    paramters:[2, 3]

    也不知道各位看官看明白了沒有,其實不懂也沒什么關(guān)系,我只是想在這里給大家說一下我們輸出方式,總結(jié)一下就是我們做了自己的DBConnect,DBStatetment,
    DBPrepareStatement....,都是繼承了JDBC的原型,在實現(xiàn)這些功能的之前,先把信息記錄在SqlInfo里,再跟據(jù)配置的寫日志方式進行寫日志.
    作者月光光是CowNew開源團隊(http://www.cownew.com)JDBMonitor開發(fā)組的核心開發(fā)人員,在J2EE開發(fā)方面頗有造詣。

    posted @ 2006-05-27 01:46 CowNew開源團隊 閱讀(1255) | 評論 (0)編輯 收藏

    這個題目其實有點大了,其實說的問題很小。
    大家都說java是跨平臺的,可是用java寫出來的代碼能不能真正的跨平臺還是要開發(fā)人員來把握。
    我今天在CSDN上看到一位朋友給JDBMonitor提出的一條bug:
    "如果我的系統(tǒng)是linux,那個listenerconfig=就難寫了,因為我要是寫成/root/什么的,他會認為是classpath,實際上這是個物理路徑,期待改進"
    因為在上一個小版本中,我為了同時適應(yīng)用戶通過類路徑指定配置文件的位置,比如,com/cownew/config.xml,也能通過真實的文件路徑制定文件的位置,比如c:/config.xml
    所以我就要判斷用戶給出的路徑是類路徑還是文件路徑,我的實現(xiàn)方式是判斷路徑是否以a-z的字母開頭,并且后邊跟著":/",如果是,則為文件路徑,否則為類路徑。
    但是在unix(linux)下,絕對路徑則是/root/cfg/config.xml的形式,我就給誤判斷成是類路徑了。這樣在這些平臺下就報錯了,我采用如下方式解決:
    JDBMonitor會首先把<configfilepath>當成類路徑去讀取,如果讀取失敗再把它當作文件路徑去讀,例如如果您設(shè)定/root/cfg/config.xml,本意是想加載文件路徑/root/cfg/下的文件config.xml,但是如果您的類路徑中有root.cfg這個包,并且包下同樣有config.xml這個文件,那么JDBMonitor會去讀root.cfg中的文件config.xml,而非/root/cfg/config.xml。
    示意代碼如下:
    InputStream is = null;
    is = this.getClass().getResourceAsStream(configFile);
    if(is==null)
    {
    ?? try
    ?{
    ??is = new FileInputStream(configFile);
    ?} catch (FileNotFoundException e)
    ?{
    ??is = null;
    ?}
    }

    不知道有沒有更好的辦法解決,請高手指教。有時間也去看看那些tomcat之類的服務(wù)器是怎么解決這個問題的。
    JDBMonitor最強大的無侵入式數(shù)據(jù)庫監(jiān)控、日志工具。
    COWNEW團隊,最專業(yè)的開源團隊!官方網(wǎng)站:
    www.cownew.com

    posted @ 2006-05-25 01:39 CowNew開源團隊 閱讀(918) | 評論 (3)編輯 收藏

    JDBMonitor(可以從www.cownew.com下載)是一個非常強大的數(shù)據(jù)庫監(jiān)控、日志工具,它的無侵入性是它最大的特點。所謂無侵入性指的是無需編寫代碼就可以為系統(tǒng)增加數(shù)據(jù)日監(jiān)控、日志功能。那么它到底是怎么實現(xiàn)的呢?咱們來探索一下它的基本原理。
    要明白JDBMonitor的工作原理,必須首先弄明白JDBC驅(qū)動的工作原理:
    所有的JDBC驅(qū)動都實現(xiàn)java.sql.Driver接口,此接口有兩個重要方法:Connection connect(String url, java.util.Properties info),boolean acceptsURL(String url)。
    JDBC中有個DriverManager類,它有一個重要方法,
    registerDriver(java.sql.Driver driver)
    所有的JDBC驅(qū)動都要調(diào)用此方法,這樣才能將注冊到驅(qū)動管理器中。
    當用戶調(diào)用DriverManager.getConnection("jdbc:......")的時候,DriverManager就把用戶穿過來的連接字符串“jdbc:......”發(fā)給每個注冊的驅(qū)動Driver的acceptsURL方法做為參數(shù),驅(qū)動Driver就調(diào)用這個Driver的connect方法然后將方法的返回值直接做為自己的返回值。
    更詳細的解釋請查看JDBC的JavaDoc,或者參考如下文章:http://www.cntopedu.cn/cntopedu_html_itxuetang/200562963708.asp


    JDBMonitor寫了自己的JDBCDriver:DBDriver,這個DBDriver識別所有以listenerconfig=開頭的jdbc連接字符串,這樣如果您修改了您系統(tǒng)的JDBC連接字符串并添加listenerconfig=等部分以后,此url就不會被您原來的JDBC驅(qū)動認識,耳反而被DBDriver認識,這樣每次的數(shù)據(jù)庫連接調(diào)用也都通過DBDriver以及相關(guān)的類來進行(比如DBPreparedStatement等),這些類首先先把通過的數(shù)據(jù)庫調(diào)用記錄下來,然后再轉(zhuǎn)發(fā)給真正的數(shù)據(jù)庫驅(qū)動,這樣就達到了攔截任何JDBC調(diào)用的目的。更相信內(nèi)容,請參考com.cownew.JDBMonitor.jdbc包下的DBDriver、DBConnection、DBStatement、DBPreparedStatement等類。這些類采用了代理模式、裝飾者模式等設(shè)計模式,使得程序的可擴展性得到很大的提升。

    COWNEW團隊,最專業(yè)的開源團隊!官方網(wǎng)站: www.cownew.com

    posted @ 2006-05-24 02:20 CowNew開源團隊 閱讀(951) | 評論 (1)編輯 收藏

    一、 Antlr 的主要類:

    Antlr 中有主要類有兩種(其實還有一種 TreeLexer

    Lexer: 文法分析器類。主要用于把讀入的字節(jié)流根據(jù)規(guī)則分段。既把長面條根據(jù)你要的尺寸切成一段一段:)并不對其作任何修改。

    Parser: 解析器類。主要用于處理經(jīng)過 Lexer 處理后的各段。一些具體的操作都在這里。

    二、 Antlr 文法文件形式:

    Antlr 文件是 *.g 形式,即以 g 為后綴名。

    例如: t.g

    class P extends Parser;

    startRule

    ??? :?? n:NAME

    ??????? {System.out.println("Hi there, "+n.getText());}

    ??? ;

    class L extends Lexer;

    // one-or-more letters followed by a newline

    NAME:?? ( 'a'..'z'|'A'..'Z' )+ NEWLINE

    ??? ;

    NEWLINE

    ??? :?? '\r' '\n'?? // DOS

    ??? |?? '\n'??????? // UNIX

    ;

    具體成分分析:

    1 、總體結(jié)構(gòu)

    Class P extends Parser

    Class L extends Lexer

    兩行同 JAVA 繼承一樣, P 繼承 Parser 類; L 繼承 Lexer 類。每個 .g 文件只能各有一個。

    2 Lexer 類分析

    一般按照

    類型名:
    ????
    匹配的具體規(guī)則
    ????

    的形式構(gòu)成。是分隔字節(jié)流的依據(jù)。同時可以看到里面可以互相引用。如本例中的類型名 NEWLINE 出現(xiàn)在 NEW 的匹配規(guī)則中。

    3 Parser 類分析

    一般按照

    起始規(guī)則名:

    ???????? 規(guī)則實例名:類型名或規(guī)則名

    ??????????????????????????? {Java 語句。。。; }

    ????????

    ???????? 。。。。。。。。。

    的形式構(gòu)成。

    起始規(guī)則名:任意。

    規(guī)則實例名:就象 Java 中“ String s ;”的 s 一樣。規(guī)則實例名用于在之后的 JAVA 語句中調(diào)用。

    類型名或規(guī)則名:可以是在 Lexer 中定義的類型名,也可以是 Parser 中定義的規(guī)則名。感覺就像是 int Integer 的區(qū)別。

    Java 語句:指當滿足當前規(guī)則時所執(zhí)行的語句。 Antlr 會自動嵌入生成的 java 類中。

    ?

    ?

    ?

    三、生成 Java

    1 、從 www.antlr.org 上下載 antlr-x.x.x.jar

    2 、配置環(huán)境變量: classpath=.;x:\jdk\lib\tools.jar;x:\antlr-x.x.x.jar

    3 、在 t.g 所在目錄下執(zhí)行:

    java antlr.Tool t.g

    會在當前目錄下生成如下文件:

    L.java Lexer 文法分析器 java 類。

    P.java Parser 解析器 java 類。

    PTokenTypes.java Lexer 中定義的類型具體化,供 Parser 解析器調(diào)用。

    PTokenTypes.txt :當外部的(如 t2.g )要調(diào)用當前的類型或規(guī)則時要用到本文件。

    ?

    ?

    ?

    四、執(zhí)行

    1 、編寫 Main
    import java.io.*;
    ????? class Main {
    ?public static void main(String[] args) {

    try {


    L lexer = new L(new DataInputStream(System.in));
    P parser = new P(lexer); parser.startRule();
    } catch(Exception e)
    {
    System.err.println("exception: "+e);
    }


    ? }
    }

    2 、執(zhí)行
    c:\> javac *.java
    c:\> java Main
    Terence
    ^Z
    Hi there, Terence
    c:\>

    本文作者kingchou是CowNew開源團隊SQL解析引擎項目組負責(zé)人。
    更多內(nèi)容請見CowNew開源團隊網(wǎng)站
    www.cownew.com
    論壇 http://www.cownew.com/newpeng/

    posted @ 2006-05-23 02:22 CowNew開源團隊 閱讀(2221) | 評論 (2)編輯 收藏

    上午我試了下JDBMonitor(http://www.cownew.com),并閱讀了部分代碼
    我覺得想法挺好的,不過我也發(fā)現(xiàn)了一個BUG

    我試了下DEMO里面TEST,結(jié)果發(fā)現(xiàn)如果使用SocketDBListener則整個程序不能正常結(jié)束
    我查了下代碼發(fā)現(xiàn)是SocketDBListener里面的THREAD不是后臺的,而且也沒有手工關(guān)閉的原因
    我改成后臺的之后就沒問題了


    另外還發(fā)現(xiàn)一個問題,
    在SocketDBListener的代碼里有這么一段:

    protected void finalize() throws Throwable
    {
    super.finalize();
    for(int i=0,n=clientList.size();i<n;i++)
    {
    Socket socket = (Socket) clientList.get(i);
    socket.close();
    }
    }
    這樣有2個問題:
    1)super.finalize() 最好在最后調(diào)用,而且最好在FIANLLY里用,如:
    finally{
    super.finalize();
    }
    2) 關(guān)閉socket之類的工作在fianlize里面做不太好,在我的測試里,當MAIN方法進行完了后
    finalize并沒有執(zhí)行,而且因為SocketDBListener里面的THREAD還在,所以shoutdownHook也沒有執(zhí)行;
    而且即使該為后臺線程,能正常關(guān)閉了,finalize也不一定進行的
    所以建議為IDBListener增加一個主動關(guān)閉的方法

    posted @ 2006-05-22 01:34 CowNew開源團隊 閱讀(843) | 評論 (0)編輯 收藏

    互幫互助,提高java程序員開發(fā)水平,完成大規(guī)模團隊項目;商業(yè)運營,追求開源產(chǎn)品利潤最大化

    一、CowNew開源團隊簡介

    CowNew開源團隊,是一個由Java開源愛好者組成的團隊,官方網(wǎng)站:www.CowNew.com。
    CowNew團隊知道很多很多java開發(fā)人員處在一個較低的開發(fā)水平,但是又都普遍想提高自己的開發(fā)技能; CowNew團隊知道很多很多java開發(fā)高手有很多想法,但是由于勢單力薄,無法完成由開發(fā)團隊協(xié)同合作、共同開發(fā)才能完成的功能;CowNew團隊知道很多很多好的想法、好的項目由于缺乏有效的商業(yè)運營而導(dǎo)致這些很有價值的東西停留在技術(shù)層面,無法取得應(yīng)有的商業(yè)價值。

    基于此我們成立了 CowNew開源團隊,此團隊的理念是“互幫互助,提高java程序員開發(fā)水平,完成大規(guī)模團隊項目;商業(yè)運營,追求開源產(chǎn)品利潤最大化”。

    我們--用實際項目開發(fā)幫助開發(fā)人員進階

    我們--為有想法的高手提供實現(xiàn)其想法的開發(fā)伙伴

    我們--積極的進行開源項目商業(yè)化運作,讓項目組成員得到更多的回報。

    二、CowNew開源團隊組織形式

    開源組織研發(fā)部門設(shè)立兩個大項目組,一個區(qū)域是項目開發(fā)區(qū),主要是實際的項目的開發(fā);一個區(qū)域是后備力量培養(yǎng)區(qū),主要為有熱情加入開源組織、有一定的開發(fā)經(jīng)驗的朋友準備,這個區(qū)域?qū)⒂蓪iT的專家指導(dǎo),幫助其提高開發(fā)能力,合格的開發(fā)人員將隨時轉(zhuǎn)到項目開發(fā)區(qū)。所有后備力量培養(yǎng)區(qū)人員都要分配到具體的項目組,主要承擔(dān)產(chǎn)品測試、文檔書寫、產(chǎn)品宣傳工作,并且要積極閱讀學(xué)習(xí)正式項目開發(fā)人員的代碼,并定期書寫學(xué)習(xí)筆記,其筆記也將做為產(chǎn)品文檔。 后備力量培養(yǎng)區(qū)的人員可以參與項目的開發(fā),如果其工作產(chǎn)品質(zhì)量較優(yōu)可以考慮納入正式產(chǎn)品中。

    另設(shè)立宣傳組和商業(yè)伙伴組,宣傳組主要負責(zé)團隊網(wǎng)站的日常維護更新,在各個業(yè)界主流網(wǎng)站中發(fā)宣傳稿,負責(zé)項目組其他成員撰寫的文章的發(fā)表推廣工作;商業(yè)伙伴組負責(zé)項目產(chǎn)品的商業(yè)化運營。

    三、CowNew2006年計劃開源項目列表

    1、JDBMonitor
    功能概述:一個可擴展的無侵入式的數(shù)據(jù)庫監(jiān)控、日志工具。此項目已經(jīng)有了第一個版本。后期將增加可用性和配置靈活性,并增強其日志分析預(yù)警能力。
    開發(fā)人員技能要求:
    熟悉java語言,或者熟悉數(shù)據(jù)挖掘
    后備人員要求:
    熟悉java語言,后備人員可以承擔(dān)部分任務(wù),其開發(fā)成果可以納入產(chǎn)品中
    2、進銷存系統(tǒng)
    功能:提供中小企業(yè)使用的常用的進貨、銷售、倉存功能,并提供業(yè)務(wù)分析功能。
    開發(fā)人員技能要求:
    熟悉下面技能中的一種或幾種:
    Swing界面開發(fā)
    java數(shù)據(jù)庫操作
    報表開發(fā)
    熟悉進銷存業(yè)務(wù)
    熟悉分布式開發(fā)
    較強的系統(tǒng)建模能力
    后備人員要求:
    熟悉java語言
    3、Java Web RAD開發(fā)工具
    功能:開發(fā)Java Web開發(fā)的RAD開發(fā)工具,簡化java的web開發(fā)難度
    開發(fā)人員技能要求:
    熟悉下面技能中的一種或幾種:
    java Web 開發(fā)
    .net Web 開發(fā)
    eclipse插件開發(fā)
    較強的系統(tǒng)建模能力
    后備人員要求:
    熟悉java語言

    4、SQL語句解析引擎
    功能:將標準SQL語句解析成抽象語法樹,從而為后續(xù)的SQL語句格式化器,SQL語句排錯器做準備。此功能是一個獨立的抽象部件。
    開發(fā)人員技能要求:
    熟悉編譯原理,能夠書寫有一定難度的詞法、語法分析器(可以使用antlr等工具)
    后備人員要求:
    熟悉下面技能中的一種或幾種:
    熟悉java語言,對編譯原理有一定了解
    熟悉SQL語法
    5、軟多路復(fù)用技術(shù)
    功能:為應(yīng)用提供多路復(fù)用支持,簡化應(yīng)用部署,提高應(yīng)用安全性。
    開發(fā)人員技能要求:
    熟悉網(wǎng)絡(luò)編程
    后備人員要求:
    有一定網(wǎng)絡(luò)編程經(jīng)驗

    ?


    四、CowNew團隊成員激勵機制

    1、加入項目組的成員將會被記錄團隊總積分。

    1、項目開始初每人確認自己要完成的工作量和需要完成的時間。項目初期每人分配一定的項目積分,對于按時甚至提前完成的人員將會給予不同程度的項目積分獎勵,對于延遲完成的則不會給予積分獎勵,對嚴重滯后的將視情況扣除積分。項目結(jié)束后此積分將會被累積到個人團隊總積分。

    2、成員在媒體上發(fā)表的CowNew相關(guān)的技術(shù)文章、宣傳文章都將會被給予一定程度的積分,并記入個人團隊總積分。

    3、成員推薦符合要求的成員加入、為團隊商業(yè)運營提供幫助等任何對團隊有益的事情都將給予相應(yīng)程度的積分。

    4、將對成員在團隊的交流平臺(qq群,論壇等)上的活躍程度進行積分,并記入積分。

    4、積分可以兌換贊助商提供的禮品等。在成員負責(zé)的項目組的產(chǎn)品取得商業(yè)運營利潤之后,將可以根據(jù)積分參與分紅。

    五、成員權(quán)利與義務(wù):

    權(quán)利:
    1、啟動項目的權(quán)利。任何成員都可以提出自己的想法,并啟動相應(yīng)的項目任務(wù)。
    2、自由退出的權(quán)利。任何成員都可以隨時退出團隊。
    3、投票權(quán)、選舉權(quán)、被選舉權(quán)。任何成員都可以參與相關(guān)項目組的決策,投票,并有權(quán)利被選為負責(zé)人。
    4、分紅權(quán)。任何成員都可以參與自己負責(zé)模塊商業(yè)運營成果的分紅。
    義務(wù):
    1、任何成員必須保守團隊的秘密。
    2、所有關(guān)于CowNew團隊以及相關(guān)產(chǎn)品的文章,代碼可以標注作者信息,但是必須同時標注CowNew團隊的版權(quán)信息。
    3、積極參與團隊的各項任務(wù)。對于長期不參與團隊的成員將會被請出團隊。

    六、請有興趣加入CowNew團隊的朋友按下面任何一種方式進行

    1、 加入QQ群,群號:20392347。驗證消息注明:加入開源。加入后請在BBS發(fā)貼簡要介紹自己。

    2、到項目組論壇報道:http://cownew.forumup.com/

    3、到項目的sourcege主頁的論壇報道:https://sourceforge.net/projects/jdbmonitor/

    4、給我們發(fā)送email:about521@163.com

    注:加入的成員請在加入的時候注明自己想?yún)⒓幽膫€項目組,想負責(zé)哪塊工作,特長是什么,聯(lián)系方式,最好能提供個人作品。本團隊暫時不接納入門級開發(fā)人員,請諒解。

    ?

    posted @ 2006-05-18 23:01 CowNew開源團隊 閱讀(1421) | 評論 (3)編輯 收藏

    Log4j (http://logging.apache.org/log4j/docs)是一個開源代碼的項目(Open source project),它使開發(fā)人員能最大限度的靈活控制程序調(diào)試信息的輸出,這一點它是通過額外的配置文件實現(xiàn)的。

    JDBMonitor(

    共同點:

    1、Log4j和JDBMonitor都有很強的可擴展性,例如Log4j可以寫自己的Appender,JDBMonitor可以寫自己的DBListener。

    2、Log4j和JDBMonitor都很容易配置。當然Log4j配置文件相對復(fù)雜。

    不同點:

    1、Log4j能為各種事件進行日志輸出,比如關(guān)鍵操作,運行中的變量值、數(shù)據(jù)庫語句日志等。而JDBMonitor只能記錄數(shù)據(jù)庫sql語句操作記錄。所以說Log4j應(yīng)用范圍更廣,如果您需要記錄非數(shù)據(jù)庫語句日志就要使用Log4j,JDBMonitor則無能為力。

    2、Log4j配置比較靈活,比如可以配置什么等級的日志被記錄,記錄的格式是什么樣的,日志文件到多大的時候被轉(zhuǎn)儲;而JDBMonitor則相對較不靈活,輸出格式比較單一、而且無法指定那些日志可以被忽略。

    3、Log4j是侵入式的,所有的日志操作都是寫在業(yè)務(wù)代碼之中的,缺點是很明顯的,這導(dǎo)致業(yè)務(wù)代碼中摻雜大量的日志輸出代碼,降低了代碼的可讀性,而且一旦想去掉日志功能以后必須逐個刪除代碼,加大了工作量和風(fēng)險。JDBMonitor是非侵入式的,它采用代理模式攔截對數(shù)據(jù)庫的調(diào)用,然后對進行日志記錄,業(yè)務(wù)系統(tǒng)中根本不用摻雜日志代碼。只要修改JDBC連接字符串即可,如果想去掉日志功能,只要將JDBC連接字符串修改回去即可。

    4、Log4j采用的日志記錄實現(xiàn)方式會對程序的運行速度有一定影響,在日志比較多的時候,甚至?xí)?dǎo)致整個程序慢到無法忍受。而JDBMonitor則另起一個線程來記錄SQL,所以它幾乎不會對程序運行速度有任何影響。

    5、Log4j的Appender不適合進行調(diào)試開發(fā),調(diào)試開發(fā)只有那個控制臺Appender可以用,但是在大數(shù)據(jù)量的時候整個屏幕狂刷不止,根本看不清,而且很多操作系統(tǒng)的控制臺(比如windows的)都有緩沖區(qū)大小限制,所以很容易造成想看的sql日志被沖掉看不到了。而Log4j的不僅有與Log4j類似的控制臺Appender可以用,而且有一個客戶端SocketSwingClient可以用,這個客戶端類似SQLServer的事件監(jiān)聽器,容納的日志量相當大,而且可以自由控制日志的上下滾動。

    posted @ 2006-05-17 17:03 CowNew開源團隊 閱讀(943) | 評論 (0)編輯 收藏

    僅列出標題
    共30頁: First 上一頁 21 22 23 24 25 26 27 28 29 下一頁 Last 
    主站蜘蛛池模板: 亚洲中文字幕久久精品无码VA| 久久亚洲国产成人影院网站| 亚洲网站视频在线观看| 免费看美女让人桶尿口| 亚洲最大黄色网站| 四虎在线成人免费网站| 日韩电影免费在线观看视频| 亚洲乱码在线观看| 韩国二级毛片免费播放| 美女黄色毛片免费看| gogo全球高清大胆亚洲| 久久国产美女免费观看精品| 中文字幕亚洲无线码a| 99在线免费视频| 亚洲国产一区二区a毛片| 2021精品国产品免费观看| 亚洲人成网站18禁止久久影院| 成人影片麻豆国产影片免费观看| 亚洲依依成人亚洲社区| 日本中文一区二区三区亚洲| 国产精品免费大片一区二区| 久久精品亚洲中文字幕无码网站| 最近免费中文字幕mv在线电影| 久久亚洲精品专区蓝色区| 凹凸精品视频分类国产品免费| 国产福利免费视频| 亚洲天天做日日做天天看| 最近中文字幕无吗免费高清 | 亚洲国产精品一区二区第一页| 免费A级毛片av无码| 亚洲一区精品伊人久久伊人| 成人无码a级毛片免费| 久久精品国产精品亚洲| 久久午夜夜伦鲁鲁片无码免费| 亚洲精品国产精品乱码不卡| 免费在线看黄网站| 亚洲人成网站在线观看播放青青| 亚洲成?Ⅴ人在线观看无码| 日韩免费观看一区| 亚洲日本VA午夜在线影院| 中文字幕不卡亚洲|