#
一、實時查看帶寬bmon官方站點:http://people.suug.ch/~tgr/bmon/gentoo:安裝:emerge net-analyzer/bmon基本用法:bmon -o ascii -p eth0其它linux系統(tǒng)可參照官方站點的說明使用。二、帶寬統(tǒng)計vnstat官方站點:http://humdi.net/vnstat/gentoo:安裝:emerge vnstat第一次使用需要對每個網(wǎng)卡運行:#vnstat -u -i eth0 ……1、查看5秒內(nèi)網(wǎng)卡eth0的平均流量:#vnstat -tr -i eth02、網(wǎng)卡eth0一周內(nèi)的流量:#vnstat -i eth0 -w
摘要: 一、決策樹簡介: 關(guān)于決策樹,幾乎是數(shù)據(jù)挖掘分類算法中最先介紹到的。決策樹,顧名思義就是用來做決定的樹,一個分支就是一個決策過程。 每個決策過程中涉及一個數(shù)據(jù)的屬性,而且只涉及一個。然后遞歸地,貪心地直到滿足決策條件(即可以得到明確的決策結(jié)果)。 決策樹的實現(xiàn)首先要有一些先驗(已經(jīng)知道結(jié)果的歷史)數(shù)據(jù)做訓(xùn)練,通過分析訓(xùn)練數(shù)據(jù)得到每個屬性對結(jié)果的影響的大小,這里我們通過... 閱讀全文
摘要: 之前做了一個統(tǒng)計商鋪的PV,UV值 大體思路:每天將用戶的訪問信息放到明細(xì)表里,然后在第二天的凌晨將這些數(shù)據(jù)歸總 PVUV表 4個字段:主鍵pk 用戶IP(customer_ip) 訪問時間(time) 商鋪ID(store_id) 統(tǒng)計TOTAL表&... 閱讀全文
網(wǎng)上有好幾種方法可以將將HTML文件轉(zhuǎn)換成PDF文件但是有些對HTML文件格式要求比較嚴(yán)格,稍微錯了一些就不能生成我們所要的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);
- }
- }
先說一下應(yīng)用環(huán)境: 采用Tilera的平臺(一種眾核平臺,),三張網(wǎng)卡,兩個10G的xgbe網(wǎng)卡,用來進(jìn)行數(shù)據(jù)的發(fā)送和接受;一個1G的普通網(wǎng)卡,用來做管理接口.
10G的xgbe工作在Tilera的特定sdk下,其中的數(shù)據(jù)包不經(jīng)過內(nèi)核協(xié)議棧,直接交付給用戶。這樣的好處是數(shù)據(jù)處理效率很高(普通的linux協(xié)議棧中需要兩次內(nèi)存的拷貝,效率低),但是也因此帶來了一些問題,有些包需要交給標(biāo)準(zhǔn)的協(xié)議棧 ,比如ospf報文,zebra工作在用戶態(tài),需要從標(biāo)準(zhǔn)的協(xié)議棧內(nèi)獲取網(wǎng)絡(luò)數(shù)據(jù)包,而xgbe是不會直接把數(shù)據(jù)交付給標(biāo)準(zhǔn)協(xié)議棧的。
TAP虛擬網(wǎng)卡是Linux標(biāo)準(zhǔn)的虛擬網(wǎng)絡(luò)設(shè)備,在Tilera平臺上其編程也是一樣的。 擁有這樣的虛擬網(wǎng)卡后可以利用其通用linux協(xié)議棧的特性,并可以將數(shù)據(jù)包交付應(yīng)用層的socket程序處理。ospfd程序就可以利用TAP進(jìn)程收到ospf報文,并發(fā)布默認(rèn)路由出去。 

上圖是TAP網(wǎng)卡的收發(fā)包流程圖 左側(cè)紅色箭頭標(biāo)示的為從協(xié)議棧經(jīng)TAP網(wǎng)卡發(fā)包標(biāo)示,對從tap讀進(jìn)來的包進(jìn)行一下netio封裝,然后經(jīng)過xbge發(fā)送出去 右側(cè)綠色箭頭標(biāo)示的為數(shù)據(jù)包經(jīng)TAP網(wǎng)卡收至協(xié)議棧的流程,調(diào)用netio(tilera 特定的網(wǎng)絡(luò)編程api)從xgbe中收到發(fā)送給tap的報后,經(jīng)過包處理進(jìn)程將數(shù)據(jù)包交付給TAP進(jìn)程,其實就是將收到的包寫進(jìn)tap網(wǎng)卡中,這樣用戶進(jìn)程就可以再內(nèi)核協(xié)議棧中接受到通過xgbe發(fā)送來的包。
存儲過程是一組預(yù)先編譯好的sql語句。將他放在服務(wù)器上面,由用戶通過指定存儲過程的名字來執(zhí)行它。 存儲過程的優(yōu)點: 封裝——可用于操作數(shù)據(jù)庫對象的方法,用戶只需要知道它的輸入輸出參數(shù)并理解其目的即可。 改善性能——已經(jīng)預(yù)先編譯 減少網(wǎng)絡(luò)流量——只返回最后的結(jié)果集 重要性——針對復(fù)雜邏輯,應(yīng)用已經(jīng)測試號的存儲過程,不容易發(fā)生錯誤。 安全性——如果數(shù)據(jù)庫擁有者DBO或者系統(tǒng)管理員SA編譯并保存了存儲結(jié)構(gòu),存儲過程就有了對它使用的數(shù)據(jù)庫對象的所有訪問權(quán)限。因此系統(tǒng)管理員可以向單獨的用于授予對數(shù)據(jù)對象的最小訪問權(quán)限,而不是直接允許用戶使用數(shù)據(jù)庫對象。 這次項目開發(fā)中運用了不少的存儲過程,中間遇到了一個小問題,大家可以看看: 事情是這樣的:我想根據(jù)卡號、教師編號、教師姓名、聯(lián)系電話這四個條件查詢教師編號,這四個條件可以不存在,可以只存在一個,可以只存在兩個,可以只存在三個,可以存在四個。開始我寫的存儲過程是這樣的 - <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 卡內(nèi)余額,realName as 管理員,OpenTime as 開卡時間,state as 狀態(tài),telephone as 聯(lián)系電話 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 卡內(nèi)余額,realName as 管理員,OpenTime as 開卡時間,state as 狀態(tài),telephone as 聯(lián)系電話FROM view_CardDetail and cardNo ='@cardNo’
這句話顯然是錯誤的,在查詢語句和條件的過渡的地方?jīng)]有where,而是突然來了個and。然而這個時候如果加上個必然條件那就完美了,接下來的存儲過程創(chuàng)建語句是這樣的: - 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 卡內(nèi)余額,realName as 管理員,OpenTime as 開卡時間,state as 狀態(tài),telephone as 聯(lián)系電話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)
這樣的話執(zhí)行出來的結(jié)果是這樣的: - SELECT TeacherID as 教師編號,Nameas 教師姓名,GradeName as 所屬年級,cardNo as 卡號,cashas 卡內(nèi)余額,realName as 管理員,OpenTime as 開卡時間,stateas 狀態(tài),telephone as 聯(lián)系電話FROM view_CardDetail WHERE 1=1and cardNo ='+@cardNo+'
必然條件在這里充當(dāng)了橋梁的作用,雖然我們沒有“1=1“的需求,但是它的存在卻恰好解決了兩者互不相容的尷尬局面。 受上面的啟發(fā),下面的情況是這樣解決的: 需要根據(jù)教師編號和起始日期查詢教師的消費記錄情況,兩個條件的存在情況各自隨便。 存儲過程代碼如下: - 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 成人數(shù)量,childNum as 兒童數(shù)量,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)
這里當(dāng)@TimeStart和@TimeEnd為空的時候,空字符串不能轉(zhuǎn)換成日期類型,這時候假如兩個變量為空,我可以給他們賦一個完全的值: - exec procConsumeByMore '', '1799-01-01','9999-12-29'
如上面的代碼就可以選擇出所有的消費記錄了。 上面兩件事情中必然事件這個配角起了不可忽視的作用,然而必然事件卻不是我們在查詢過程中需要的條件。 生活中配角并不意味著無趣和呆板,配角一樣可以靈動,只是它把對別人的善意放在第一位,不把張揚(yáng)作為表達(dá)自己的方式。‘上善若水,水善利萬物而不爭’,但是水又無處不在,其實就是這樣一種狀態(tài)。創(chuàng)造一個最好的配角,并不比創(chuàng)造一個主角容易。
寫了一個簡單的委托的試用測試: 首先創(chuàng)建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中實現(xiàn)委托: [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中實現(xiàn): [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 調(diào)用添加: [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內(nèi)容 1、 $("p").append("<a href='www.baidu.com'>baidu</a>") ; 增加內(nèi)容到p標(biāo)簽內(nèi)部 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集合中的所有子節(jié)點
14 、
$("p").remove(); 從集合中移除所有p元素
15 、
$("p").detach(".hello"); 從DOM中把帶有hello類的段落刪除
16、
$("b").clone().prependTo("p"); 復(fù)制b元素 并且添加到p中
第一次去面試的時候人家人如何在SSH框架下,如何進(jìn)行Hibernate的優(yōu)化,當(dāng)時自己只是看到這些根本就沒有系統(tǒng)的總結(jié)這些東西,今天終于找到一個時間來解決一下自己面試的這個問題了。 Hibernate自述 我天生效率比較低,在普遍情況下,需要將執(zhí)行轉(zhuǎn)換為SQL語句的Hibernate低于直接JDBC存取。但是在經(jīng)過比較好的性能優(yōu)化之后,我的性能還是讓人相當(dāng)滿意的,特別是應(yīng)用二級緩存之后,甚至可以獲得比較不使用緩存的JDBC更好的性能。 優(yōu)化總結(jié) 要想優(yōu)化Hibernate,我們必須知道應(yīng)該從什么地方進(jìn)行優(yōu)化,從什么地方入手。Hibernate的優(yōu)化方向:數(shù)據(jù)庫設(shè)計、HQL優(yōu)化、緩存、主配置、延遲加載、方法選用、集合選用、事物控制、批量操作 具體分析第一點:數(shù)據(jù)庫設(shè)計 前邊博客介紹過 數(shù)據(jù)庫設(shè)計,今天我們還從這開始,表的設(shè)計就是建樓的基礎(chǔ),如何讓基礎(chǔ)簡潔而結(jié)實這是最重要的。 優(yōu)化策略: 1. 建索引
2. 減少表之間的關(guān)聯(lián)
3. 簡化查詢字段,沒用的字段不要,已經(jīng)對返回結(jié)果的控制,盡量返回少量數(shù)據(jù)
4. 適當(dāng)?shù)娜哂鄶?shù)據(jù),不過分最求高范式
第二點:HQL優(yōu)化 
(HQL知識圖) 假如想好好了解一下的建議看一下這篇博客HQL詳細(xì)使用,我個人認(rèn)為寫的還可以,知識總結(jié)的很細(xì)致。 總結(jié): 1. 實體查詢:可以使用sql語句查詢
2. 實體的更新和刪除:hibernate3中直接提供更加靈活更加效率的解決方法
3. 屬性查詢:動態(tài)構(gòu)造實例對象,對結(jié)果集進(jìn)行封裝
4. 分組與排序:
A. Order by子句
B. Group by子句與統(tǒng)計查詢
C. 優(yōu)化統(tǒng)計查詢:內(nèi)連接,外連接
5. 參數(shù)綁定:和jdbc一樣,對hibernate的參數(shù)綁定提供了豐富的支持。
第三點:緩存 運行機(jī)制: 介于應(yīng)用程序和物理數(shù)據(jù)源之間,其作用是為了降低應(yīng)用程序?qū)ξ锢頂?shù)據(jù)源訪問的頻數(shù),從而提高運行性能。 緩存被廣泛應(yīng)用的用于優(yōu)化數(shù)據(jù)庫。當(dāng)一些數(shù)據(jù)被從數(shù)據(jù)庫中讀取出來的時候,我們可以把它們放到緩存里。這樣我們可以再次使用的時候直接從緩存中取出來,這樣我們的效率就提高了很多。
控制范圍: 一級緩存是session對象的生命周期通常對應(yīng)的一個數(shù)據(jù)庫事務(wù)或者一個應(yīng)用事務(wù),它是事務(wù)范圍內(nèi)的緩存
二級緩存是一個可插拔的緩存插件,它是由SessionFactory負(fù)責(zé)管理。由于SessionFactory對象的生命周期和應(yīng)用程序的整個過程對應(yīng),所以二級緩存是進(jìn)城范圍或者集群范圍內(nèi)的緩存。用于初始化很少更改的數(shù)據(jù)、不重要的數(shù)據(jù),不會并發(fā)訪問的數(shù)據(jù)。
Hibernate緩存的一些問題和建議:hibernate的緩存
第四點:捉取策略 1. 捉取優(yōu)化:Hibernate在關(guān)聯(lián)關(guān)系之間進(jìn)行導(dǎo)航,充分利用Hibernate提供的技術(shù) 2. 如何捉取 立即捉取:當(dāng)捉取宿主對象時,同時捉取其相關(guān)對象和關(guān)聯(lián)集以及屬性 延遲加載:當(dāng)捉宿主對象時,并不捉取其關(guān)聯(lián)對象,而是當(dāng)對其對象進(jìn)行調(diào)用時才加載。 3. 捉取粒度:設(shè)置捉取個數(shù)
第五點:批量數(shù)據(jù)處理(修改和刪除) 在Hibernate2中,如果需要對任何數(shù)據(jù)進(jìn)行修改和刪除操作都需要先執(zhí)行查詢操作,在得到數(shù)據(jù)后才進(jìn)行修改和刪除。 1. 不適用Hibernate API而是直接使用JDBC API來做原生態(tài)SQL語句進(jìn)行查詢,這種方法比較好,相對來說較快。
2. 運用存儲過程
3. 一定量范圍內(nèi)可以使用hibernate API,但是特大數(shù)據(jù)量不行。
第六點:結(jié)果集的使用: 結(jié)果集的使用:list()和iterator()區(qū)別 查詢方式: list只能利用查詢緩存(但在交易系統(tǒng)中查詢緩存作用不大),無法利用二級緩存中的單個實體,但是list查出的對象會寫入二級緩存,但它一般只生成較少的sql語句,很多情況就是一條。
iterator則利用二級緩存,對于一條查詢語句,它會先從數(shù)據(jù)庫中找到所有符合條件的記錄的ID,在通過ID去緩存找,對于緩存中沒有的記錄,在構(gòu)造語句從數(shù)據(jù)庫查出,第一次的執(zhí)行會產(chǎn)生N+1條SQL語句。
產(chǎn)生結(jié)果: 用list可能會溢出
通過Iterator,配合緩存管理API,在海量數(shù)據(jù)查詢中可以很好的解決內(nèi)存問題。
綜合考慮: 一般List會填充二級緩存,卻不能利用二級緩存,而Iterator可以讀二級緩存,然而無法命中的話,效率很低效。一般處理方法,就是第一次查詢使用list,隨后使用iterator查詢。
總結(jié) Hibernate優(yōu)化總結(jié)還有主配置、方法選用、事物控制沒有涉及到,因為它們相對來說這些方面比較簡單,但是還是很重要的。 在實施一個項目的時候我們沒有必要想這些問題,做項目的時候第一步運行起來,第二步優(yōu)化一下。在很多小型項目中第二步一般都不會去做,所以說我們做工程的時候還是要牢記運行出來,假如自己作為研究或者這個問題比較嚴(yán)重的話我們才考慮優(yōu)化。 Hibernate調(diào)優(yōu)方面沒有最有只有更優(yōu),讓我們不斷積極找到優(yōu)化的方法,來優(yōu)化我們的程序,來優(yōu)化我們自己。 關(guān)于Hibernate優(yōu)化方面,希望大家留下寶貴的意見,多對交流!
|