#
一、實時查看帶寬bmon官方站點:http://people.suug.ch/~tgr/bmon/gentoo:安裝:emerge net-analyzer/bmon基本用法:bmon -o ascii -p eth0其它linux系統可參照官方站點的說明使用。二、帶寬統計vnstat官方站點:http://humdi.net/vnstat/gentoo:安裝:emerge vnstat第一次使用需要對每個網卡運行:#vnstat -u -i eth0 ……1、查看5秒內網卡eth0的平均流量:#vnstat -tr -i eth02、網卡eth0一周內的流量:#vnstat -i eth0 -w
摘要: 一、決策樹簡介: 關于決策樹,幾乎是數據挖掘分類算法中最先介紹到的。決策樹,顧名思義就是用來做決定的樹,一個分支就是一個決策過程。 每個決策過程中涉及一個數據的屬性,而且只涉及一個。然后遞歸地,貪心地直到滿足決策條件(即可以得到明確的決策結果)。 決策樹的實現首先要有一些先驗(已經知道結果的歷史)數據做訓練,通過分析訓練數據得到每個屬性對結果的影響的大小,這里我們通過... 閱讀全文
摘要: 之前做了一個統計商鋪的PV,UV值 大體思路:每天將用戶的訪問信息放到明細表里,然后在第二天的凌晨將這些數據歸總 PVUV表 4個字段:主鍵pk 用戶IP(customer_ip) 訪問時間(time) 商鋪ID(store_id) 統計TOTAL表&... 閱讀全文
網上有好幾種方法可以將將HTML文件轉換成PDF文件但是有些對HTML文件格式要求比較嚴格,稍微錯了一些就不能生成我們所要的PDF文件,這里我推薦一個 PD4ML,它可以解決HTML文件格式不正確的問題,可以生成一個比較好的PDF文件,其處理速度快,而且對CSS文件兼容的非常好。下面是最基本的PD4ML編程:- package samples;
-
- import java.awt.Insets;
- import java.io.File;
- import java.io.IOException;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.security.InvalidParameterException;
-
- import org.zefer.pd4ml.PD4Constants;
- import org.zefer.pd4ml.PD4ML;
-
- public class GettingStarted1 {
- protected int topValue = 10;
- protected int leftValue = 20;
- protected int rightValue = 10;
- protected int bottomValue = 10;
- protected int userSpaceWidth = 1300;
-
- public static void main(String[] args) {
- try {
- GettingStarted1 jt = new GettingStarted1();
- jt.doConversion("http://pd4ml.com/sample.htm", "c:/pd4ml.pdf");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public void doConversion( String url, String outputPath )
- throws InvalidParameterException, MalformedURLException, IOException {
- File output = new File(outputPath);
- java.io.FileOutputStream fos = new java.io.FileOutputStream(output);
-
- PD4ML pd4ml = new PD4ML();
-
- pd4ml.setHtmlWidth(userSpaceWidth); // set frame width of "virtual web browser"
-
- // choose target paper format and "rotate" it to landscape orientation
- pd4ml.setPageSize(pd4ml.changePageOrientation(PD4Constants.A4));
-
- // define PDF page margins
- pd4ml.setPageInsetsMM(new Insets(topValue, leftValue, bottomValue, rightValue));
-
- // source HTML document also may have margins, could be suppressed this way
- // (PD4ML *Pro* feature):
- pd4ml.addStyle("BODY {margin: 0}", true);
-
- // If built-in basic PDF fonts are not sufficient or
- // if you need to output non-Latin texts,
- // TTF embedding feature should help (PD4ML *Pro*)
- pd4ml.useTTF("c:/windows/fonts", true);
-
- pd4ml.render(new URL(url), fos); // actual document conversion from URL to file
- fos.close();
-
- System.out.println( outputPath + "\ndone." );
- }
- }
The following Java class slightly changes the above example. Now it pre-reads source HTML to a string and passes it torender()method wrapped toStringReader. First it writes PDF bytes toByteArrayOutputStream, which makes possible to measure size of the resulting document.A disadvantage of the method is a bigger RAM utilization. - package samples;
-
- import java.awt.Insets;;
- import java.io.BufferedInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.StringReader;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.security.InvalidParameterException;
-
- import org.zefer.pd4ml.PD4Constants;
- import org.zefer.pd4ml.PD4ML;
-
- public class GettingStarted2 {
- protected int topValue = 10;
- protected int leftValue = 20;
- protected int rightValue = 10;
- protected int bottomValue = 10;
- protected int userSpaceWidth = 1300;
-
- public static void main(String[] args) {
- try {
- GettingStarted2 jt = new GettingStarted2();
- String html = readFile("c:/sample.htm", "UTF-8");
- jt.doConversion2(html, "c:/pd4ml.pdf");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public void doConversion2( String htmlDocument, String outputPath )
- throws InvalidParameterException, MalformedURLException, IOException {
-
- PD4ML pd4ml = new PD4ML();
-
- pd4ml.setHtmlWidth(userSpaceWidth); // set frame width of "virtual web browser"
-
- // choose target paper format
- pd4ml.setPageSize(pd4ml.changePageOrientation(PD4Constants.A4));
-
- // define PDF page margins
- pd4ml.setPageInsetsMM(new Insets(topValue, leftValue, bottomValue, rightValue));
-
- // source HTML document also may have margins, could be suppressed this way
- // (PD4ML *Pro* feature):
- pd4ml.addStyle("BODY {margin: 0}", true);
-
- // If built-in basic PDF fonts are not sufficient or
- // if you need to output non-Latin texts, TTF embedding feature should help
- // (PD4ML *Pro*)
- pd4ml.useTTF("c:/windows/fonts", true);
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- // actual document conversion from HTML string to byte array
- pd4ml.render(new StringReader(htmlDocument), baos);
- // if the HTML has relative references to images etc,
- // use render() method with baseDirectory parameter instead
- baos.close();
-
- System.out.println( "resulting PDF size: " + baos.size() + " bytes" );
- // in Web scenarios it is a good idea to send the size with
- // "Content-length" HTTP header
-
- File output = new File(outputPath);
- java.io.FileOutputStream fos = new java.io.FileOutputStream(output);
- fos.write( baos.toByteArray() );
- fos.close();
-
- System.out.println( outputPath + "\ndone." );
- }
-
- private final static String readFile( String path, String encoding ) throws IOException {
-
- File f = new File( path );
- FileInputStream is = new FileInputStream(f);
- BufferedInputStream bis = new BufferedInputStream(is);
-
- ByteArrayOutputStream fos = new ByteArrayOutputStream();
- byte buffer[] = new byte[2048];
-
- int read;
- do {
- read = is.read(buffer, 0, buffer.length);
- if (read > 0) {
- fos.write(buffer, 0, read);
- }
- } while (read > -1);
-
- fos.close();
- bis.close();
- is.close();
-
- return fos.toString(encoding);
- }
- }
先說一下應用環境: 采用Tilera的平臺(一種眾核平臺,),三張網卡,兩個10G的xgbe網卡,用來進行數據的發送和接受;一個1G的普通網卡,用來做管理接口.
10G的xgbe工作在Tilera的特定sdk下,其中的數據包不經過內核協議棧,直接交付給用戶。這樣的好處是數據處理效率很高(普通的linux協議棧中需要兩次內存的拷貝,效率低),但是也因此帶來了一些問題,有些包需要交給標準的協議棧 ,比如ospf報文,zebra工作在用戶態,需要從標準的協議棧內獲取網絡數據包,而xgbe是不會直接把數據交付給標準協議棧的。
TAP虛擬網卡是Linux標準的虛擬網絡設備,在Tilera平臺上其編程也是一樣的。 擁有這樣的虛擬網卡后可以利用其通用linux協議棧的特性,并可以將數據包交付應用層的socket程序處理。ospfd程序就可以利用TAP進程收到ospf報文,并發布默認路由出去。 

上圖是TAP網卡的收發包流程圖 左側紅色箭頭標示的為從協議棧經TAP網卡發包標示,對從tap讀進來的包進行一下netio封裝,然后經過xbge發送出去 右側綠色箭頭標示的為數據包經TAP網卡收至協議棧的流程,調用netio(tilera 特定的網絡編程api)從xgbe中收到發送給tap的報后,經過包處理進程將數據包交付給TAP進程,其實就是將收到的包寫進tap網卡中,這樣用戶進程就可以再內核協議棧中接受到通過xgbe發送來的包。
存儲過程是一組預先編譯好的sql語句。將他放在服務器上面,由用戶通過指定存儲過程的名字來執行它。 存儲過程的優點: 封裝——可用于操作數據庫對象的方法,用戶只需要知道它的輸入輸出參數并理解其目的即可。 改善性能——已經預先編譯 減少網絡流量——只返回最后的結果集 重要性——針對復雜邏輯,應用已經測試號的存儲過程,不容易發生錯誤。 安全性——如果數據庫擁有者DBO或者系統管理員SA編譯并保存了存儲結構,存儲過程就有了對它使用的數據庫對象的所有訪問權限。因此系統管理員可以向單獨的用于授予對數據對象的最小訪問權限,而不是直接允許用戶使用數據庫對象。 這次項目開發中運用了不少的存儲過程,中間遇到了一個小問題,大家可以看看: 事情是這樣的:我想根據卡號、教師編號、教師姓名、聯系電話這四個條件查詢教師編號,這四個條件可以不存在,可以只存在一個,可以只存在兩個,可以只存在三個,可以存在四個。開始我寫的存儲過程是這樣的 - <span style="font-size:24px;">CREATE PROCEDURE [dbo].[procCardByMore]</span>
- @cardNo varchar (50),
- @TeacherID varchar(50),
- @Name varchar(50),
- @telephone varchar(50)
- AS
- DECLARE @sql varchar(1000)
- SET @sql='SELECT TeacherID as 教師編號,Name as 教師姓名,GradeName as 所屬年級,cardNo as 卡號,cash as 卡內余額,realName as 管理員,OpenTime as 開卡時間,state as 狀態,telephone as 聯系電話 FROM view_CardDetail '
-
- IF(@cardNo <>'')
- BEGIN
- SET @sql=@sql+'and cardNo ='''+@cardNo+''''
- END
-
- IF(@TeacherID <>'')
- BEGIN
- SET @sql=@sql+'and TeacherID ='''+@TeacherID+''''
- END
-
- IF(@Name <>'')
- BEGIN
- SET @sql=@sql+'and Name ='''+@Name +''''
- END
-
- IF(@Name <>'')
- BEGIN
- SET @sql=@sql+'and telephone ='''+@telephone +''''
- END
-
- exec(@sql)
這里面假如卡號不為空的話,那么寫出來的sql語句是這樣的: - SELECT TeacherID as 教師編號,Name as 教師姓名,GradeName as 所屬年級,cardNo as 卡號,cash as 卡內余額,realName as 管理員,OpenTime as 開卡時間,state as 狀態,telephone as 聯系電話FROM view_CardDetail and cardNo ='@cardNo’
這句話顯然是錯誤的,在查詢語句和條件的過渡的地方沒有where,而是突然來了個and。然而這個時候如果加上個必然條件那就完美了,接下來的存儲過程創建語句是這樣的: - CREATE PROCEDURE [dbo].[procCardByMore]
- @cardNo varchar (50),
- @TeacherID varchar(50),
- @Name varchar(50),
- @telephone varchar(50)
- AS
- DECLARE @sql varchar(1000)
- SET @sql='SELECT TeacherID as 教師編號,Name as 教師姓名,GradeName as 所屬年級,cardNo as 卡號,cash as 卡內余額,realName as 管理員,OpenTime as 開卡時間,state as 狀態,telephone as 聯系電話FROM view_CardDetail WHERE 1=1 '
-
- IF(@cardNo <>'')
- BEGIN
- SET @sql=@sql+'and cardNo ='''+@cardNo+''''
- END
-
- IF(@TeacherID <>'')
- BEGIN
- SET @sql=@sql+'and TeacherID ='''+@TeacherID+''''
- END
-
- IF(@Name <>'')
- BEGIN
- SET @sql=@sql+'and Name ='''+@Name +''''
- END
-
- IF(@Name <>'')
- BEGIN
- SET @sql=@sql+'and telephone ='''+@telephone +''''
- END
-
- exec(@sql)
這樣的話執行出來的結果是這樣的: - SELECT TeacherID as 教師編號,Nameas 教師姓名,GradeName as 所屬年級,cardNo as 卡號,cashas 卡內余額,realName as 管理員,OpenTime as 開卡時間,stateas 狀態,telephone as 聯系電話FROM view_CardDetail WHERE 1=1and cardNo ='+@cardNo+'
必然條件在這里充當了橋梁的作用,雖然我們沒有“1=1“的需求,但是它的存在卻恰好解決了兩者互不相容的尷尬局面。 受上面的啟發,下面的情況是這樣解決的: 需要根據教師編號和起始日期查詢教師的消費記錄情況,兩個條件的存在情況各自隨便。 存儲過程代碼如下: - CREATE PROCEDURE [dbo].[procConsumeByMore]
- @TeacherID varchar(50),
- @TimeStart datetime,
- @TimeEnd datetime
- AS
- DECLARE @sql varchar(1000)
- SET @sql='SELECT TeacherID as 教師編號,Name as 教師姓名,orderID as 訂單編號,adultNum as 成人數量,childNum as 兒童數量,consumeCash as 消費金額,consumeTime as 消費時間,userID as 管理員編號,realName as 管理員姓名FROM view_consumeDetail WHERE 1=1 '
-
-
- IF(@TeacherID <>'')
- BEGIN
- SET @sql=@sql+'and TeacherID ='''+@TeacherID+''''
- END
-
- IF( @TimeStart<>null and @TimeEnd<>null)
- BEGIN
- SET @sql=@sql+'and consumeTime between '''+@TimeStart +''' and '''+@TimeEnd+''''
- END
-
- exec(@sql)
這里當@TimeStart和@TimeEnd為空的時候,空字符串不能轉換成日期類型,這時候假如兩個變量為空,我可以給他們賦一個完全的值: - exec procConsumeByMore '', '1799-01-01','9999-12-29'
如上面的代碼就可以選擇出所有的消費記錄了。 上面兩件事情中必然事件這個配角起了不可忽視的作用,然而必然事件卻不是我們在查詢過程中需要的條件。 生活中配角并不意味著無趣和呆板,配角一樣可以靈動,只是它把對別人的善意放在第一位,不把張揚作為表達自己的方式。‘上善若水,水善利萬物而不爭’,但是水又無處不在,其實就是這樣一種狀態。創造一個最好的配角,并不比創造一個主角容易。
寫了一個簡單的委托的試用測試: 首先創建FunctionTest類,聲明委托: FunctionTest.h
[java] view plaincopyprint? // // FunctionTest.h // DelegateDemo // // Created by shx on 12-7-17. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. // #import <Foundation/Foundation.h> @protocol FunctionTestDelegate; @interface FunctionTest : NSObject { id <FunctionTestDelegate> delegate; } @property (nonatomic, assign)id <FunctionTestDelegate> delegate; - (void)func1; - (void)func2; @end @protocol FunctionTestDelegate <NSObject> - (void)func3; - (void)func4; @end FunctionTest.m [java] view plaincopyprint? // // FunctionTest.m // DelegateDemo // // Created by shx on 12-7-17. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. // #import "FunctionTest.h" @implementation FunctionTest @synthesize delegate; - (void)func1 { NSLog(@"function 1 called  "); [delegate performSelector:@selector(func3)]; } - (void)func2 { NSLog(@"function 2 called  "); [delegate performSelector:@selector(func4)]; } @end 在appdelegate中實現委托: [java] view plaincopyprint? // // AppDelegate.h // DelegateDemo // // Created by shx on 12-7-17. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. // #import <UIKit/UIKit.h> #import "FunctionTest.h" @class ViewController; @interface AppDelegate : UIResponder <UIApplicationDelegate,FunctionTestDelegate> { FunctionTest *test; } @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) ViewController *viewController; @end AppDelegate.m中實現: [java] view plaincopyprint? #pragma mark -FunctionTestDelegate - (void)func3 { NSLog(@"function 3 called  ns"); } - (void)func4 { NSLog(@"function 4 called  ns"); } 在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 調用添加: [java] view plaincopyprint? test = [[FunctionTest alloc]init]; test.delegate = self; [test func1]; [test func2];
package gongzibai.co.cc; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.BaseAdapter; import android.widget.Gallery; import android.widget.ImageView; import android.widget.Toast; public class Gallery1Activity extends Activity { public static final int CHANGE_BANNER = 1; private int cur_index = 0; /** Called when the activity is first created. */ @Override public void onCreate( Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final DetialGallery gallery = (DetialGallery) findViewById(R.id.widget1); ImageAdapter imageAdapter = new ImageAdapter( Gallery1Activity.this); gallery.setAdapter(imageAdapter); final Handler handler = new Handler() { public void handleMessage( Message msg) { switch (msg.what) { case CHANGE_BANNER: gallery.onKeyDown( KeyEvent.KEYCODE_DPAD_RIGHT, null); break; default: break; } }; }; // new Thread(new Runnable() { // int flag = 1; // // public void run() { // // while (true) { // // handler.sendEmptyMessage(CHANGE_BANNER); // // try { // // Thread.sleep(1000); // // } catch (InterruptedException e) { // // e.printStackTrace(); // // } // // } // // } // // } // // ).start(); gallery.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected( AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub Toast.makeText( Gallery1Activity.this, "這是第" + arg2 + "張圖片", 2).show(); } @Override public void onNothingSelected( AdapterView<?> arg0) { // TODO Auto-generated method stub } }); } class ImageAdapter extends BaseAdapter { Context context; int[] imgResId = new int[] { R.drawable.icon, R.drawable.icon2, R.drawable.icon3, R.drawable.icon, R.drawable.icon2, R.drawable.icon3, }; public ImageAdapter( Gallery1Activity gallery1Activity) { // TODO Auto-generated constructor stub super(); this.context = gallery1Activity; } @Override public int getCount() { // TODO Auto-generated method stub // return Integer.MAX_VALUE; return Integer.MAX_VALUE; } @Override public Object getItem( int position) { // TODO Auto-generated method stub return position; // // return position; // return position; } @Override public long getItemId( int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub ImageView imageView = new ImageView( context); imageView .setImageResource(imgResId[arg0%imgResId.length]); imageView .setScaleType(ImageView.ScaleType.FIT_XY); imageView .setLayoutParams(new Gallery.LayoutParams( 175, 200)); return imageView; } } }
文檔處理就是在dom元素中添加html內容 1、 $("p").append("<a href='www.baidu.com'>baidu</a>") ; 增加內容到p標簽內部 2、 $("p").appendTo("div") ; 把所有的p元素增加到div中 3、 $("p").prepend("<b>Hello</b>"); 增加所有的b元素到p前
4、
$("p").prependTo("#foo"); 把p前置添加到id為 foo中。。
5、
$("p").after( $("b") ); 將p添加到b的后面
6、
$("p").before("<b>Hello</b>"); 在所有p元素之前插入html
7、
$("p").insertAfter("#foo"); 將p插入id為foo元素的后面
8、
$("p").insertBefore("#foo");
$("#foo").before("p") 操作相同,把所有元素插入到一個元素之前
9、
$("p").wrap("<div class='wrap'></div>"); 把所有p用div包裝起來
10 、
$("p").unwrap() 移除p元素的父元素
11、
$("p").wrapAll(document.createElement("div")); 用div包裝所有p
12、
$("<b>Paragraph. </b>").replaceAll("p"); 替換所有p
13、
$("p").empty(); 刪除p集合中的所有子節點
14 、
$("p").remove(); 從集合中移除所有p元素
15 、
$("p").detach(".hello"); 從DOM中把帶有hello類的段落刪除
16、
$("b").clone().prependTo("p"); 復制b元素 并且添加到p中
第一次去面試的時候人家人如何在SSH框架下,如何進行Hibernate的優化,當時自己只是看到這些根本就沒有系統的總結這些東西,今天終于找到一個時間來解決一下自己面試的這個問題了。 Hibernate自述 我天生效率比較低,在普遍情況下,需要將執行轉換為SQL語句的Hibernate低于直接JDBC存取。但是在經過比較好的性能優化之后,我的性能還是讓人相當滿意的,特別是應用二級緩存之后,甚至可以獲得比較不使用緩存的JDBC更好的性能。 優化總結 要想優化Hibernate,我們必須知道應該從什么地方進行優化,從什么地方入手。Hibernate的優化方向:數據庫設計、HQL優化、緩存、主配置、延遲加載、方法選用、集合選用、事物控制、批量操作 具體分析第一點:數據庫設計 前邊博客介紹過 數據庫設計,今天我們還從這開始,表的設計就是建樓的基礎,如何讓基礎簡潔而結實這是最重要的。 優化策略: 1. 建索引
2. 減少表之間的關聯
3. 簡化查詢字段,沒用的字段不要,已經對返回結果的控制,盡量返回少量數據
4. 適當的冗余數據,不過分最求高范式
第二點:HQL優化 
(HQL知識圖) 假如想好好了解一下的建議看一下這篇博客HQL詳細使用,我個人認為寫的還可以,知識總結的很細致。 總結: 1. 實體查詢:可以使用sql語句查詢
2. 實體的更新和刪除:hibernate3中直接提供更加靈活更加效率的解決方法
3. 屬性查詢:動態構造實例對象,對結果集進行封裝
4. 分組與排序:
A. Order by子句
B. Group by子句與統計查詢
C. 優化統計查詢:內連接,外連接
5. 參數綁定:和jdbc一樣,對hibernate的參數綁定提供了豐富的支持。
第三點:緩存 運行機制: 介于應用程序和物理數據源之間,其作用是為了降低應用程序對物理數據源訪問的頻數,從而提高運行性能。 緩存被廣泛應用的用于優化數據庫。當一些數據被從數據庫中讀取出來的時候,我們可以把它們放到緩存里。這樣我們可以再次使用的時候直接從緩存中取出來,這樣我們的效率就提高了很多。
控制范圍: 一級緩存是session對象的生命周期通常對應的一個數據庫事務或者一個應用事務,它是事務范圍內的緩存
二級緩存是一個可插拔的緩存插件,它是由SessionFactory負責管理。由于SessionFactory對象的生命周期和應用程序的整個過程對應,所以二級緩存是進城范圍或者集群范圍內的緩存。用于初始化很少更改的數據、不重要的數據,不會并發訪問的數據。
Hibernate緩存的一些問題和建議:hibernate的緩存
第四點:捉取策略 1. 捉取優化:Hibernate在關聯關系之間進行導航,充分利用Hibernate提供的技術 2. 如何捉取 立即捉取:當捉取宿主對象時,同時捉取其相關對象和關聯集以及屬性 延遲加載:當捉宿主對象時,并不捉取其關聯對象,而是當對其對象進行調用時才加載。 3. 捉取粒度:設置捉取個數
第五點:批量數據處理(修改和刪除) 在Hibernate2中,如果需要對任何數據進行修改和刪除操作都需要先執行查詢操作,在得到數據后才進行修改和刪除。 1. 不適用Hibernate API而是直接使用JDBC API來做原生態SQL語句進行查詢,這種方法比較好,相對來說較快。
2. 運用存儲過程
3. 一定量范圍內可以使用hibernate API,但是特大數據量不行。
第六點:結果集的使用: 結果集的使用:list()和iterator()區別 查詢方式: list只能利用查詢緩存(但在交易系統中查詢緩存作用不大),無法利用二級緩存中的單個實體,但是list查出的對象會寫入二級緩存,但它一般只生成較少的sql語句,很多情況就是一條。
iterator則利用二級緩存,對于一條查詢語句,它會先從數據庫中找到所有符合條件的記錄的ID,在通過ID去緩存找,對于緩存中沒有的記錄,在構造語句從數據庫查出,第一次的執行會產生N+1條SQL語句。
產生結果: 用list可能會溢出
通過Iterator,配合緩存管理API,在海量數據查詢中可以很好的解決內存問題。
綜合考慮: 一般List會填充二級緩存,卻不能利用二級緩存,而Iterator可以讀二級緩存,然而無法命中的話,效率很低效。一般處理方法,就是第一次查詢使用list,隨后使用iterator查詢。
總結 Hibernate優化總結還有主配置、方法選用、事物控制沒有涉及到,因為它們相對來說這些方面比較簡單,但是還是很重要的。 在實施一個項目的時候我們沒有必要想這些問題,做項目的時候第一步運行起來,第二步優化一下。在很多小型項目中第二步一般都不會去做,所以說我們做工程的時候還是要牢記運行出來,假如自己作為研究或者這個問題比較嚴重的話我們才考慮優化。 Hibernate調優方面沒有最有只有更優,讓我們不斷積極找到優化的方法,來優化我們的程序,來優化我們自己。 關于Hibernate優化方面,希望大家留下寶貴的意見,多對交流!
|