如鵬網 大學生計算機學習社區

          CowNew開源團隊

          http://www.cownew.com 郵件請聯系 about521 at 163.com

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

          #

          1、從TextEditor繼承,調用setSourceViewerConfiguration,并傳進去一個從SourceViewerConfiguration 繼承的配置類,就可以實現各種代碼editor。
          2、swt盡量使用GridLayout布局(不是java.awt中的GridLayout,而是swt中的)和GridData域。文章:http://coolbear.yculblog.com/post.89429.html

          3、得到文件的編輯器的方法:
          ??? public static IEditorPart findEditor(IFile file){
          ??????? IEditorReference[] editors = getActivePage().getEditorReferences();;
          ??????? for (int i = 0; i < editors.length; i++) {
          ??????????? IEditorPart part = (IEditorPart)editors[i].getPart(false);
          ??????????? if (part != null ){
          ??????????????? IEditorInput input = part.getEditorInput();
          ??????????????? if(input instanceof FileEditorInput && ((FileEditorInput)input).getFile().equals(file))
          ??????????????????? return part;
          ??????????? }???????????????
          ??????? }
          ??????? return null;
          ??? }

          4、得到工作區中所有工程的方法:
          ??????? IProject[] projects = ResourcesPlugin.getWorkspace().getRoot()
          ??????????????? .getProjects();
          這在開發自己的工程向導的時候很有用處。
          5、工程特有文件判斷方法
          project.getFile("cownew.prj").exists();
          project.getDescription().hasNature();
          給工程增加Nature的方法:
          ?IProjectDescription desc = project.getDescription();
          String[] oldNatureIds = desc.getNatureIds();
          ??????????????? String[] newNatureIds? = new String[oldNatureIds.length +1];
          ??????????????? System.arraycopy(oldNatureIds, 0, newNatureIds, 0, oldNatureIds.length);
          ??????????????? newNatureIds[oldNatureIds.length] = "CowNewNature";
          ??????????????? desc.setNatureIds(newNatureIds);
          ??????????????? project.setDescription(desc, monitor);
          6、創建文件夾的方法:
          IFolder folder = project.getFolder("myfold");
          if (folder!=null && !folder.exists())
          ? folder.create(false, true, null);

          7、彈出包選擇對話框的方法:
          ElementListSelectionDialog dialog = new ElementListSelectionDialog(
          ??????????????????? getShell(), new LabelProvider());
          ??????????? dialog.setIgnoreCase(false);
          dialog.setElements(getAllPackages().toArray());
          ??????????? String path = currentPackage();
          ?dialog.setInitialSelections(new Object[] { path });
          dialog.open();
          fPKName.setText((String) dialog.getFirstResult());

          public List getAllPackages() {
          ??????? List list = new ArrayList();
          ??????? IResource res = getFirstSelection();
          ??????? IProject project = res.getProject();
          ??????? File file = project.getFolder("src").getLocation().toFile();
          ??????? File[] fs = file.listFiles();
          ??????? for (int i = 0; i < fs.length; i++) {
          ??????????? if (fs[i].isDirectory())
          ??????????????? iterator("", fs[i], list);
          ??????? }
          ??????? Collections.sort(list);
          ??????? return list;
          ??? }
          8 objectClass="org.eclipse.core.resources.IFile"代表菜單應用到文件
          9 透視圖的的實現很簡單,就是在構造函數里邊打開一些視圖,使一些action(這樣菜單和按鈕也就都可用)可以用,比如:
          String editorArea = layout.getEditorArea();
          ??????? IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
          ??????????????? 0.30f, editorArea);
          ??????? left.addView(PACKAGE_VIEW_ID);
          ?layout.setEditorAreaVisible(true);
          ?layout.addShowViewShortcut(IDESystem.BUSINESSVIEW_ID);

          posted @ 2006-07-21 00:33 CowNew開源團隊 閱讀(1280) | 評論 (1)編輯 收藏

          為了幫助更多的朋友掌握eclipse的使用,我們團隊做了一個eclipse視頻教程,全部都是開發過程的屏幕錄像,并且伴有語音講解。一共八講,今天全部上傳完畢。希望我們的努力幫助更多的朋友。
          觀看方式:
          1、登錄硅谷動力在線觀看:http://www.enet.com.cn/article/2006/0704/A20060704124810.shtml
          2、通過cownew團隊網站中的超鏈接訪問:
          http://www.cownew.com/kc/

          感謝大家的支持。
          附前四講課件:
          ????????? 第一講? eclipse的基本使用
          1、eclipse工程的建立
          2、源文件夾等概念
          3、基本代碼的編寫
          ???????????? 第二講? eclipse基本操作(1)
          1、建立包、建立接口 及其他??
          2、工程的高級配置???
          3、工程的構建
          3、代碼的自動完成、自動修正功能
          ?? 黃色的、紅色的標識
          ?? (1)方法的自動生成
          ?? (2)導入import
          ?? (3)清除無用的import
          ?? (4)自動清除無用的方法、變量
          ?? (5)自動實現接口的、抽象類的方法,自動重載父類方法
          ???????? 第三講?? eclipse基本操作(2)
          1、Java的調試
          ??? (1) 斷點、條件斷點、異常斷點
          ?? (2)斷點中變量的查看,語句的執行
          2、智能糾錯、自動完成:
          ?? (1)自動生成try...catch,自動列出異常列表,自動轉型...在紅色提示上點擊鼠標,常??梢缘玫襟@喜
          ?? (2)自動生成set、get方法
          ?? (3)自動生成構造函數,?
          ?? (4)javadoc的自動生成

          第四講 eclipse高級操作(1) 重構
          一、概述
          1、好的程序應該是不斷重構出來的。消除bad smell,提高代碼可讀性、可維護性和可擴展性。《重構-改善既有代碼的設計》(英文名《Refactoring: Improving the Design of Existing Code 》)
          2、Eclipse的自動重構功能能夠很好地支持各種程序元素的重命名,并自動更新相關的引用。Eclipse能夠支持方法、字段在類之間移動,并自動更新引用。Eclipse較好地支持內聯字段、函數的更新替換。Eclipse較好地支持抽取方法、變量等程序元素。
          3、Eclipse的重構支持撤銷和重做,并且能夠預覽重構結果,會對有可能導致錯誤的重構結果進行提示。所以使用Eclipse進行重構是非常安全的。
          二、重構不高深-實戰重構
          1、方法抽取 Extract Mehod:
          將caclCost中參數校驗部分抽取成方法verify。
          2、重命名 Rename
          ? (1)重命名類名Test1為CostCalculator。
          ? (2)重命名User為UserInfo
          3、內聯 Inlining
          ?? 內聯方法add
          4、常量抽取 Extract Constant:
          ?? 將"normal"、"vip"抽取成常量
          5、抽取局部變量 Extract Local Variable
          ?? 將user.userType抽取成變量
          6、包裝字段 Encapsulate Field
          ?? 重構User類,用set get包裝
          7、Extract Interface 抽取接口
          ?? CostCalculator中抽取ICostCalculator接口
          posted @ 2006-07-19 23:55 CowNew開源團隊 閱讀(1797) | 評論 (3)編輯 收藏

          類型轉化

          Java是一種強類型語言,每個實例都必須有指定的類型。實際上,Java類型有兩種聲明類型運行時類型 (也可以相應的說是靜態類型動態類型 ). 像Python這樣的弱類型語言通常稱為無類型,但是這樣說并不嚴謹,因為每個實例都有它的運行時類型。你只是不用事先聲明一個實例的類型而已。

          要想調用一個對象中的方法,這個方法需要在聲明類型中存在。也就是說,你只能調用定義在父類中的方法,即使該實例是一個確定的子類型:

          List list = new ArrayList();
          list.add("data");       // 在這里沒問題
          list.ensureCapacity(4); // 這里就不行了ensureCapacity() 只在ArrayList中才有。
          

          如果我們要調用實際類型中的方法,我們首先要將它轉為正確的類型。在本例中,我們可以把 ArrayList 轉為List,因為ArrayList實現了List 接口. 也可以在運行時動態的檢驗,使用 list instanceof ArrayList.

          可擴展的接口

          糟糕的是,一個類不能總是實現你所需要實現的接口。可能是因為這只對少數幾種情況才有效,或者它是一個沒有被關聯的庫中的類型,或者這個接口在后期又被改變了。

          這種情況就可以使用IAdaptable。 你可以把 IAdaptable 動態的進行類型轉化。使用如下方法避免直接的類型轉化:

          Object o = new ArrayList();
          List list = (List)o;
          

          我們可以這樣做:

          IAdaptable adaptable = new ArrayList();
          List list = (List)adaptable.getAdapter(java.util.List.class);
          

          你可認為它是一種類型動態轉化; 我們把adaptable轉為List實例。

          為什么不直接轉化,而要用額外的getAdapter() 呢?這種機制可以使我們將目標類轉化為沒有實現的接口。例如, 我們可能想使用HashMap 作為一個 List, 盡管他們并不兼容。

          IAdaptable adaptable = new HashMap();
          List list = (List)adaptable.getAdapter(java.util.List.class);
          

          實現IAdaptable

          大多數IAdaptable的實現看起來就想是為支持類型構造多個if表達式的疊加。如果要為HashMap實現getAdapter() 可以這樣:

          public class HashMap implements IAdaptable {
            public Object getAdapter(Class clazz) {
              if (clazz == java.util.List.class) {
                List list = new ArrayList(this.size());
                list.addAll(this.values());
                return list;
              }
              return null;
            }
            // ...
          }
          

          返回的是一個對自身的代理,而不是直接轉化類型。如果請求的是不支持的類型,可以直接返回null表明失敗,這樣比拋出異常要好。

          PlatformObject

          當你想添加新的要擴展的類型時,只是簡單的修改一下就可以了。在任何情況下,如果已經得到了類型,為什么不修改接口?不修改類(如果使用接口,不容易保證向后兼容)或者改變它的類型(HashMap不是 List,但是可以轉化)是有原因的。要解決這個問題,在Eclipse中,使用了一個抽象類 HashMap is not a List, but can be conveted into one).

          To solve this problem, there's an abstract class that is used by most parts of Eclipse called -->PlatformObject。它為你實現了 IAdaptable接口,你就可以不用再操心了。

          PlatformObject 代理所有的它對getAdapter()的請求到 IAdapterManager. IAdapterManager是平臺默認提供的,通過 Platform.getAdapterManager()來訪問。你可以將它想象為一個巨大的 Map ,它負責關聯類和適當的適配器。PlatformObjectgetAdapter() 方法可以訪問到這個Map.

          適配已存在的類

          這樣的好處是可以為每一個PlatformObject對象動態的關聯新的適配器,而不用重新編譯。在Eclipse中的很多地方都是這樣來支持擴展的。

          這里希望將裝有StringList轉為XML節點。 XML節點顯示為:

          <List>
            <Entry>First String</Entry>
            <Entry>Second String</Entry>
            <Entry>Third String</Entry>
          </List>
          

          因為ListtoString方法可能有別的用途,所以不能使用。 可以為List添加一個工廠,當有轉為XML節點的請求時,一個Node對象就會自動返回。

          這里需要3個步驟:

          1. 從List中生成Node

          使用IAdapterFactory 來封裝轉換機制:

          import nu.xom.*;
          public class NodeListFactory implements IAdapterFactory {
            /** The supported types that we can adapt to */
            private static final Class[] types = {
              Node.class,
            };
            public Class[] getAdapterList() {
              return types;
            }
            /** The actual conversion to a Node */
            public Object getAdapter(Object list, Class clazz) {
              if (clazz == Node.class && list instanceof List) {
                Element root = new Element("List");
                Iterator it = list.iterator();
                while(it.hasNext()) {
                  Element item = new Element("Entry");
                  item.appendChild(it.next().toString());
                  root.appendChild(item);
                }
                return root;
              } else {
                return null;
              }
            }
          }
          

          2. 注冊工廠到PlatformAdapterManager

          我們需要注冊工廠到適配器工廠,當我們向 List實例請求Node時, 它就會知道是使用我們注冊的工廠。 Platform為我們管理IAdapterManager ,而且注冊過程相當簡單:

          Platform.getAdapterManager().registerAdapters(
            new NodeListFactory(), List.class
          );
          

          上面的代碼要求平臺管理者關聯NodeListFactoryList。但我們要求List實例的適配器,它會調用這個工廠。根據我們對工廠的定義,會獲得一個Node對象。在Eclispe中,這一步必須在插件啟動的時候顯式的執行,要隱式執行可以通過 org.eclipse.core.runtime.adapters 擴展點。

          3. 向List要求Node

          這里是要求適配器返回一個 Node 對象:

          Node getNodeFrom(IAdaptable list) {
            Object adaptable = list.getAdapter(Node.class);
            if (adaptable != null) {
              Node node = (Node)adaptable;
              return node;
            }
            return null;
          }
          

          總結

          如果你要在運行時為已存在的類添加功能,只要定義一個能完成轉換功能的工廠,然后注冊工程到 PlatformAdapterManager就可以了. 這項功能可以用來為一個非UI組件注冊一個指定的UI組件,同時保持兩部分的完全分離。就像在org.rcpapps.rcpnews.uiorg.rcpapps.rcpnews 插件中的使用。在這些例子中, IPropertySource 在UI插件中,它需要與非UI插件的數據相關聯。當UI插件初始化時,它注冊IPropertySourcePlatform, 當數據對象在瀏覽器中被選中時,屬性視圖中就會顯示相應的屬性。

          很明顯, java.util.List不能擴展PlatformObject, 所以你不能指望例子中的代碼能夠編譯通過,你可以重新構造 List的子類來實現目的.繼承PlatformObject 也不是必須的:

          public class AdaptableList implements IAdaptable, List {
            public Object getAdapter(Class adapter) {
               return Platform.getAdapterManager().getAdapter(this, adapter);
            }
            private List delegate = new ArrayList();
            public int size() {
              return delegate.size();
            }
            // ...
          }
          

          本例中使用了XOM 來生成XML。

          from:
          http://www.javathink.org/bbs/read.php?tid-1469-page-e.html

          posted @ 2006-07-19 21:49 CowNew開源團隊 閱讀(359) | 評論 (0)編輯 收藏


          CowNew開源團隊網站 http://www.cownew.com
          作者 楊中科 是CowNew開源團隊發起人之一,郵箱about521? at 163 dot com
          論壇 http://www.cownew.com/newpeng/
          轉載請注明此版權信息


          ?? 最近準備把進銷存項目激活,這樣一方面可以讓更多的人有機會參與到開源開發中來,另一方面也把SQL翻譯器、SQL優化器、JDBMonitor應用到這個項目中,這樣這三個基礎模塊就可以在實際項目應用中得到驗證和增強。
          ??? 我準備用hibernate實現持久層,于是到hibernate的網站上把hibernate3下載下來,看了看有個hibernatetools,是個hibernate在eclipse下的輔助工具,也down了下來,用了用感覺不錯??梢灾苯訌臄祿毂砩蒔OJO和hbm.xml(其實我不是很喜歡這種開發方式,我更喜歡我用建模工具來寫POJO,然后用工具生成hbm.xml和DDL,不過好像hibernate3現在還沒有這種工具,如果哪位朋友知道有這種工具,希望賜教)。
          美中不足的是它生成的javabean的字段名是完全和數據庫字段名一致、生成的javabean的類名是完全和數據庫表名一致。出于清晰以及可移植的考慮(也是公司的開發規范養成的習慣),我設計的表名全部以"T_"開頭,中間再加上子系統名,最后才是表意的表名,比如用“T_PS_BOM”表示生產管理系統中的物料清單表;字段名全部以“F”開頭,比如FId,FName。
          這樣就導致生成了如下的javabean:

          public class TPSBOM
          {
          ?? .......
          ?? public String getFID()
          ?? ...
          ?? public String getFNumber()
          }


          ??? 看起來很不直觀。我剛剛想放棄這個工具,想了想,“拿來就用,不好用就換”可不是做開源人該有的精神呀。鉆研一下。
          看看了Hibernate Code Generation頁簽中有一個“reveng Strategy”,什么意思?“反向工程策略”??好像有門兒,點擊“Browse”彈出一個類選擇對話框,竟然看到了它默認顯示的“DefaultReverseEngineeringStrategy”類了,我在hibernatetools的安裝目錄找來找去,終于在plugins\org.hibernate.eclipse_3.2.0.beta6\lib\tools下的hibernate-tools.jar中找到了這個類的影子,用反編譯工具反編譯一下(懶得去網上下源碼了,呵呵)。一個個方法名展現在我面前:
          tableToClassName
          columnToPropertyName
          columnToHibernateTypeName
          。。。
          ??? 這不就是在把數據庫相應的項映射成java相應的項嗎?
          ??? 開工!
          ??? 新建一個類CowNewReverseEngineeringStrategy,繼承自DefaultReverseEngineeringStrategy,override? tableToClassName、
          columnToPropertyName這兩個方法,在這兩個方法中寫入自己的轉換邏輯。
          然后打包成jar包,放到plugins\org.hibernate.eclipse_3.2.0.beta6\lib\tools下,然后在plugins\org.hibernate.eclipse_3.2.0.beta6\lib\tools\MANIFEST.MF中把這個新增包的內容加上,關閉eclipse,加個-clean參數啟動eclipse,然后點擊“Hibernate Code Generation”,把“reveng Strategy”填成“com.cownew.DevTools.hibtools.RevEng.CowNewReverseEngineeringStrategy”,“Run”?。?!
          暈倒,竟然報錯“com.cownew.DevTools.hibtools.RevEng.CowNewReverseEngineeringStrategy
          Exception while generating code
          Reason?? org.hibernate.console.HibernateConsoleRunTimeException:Could not create or find com.?? with one argument deleate constructor”

          看來是反射調用的時候出了問題,重新打開hibernate-tools.jar,仔細觀察,竟然發現了一個DelegatingReverseEngineeringStrategy,它多??? 了一個參數為“ReverseEngineeringStrategy delegate”的構造函數,而其他調用都是轉發給ReverseEngineeringStrategy了,暈倒,搞不懂它在做什么,也沒時間研究了,給CowNewReverseEngineeringStrategy也曾街一個參數為“ReverseEngineeringStrategy delegate”的構造函數,重新打包,重新啟動eclipse,哈哈,一切搞定,終于生成我可愛的,
          public class PersonInfo

          ? public String getNumber()。。。
          ? public String getId()。。。

          了。
          ??? 附全部代碼:

          package com.cownew.DevTools.hibtools.RevEng;

          import java.beans.Introspector;

          import org.hibernate.cfg.reveng.DefaultReverseEngineeringStrategy;
          import org.hibernate.cfg.reveng.ReverseEngineeringSettings;
          import org.hibernate.cfg.reveng.ReverseEngineeringStrategy;
          import org.hibernate.cfg.reveng.ReverseEngineeringStrategyUtil;
          import org.hibernate.cfg.reveng.TableIdentifier;
          import org.hibernate.util.StringHelper;

          public class CowNewReverseEngineeringStrategy extends
          DefaultReverseEngineeringStrategy
          {

          ?public CowNewReverseEngineeringStrategy(ReverseEngineeringStrategy delegate)
          ?{??
          ??super();
          ?}

          ?private ReverseEngineeringSettings settings = new ReverseEngineeringSettings();

          ?public String tableToClassName(TableIdentifier table)
          ?{
          ??String tableName = table.getName();
          ??if (tableName != null && tableName.toUpperCase().startsWith("T_"))
          ??{
          ???String pkgName = settings.getDefaultPackageName();
          ???int lastIndex = tableName.lastIndexOf('_');
          ???tableName = tableName.substring(lastIndex + 1, tableName.length())
          ?????+ "Info";

          ???String className = toUpperCamelCase(tableName);

          ???if (pkgName.length() > 0)
          ????return StringHelper.qualify(pkgName, className);
          ???return className;

          ??} else
          ??{
          ???return super.tableToClassName(table);
          ??}
          ?};

          ?public String columnToPropertyName(TableIdentifier table, String column)
          ?{
          ??if (column != null && column.toUpperCase().startsWith("F"))
          ??{
          ???String cownewColName = column.substring(1, column.length());
          ???
          ???String decapitalize = Introspector
          ?????.decapitalize(toUpperCamelCase(cownewColName));
          ???return keywordCheck(decapitalize);
          ??} else
          ??{
          ???return super.columnToPropertyName(table, column);
          ??}
          ?}

          ?private String keywordCheck(String possibleKeyword)
          ?{
          ??if (ReverseEngineeringStrategyUtil
          ????.isReservedJavaKeyword(possibleKeyword))
          ???possibleKeyword += "_";
          ??return possibleKeyword;
          ?}

          ?public void setSettings(ReverseEngineeringSettings settings)
          ?{
          ??super.setSettings(settings);
          ??this.settings = settings;
          ?}

          ?public static void main(String[] args)
          ?{
          ??TableIdentifier table = new TableIdentifier("T_BD_Person");
          ??//TableIdentifier table = new TableIdentifier("T_Person");
          ??//TableIdentifier table = new TableIdentifier("Person");
          ??CowNewReverseEngineeringStrategy revEng = new CowNewReverseEngineeringStrategy(null);
          ??String className = revEng.tableToClassName(table);
          ??System.out.println(className);
          ??System.out.println(revEng.columnToPropertyName(table, "FId"));
          ??System.out.println(revEng.columnToPropertyName(table, "Id"));
          ?}
          }


          ?

          posted @ 2006-07-16 22:27 CowNew開源團隊 閱讀(1522) | 評論 (4)編輯 收藏

          CowNew開源團隊網站 http://www.cownew.com
          作者是CowNew開源團隊發起人之一,郵箱about521? at 163 dot com
          論壇 http://www.cownew.com/newpeng/
          轉載請注明此版權信息


          java做的系統給人的印象是什么?占內存!說道這句話就會有N多人站出來為java辯護,并舉出一堆的性能測試報告來證明這一點。其實從理論上來講java做的系統并不比其他語言開發出來的系統更占用內存,那么為什么卻有這么N多理由來證明它確實占內存呢???兩個字,陋習。
          (1)別用new Boolean()。
          在很多場景中Boolean類型是必須的,比如JDBC中boolean類型的set與get都是通過Boolean封裝傳遞的,大部分ORM也是用Boolean來封裝boolean類型的,比如:
          ps.setBoolean("isClosed",new Boolean(true));
          ps.setBoolean("isClosed",new Boolean(isClosed));
          ps.setBoolean("isClosed",new Boolean(i==3));

          通常這些系統中構造的Boolean實例的個數是相當多的,所以系統中充滿了大量Boolean實例小對象,這是相當消耗內存的。
          Boolean類實際上只要兩個實例就夠了,一個true的實例,一個false的實例。
          Boolean類提供兩了個靜態變量:
          public static final Boolean TRUE = new Boolean(true);
          public static final Boolean FALSE = new Boolean(false);
          需要的時候只要取這兩個變量就可以了,
          比如:
          ps.setBoolean("isClosed",Boolean.TRUE);

          那么象2、3句那樣要根據一個boolean變量來創建一個Boolean怎么辦呢?可以使用Boolean提供的靜態方法:?? Boolean.valueOf()
          比如:
          ?
          ps.setBoolean("isClosed",Boolean.valueOf(isClosed));
          ps.setBoolean("isClosed",Boolean.valueOf(i==3));
          因為valueOf的內部實現是:
          return (b ? TRUE : FALSE);
          所以可以節省大量內存。

          相信如果Java規范直接把Boolean的構造函數規定成private,就再也不會出現這種情況了。
          (2)別用new Integer。
          和Boolean類似,java開發中使用Integer封裝int的場合也非常多,并且通常用int表示的數值通常都非常小。
          SUN SDK中對Integer的實例化進行了優化,Integer類緩存了-128到127這256個狀態的Integer,如果使用Integer.valueOf(int i),傳入的int范圍正好在此內,就返回靜態實例。
          這樣如果我們使用Integer.valueOf代替new Integer的話也將大大降低內存的占用。如果您的系統要在不同的SDK(比如IBM SDK)中使用的話,那么可以自己做了工具類封裝一下,比如IntegerUtils.valueOf(),這樣就可以在任何SDK中都可以使用這種特性。

          (3)用StringBuffer代替字符串相加。這個我就不多講了,因為已經被人講過N次了。我只想將一個不是笑話的笑話,我在看國內某“著名”java開發的WEB系統的源碼中,竟然發現其中大量的使用字符串相加,一個拼裝SQL語句的方法中竟然最多構造了將近100個string實例。無語中!
          (4)過濫使用哈希表,有一定開發經驗的開發人員經常會使用hash表(hash表在JDK中的一個實現就是HashMap)來緩存一些數據,從而提高系統的運行速度。比如使用HashMap緩存一些物料信息、人員信息等基礎資料,這在提高系統速度的同時也加大了系統的內存占用,特別是當緩存的資料比較多的時候。其實我們可以使用操作系統中的緩存的概念來解決這個問題,也就是給被緩存的分配一個一定大小的緩存容器,按照一定的算法淘汰不需要繼續緩存的對象,這樣一方面會因為進行了對象緩存而提高了系統的運行效率,同時由于緩存容器不是無限制擴大,從而也減少了系統的內存占用?,F在有很多開源的緩存實現項目,比如ehcache、oscache等,這些項目都實現了FIFO、MRU等常見的緩存算法。
          (5)避免過深的類層次結構和過深的方法調用。因為這兩者都是非常占用內存的(特別是方法調用更是堆棧空間的消耗大戶)。

          (6)變量只有在用到它的時候才定義和實例化。
          (7)盡量避免使用static變量,類內私有常量可以用final來代替。

          posted @ 2006-07-14 23:50 CowNew開源團隊 閱讀(1277) | 評論 (3)編輯 收藏

          ??????? 很多關心CowNew的朋友紛紛給我發email或者qq留言,說看到最近CowNew開源項目沒有動靜了,問我是不是虎頭蛇尾死掉了。謝謝大家的關心,CowNew沒有停止進步的步伐,最近一段時間沒有動靜是因為我們在悶頭做產品的開發。經過一個多月的努力,在kingchou、紫龍等隊友的團結奮斗下,SQL解析引擎和JDBMonitor都已經取得了階段性的成果。
          ??????? SQL解析引擎已經可以生成完整的異構SQLAST,除有少數小bug之外已經基本達到了預期的目標。另外在SQL解析引擎基礎上開發的CowNewSQL翻譯器也可以實現了基本的功能??梢苑g大部分主流的sql語句,比如:
          (1)可以將符合CowNewSQL語法的select now()翻譯成對應如下的特定平臺sql:
          mssql:Select GETDATE()
          mysql:Select NOW()
          oracle8i:Select SYSDATE FROM DUAL
          oracle9i:Select SYSDATE FROM DUAL
          (2)可以將符合CowNewSQL語法的
          update T2 set fid=t1.fid from (select * from t2
          left join t3 on t3.fid=t2.fid union select * from t5)
          翻譯成對應如下的特定平臺sql:
          mssql:UPDATE T2 SET fid = t1.fid
          FROM(
          Select *
          From t2 left join t3 on t3.fid = t2.fid
          union Select *
          From t5
          )
          mysql:UPDATE T2 SET fid = t1.fid
          FROM(
          Select *
          From t2 left join t3 on t3.fid = t2.fid
          union Select *
          From t5
          )
          oracle8i:UPDATE T2 SET fid = t1.fid
          FROM(
          Select *
          From t2,t3 WHERE t3.fid = t2.fid(+)
          union Select *
          From t5
          )
          oracle9i:UPDATE T2 SET fid = t1.fid
          FROM(
          Select *
          From t2 left join t3 on t3.fid = t2.fid
          union Select *
          From t5
          )

          (2)可以將符合CowNewSQL語法的
          select top 20 ABS(-1),lcase(trim(name)),tochar(now()), ADD_SECONDS(now(),22),t2.name,DateAdd(Year,now(),3) from T_Table
          ,(select * from T_MD where FID=2222222222) as tmd
          left join T_T4 on tmd.id>T_Table.id
          left join T_T2 as t2 on T_T2.id=T_Table.id
          right join T_T3 as t3 on t2.id=t3.id
          翻譯成對應如下的特定平臺sql:
          mssql:Select? top 20
          ?ABS(-1) , LOWER(LTRIM(RTRIM(name)) ,CONVERT(VARCHAR, GETDATE()),DATEADD(second,GETDATE(),22),t2.name,DATEADD(Year, GETDATE(), 3)
          From T_Table,
          Select *
          From T_MD
          Where FID = 2222222222 as tmd
          ?left join T_T4 on tmd.id > T_Table.id left join T_T2 as t2 on T_T2.id = T_Table.id right join T_T3 as t3 on t2.id = t3.id
          mysql:Select? ABS(-1) , LOWER(LTRIM(RTRIM(name)) ,CONCAT('', NOW()),DATE_ADD(NOW(), INTERVAL 22 SECOND),t2.name,DATE_ADD(3, INTERVAL NOW() YEAR)
          From T_Table,
          Select *
          From T_MD
          Where FID = 2222222222 as tmd
          ?left join T_T4 on tmd.id > T_Table.id left join T_T2 as t2 on T_T2.id = T_Table.id right join T_T3 as t3 on t2.id = t3.id limit 0, 20

          oracle8i:Select? ABS(-1) , LOWER(LTRIM(RTRIM(name)) , TO_CHAR(SYSDATE) ,(SYSDATE + 22/86400),t2.name,add_months(3, TRUNC(SYSDATE) * 12)
          From T_Table,
          Select *
          From T_MD
          Where FID = 2222222222 as tmd
          ,T_T4,T_T2 as t2,T_T3 as t3 WHERE ROWNUM <= 20
          ?AND tmd.id > T_Table.id(+) AND T_T2.id = T_Table.id(+) AND t2.id(+) = t3.id
          oracle9i:Select? ABS(-1) , LOWER(LTRIM(RTRIM(name)) , TO_CHAR(SYSDATE) ,(SYSDATE + 22/86400),t2.name,add_months(3, TRUNC(SYSDATE) * 12)
          From T_Table,
          Select *
          From T_MD
          Where FID = 2222222222 as tmd
          ?left join T_T4 on tmd.id > T_Table.id left join T_T2 as t2 on T_T2.id = T_Table.id right join T_T3 as t3 on t2.id = t3.id WHERE ROWNUM <= 20

          ??????? 但是這些sql翻譯只是按照語法手冊進行的翻譯,還沒有經過正式數據庫環境的測試,還需要進一步的測試。
          ??????? 目前僅支持MSSQLSERVER,MYSQL,Oracle8i,Oracle9i,我們計劃進一步支持DB2UDB,FireBird、ACCESS等數據庫。而且SQL解析引擎是用JDK5開發的,我們將是用Retrotranslator將其轉換個以保證可以在JDK1.4上運行。

          ??????? JDBMonitor的需求已經基本完成,但是新增的功能目前只能運行在MSSQLSERVER上,我們準備等COWNEWSQL翻譯器開發完畢后,將JDBMonitor涉及到數據庫操作的地方是用COWNEWSQL翻譯器來完成多數據庫支持,所以我們將會推遲JDBMonitor的原計劃的發版日期。
          ??????? 目前我們的項目還是很缺乏高手,比如CowNewSQL這塊就缺乏對各種數據庫比較熟悉的朋友,還有能對CowNewSQL進行全面測試的朋友,希望對這方面開發比較感興趣的能加入到我們的開發中來,共同打造優秀的開源產品。可以直接給我發送郵件about521 at 163.com

          posted @ 2006-07-03 00:35 CowNew開源團隊 閱讀(2721) | 評論 (0)編輯 收藏

          以下內容轉自韓寒的“太變態了!”
          "
          ?
          ... ...
          今年的超級女聲開始了,
          加油好男兒也開始了,
          但是我發現,
          就我看的這些選手里,
          明顯有點問題,
          仿佛兩個節目弄反了,
          男的全是能擠出奶來的,
          還經常對著鏡頭耶耶耶耶的,
          耶他大爺..
          女的全是弄成男人樣還壓低嗓子說話的.
          總之就是,
          讓異性看著都一點性欲沒有.
          太變態了.
          太變態了.
          我相信超級女聲里很多是趕時髦,
          可能性格并不如此,
          但那些男的,
          我真恨不得沖上去對著他們的褲襠就是一腳... ..."
          posted @ 2006-06-23 18:40 CowNew開源團隊 閱讀(345) | 評論 (1)編輯 收藏

          CowNew開源團隊網站 http://www.cownew.com
          作者 楊中科 是CowNew開源團隊JDBMonitor開發組的開發人員,郵箱about521? at 163 dot com
          論壇 http://www.cownew.com/newpeng/
          轉載請注明此版權信息
          以前我一直是用使用數據源的系統測試JDBMonitor,昨天我準備把JDBMonitor嵌入到一個小的jsp留言板中,這個留言板寫的非常簡單,數據庫操作也是connection隨取隨用、用完了就關這種最簡單的形式,這倒是幫助我發現了一個超級大bug。
          在記事本運行中常常不規律的DataBaseDBListener的logSQL方法報空指針錯誤,是在logStatement.setString(1, randomGUID.toString());這一句拋出的,我跟蹤到mysql驅動的內部(我使用的是mysql數據庫做DataBaseDBListener的輸出數據庫),發現在setString的實現中會去調用connection的方法,而此時connection已經是null了,所以會報空指針錯誤。
          從其不規律的特點我判斷出應該是多線程導致的問題。我跟蹤發現,有的時候是先調用DataBaseDBListener的close后logSql才被調用。經過分析找出了問題所在,問題就在DBLogger中內部類LogConsumer的startConsumer方法,這個是修改以前的代碼:
          for (;;)
          ?{
          ??SQLInfo info = (SQLInfo) channel.take();????

          ??if(info==null)
          ??{
          ???ontinue;
          ??}
          ??for (int i = 0, n = dbListeners.length; i < n; i++)
          ??{
          ???dbListeners[i].logSql(info);
          ??}

          ?}


          在調用channel.take()以后,這個SQLInfo就從channel中去除了。這時如果DBLogger的方法被調用,那么即使dbListeners[i].logSql(info)仍然在運行,但是DBLogger會認為channel已經空了,所有的dbListeners都可以被close了,而在DataBaseDBListener的close方法中會把輸出目標數據庫connection關掉,那么此時如果DataBaseDBListener的logSql方法還在調用的話,那么一旦使用這個connection,那么就會出現錯誤了。
          我是如下修改的:
          修改BlockedChannel類,去掉其take方法,增加一個peek方法和一個remove方法,peek方法是從channel中查出一個對象,但是不把它從channel中移走,只有調用remove方法后才會被移走。
          修改DBLogger中內部類LogConsumer的startConsumer方法為如下:
          for (;;)
          ?{
          ??SQLInfo info = (SQLInfo) channel.peek();
          ??if(info==null)
          ??{
          ???continue;
          ??}
          ??for (int i = 0, n = dbListeners.length; i < n; i++)
          ??{
          ???dbListeners[i].logSql(info);
          ??}
          ??channel.remove(info);
          ?}

          也就是只有SQLInfo被處理完了,才會從channel中移走。
          看來JDBMonitor還是要多多測試多多驗證,我近期準備對JDBMonitor進行性能測試,看看有沒有并發問題有沒有性能問題,不要再急著加新功能了,把這些基礎的功能做好再說,否則別人用著用著就出現中斷性錯誤了,那將會是比缺少功能更可怕的事情。一位同事曾經說過一句話:“做的越多錯的越多。不要你做的多好,只要把已經做完的東西做的更好就可以了?!保磥泶_實有一定道理呀。把基本的東西做好再說,否則被人罵不專業就慘了。

          posted @ 2006-06-15 22:52 CowNew開源團隊 閱讀(833) | 評論 (0)編輯 收藏

          CowNew開源團隊網站 http://www.cownew.com
          論壇 http://www.cownew.com/newpeng/
          轉載請注明此版權信息

          今天做的事情比較雜,所以感想也比較雜:
          1、java程序的遠程調試。
          “JPDA是sun jdk自帶的遠程調試機制。它提供了一套標準的調試接口,可以從虛擬機一級允許外界用特定協議探測虛擬機內部的運作細節。只要你裝了jdk 1.2以上的sun jdk,就已經有了jpda支持。 只要是用標準JDK中java.exe運行的應用,就可以用jpda進行遠程調試。以web應用的開發為例,servlet和ejb的調試一直不是一件太容易的事情。雖然jbuilder、eclipse等有一些常見的應用服務器,如tomcat, weblogic 6.x,的調試插件,但是用法各不相同,而且很容易由于版本問題導致出現各種問題,而且對于有的服務器則沒有相應的IDE插件。
          JPDA就不一樣。由于它是java平臺的標準功能之一,所以我們其實可以調試任何用jdk運行的程序。只需要做兩件事:
          (1)、 在被調試的應用上,增加幾個java虛擬機啟動參數,讓它啟動后進入調試服務器模式;
          (2) 在本機或網絡中另一臺機器上用某種jpda客戶端程序,attach到被調試的應用程序(可以通過socket或共享內存兩種方式)。jpda本身只是一個接口,調試工具的好用與否就要看其對jpda的應用如何。jdb是sun jdk自帶的命令行jpda調試客戶程序,你可以用命令行設置斷點,查看變量值,等等。但不是很直觀。而jbuilder、eclipse的jpda調試器就做到了將jpda圖形化,可以直觀的設置斷點,跟蹤程序,查看量值,等等。 ”---本段改編自“http://www.cjsdn.com/post/print?bid=7&id=1376”

          以elipse+tomcat為例:
          (1)打開Tomcat 5.0\bin下的catalina.bat,在“set JPDA= ”下加入如下兩行:
          set JPDA_TRANSPORT=dt_socket
          set JPDA_ADDRESS=8787
          (2)啟動tomcat
          (3)在eclipse的debug中新建一個“Remote Java Application”,工程選擇被調試的遠程程序的源碼工程,host填127.0.0.1,port為8787
          (4)運行調試。
          這樣我們就可以在eclipse中下斷點調試tomcat中運行的程序了。讓那些亂七八糟的插件哪涼快去哪呆著吧。
          注意一定要保證eclipse工程中的源碼和tomcat中運行的程序一致。

          2、調用對象的wait方法的時候有可能會拋出InterruptedException異常,以前我是把這個異常再次拋出,今天運行發現當這個異常拋出的時候,線程就死掉了。因此不能簡單的將此異常re-throw,必須處理它,比如JDBMonitor中的BlockedChannel的take方法就要如下改寫:
          public synchronized Object take()
          ?{
          ??if (container.isEmpty())
          ??{
          ???try
          ???{
          ????wait();
          ???} catch (InterruptedException e)
          ???{
          ????return null;
          ???}
          ??}
          ??Object obj = container.pop();
          ??return obj;
          ?}

          3、windows下運行linux的最好的工具
          最近一直想驗證JDBMonitor在linux底下是否有bug,但是聽人說過,linux安裝不當很容易發生數據丟失,因此一直不敢裝。而用virtual PC,VMWare之類的軟件又太消耗內存,而且需要虛擬機安裝完成再安裝linux。今天無意中搜索到一個windows下的linux虛擬機:MetroPipe VPM 。
          下載地址:
          http://www.metropipe.net/ProductsPVPMDownload.shtml
          解壓后直接運行其中的qemu-win.bat就能啟動Linux。不用安裝,啟動關閉都非???,而且占用內存相對來說比較小。
          唯一一個缺點就是默認就進入圖形模式,抽時間看看怎么配置讓它啟動以后進入字符模式。
          詳細可以參考:http://www.highand.com/viewthread.php?tid=545

          ?

          posted @ 2006-06-13 01:06 CowNew開源團隊 閱讀(964) | 評論 (0)編輯 收藏

          對于一個新手來說,安裝Linux勢必會帶來很大的風險。膽子小的最后決定繼續享受Windows,膽子大的有一些不幸地丟失了硬盤中的所有數據?,F在你不必提心吊膽了!在Windows下你可以輕易運行Linux,無需安裝,你只要下載一個MetroPipe VPM(以下簡稱VPM),解壓后運行一下就OK了。

          QUOTE:

          MetroPipe VPM 小檔案

          軟件版本:不詳 軟件大?。?3MB
          軟件性質:免費 適用平臺:Windows/Linux
          下載地址:http://www.metropipe.net/ProductsPVPMDownload.shtml
          軟件備注:在下載頁面中包含了多種下載方式,建議使用“Download.zip file via HTTP”右側的Download按鈕下載。


          VPM其實是一個多平臺的小型虛擬機軟件,這個壓縮包中包含了一個完整的Linux版本。解壓后直接運行其中的qemu-win.bat就能啟動Linux(如果硬盤配置較低,啟動時間會比較長),根據彈出窗口的提示回車登錄Linux,出現桌面后就能和普通Linux一樣cao作了。磁盤目錄結構、命令等都和普通的Linux完全相同,如果想練手的話非常合適。


          *為什么鼠標逃不出Linux窗口了

          進入Linux之后,你會發現鼠標無法脫離Linux窗口了,要再次回到Windows,可以使用組合鍵“Ctrl+Shift”。


          *能否全屏顯示

          使用組合鍵“Ctrl+Shift+F"(要回到窗口模式只需再按一次)就能全屏cao作Linux,但是全屏之后 屏閃比較嚴重,還是窗口模式比較對得起自己的眼睛。

          *在這個Linux中能否上網

          運行后直接映射Windows中當前存在的網絡連接,無需手動配置。可以用Linux中自帶的FireFox看網頁、Thunderbird收郵件、axFTP上傳文件,但可惜只支持英語

          *小提示
          要關閉時可以直接關閉窗口,也可以右鍵點擊桌面空白處選擇“Power Down→Shutdown”。


          摘自《電腦愛好者》2006年第5期 Page 40

          posted @ 2006-06-12 23:59 CowNew開源團隊 閱讀(1610) | 評論 (0)編輯 收藏

          僅列出標題
          共30頁: First 上一頁 19 20 21 22 23 24 25 26 27 下一頁 Last 
          主站蜘蛛池模板: 佛坪县| 衡阳县| 汕尾市| 墨玉县| 西和县| 南乐县| 新闻| 浠水县| 宽城| 桦甸市| 水富县| 唐海县| 青浦区| 四平市| 车致| 新竹市| 赞皇县| 道真| 同德县| 乌恰县| 尼木县| 封开县| 蓬莱市| 运城市| 洛浦县| 吉水县| 米泉市| 从江县| 通化市| 仁化县| 娱乐| 武平县| 万盛区| 定西市| 宜黄县| 西华县| 昆明市| 新闻| 临泽县| 五原县| 准格尔旗|