Müdavim Girişi

E-Posta
Parola

Ücretsiz Kayıt Ol


Online Müdavimler (0 Kişi)
  • Online Kişi Bulunmadı

Yazar Hakkında
x
İsmail Kocacan
İsmail Kocacan is experienced on many development platforms and continues to learn technologies. Since the age of 16-17, dealing with software technologies. And continuous learning, teaching, research, continues to develop.
ExtJS GridPanel Sql Paging

 Herkese Selamlar Saygılar;

Bu makalede SQL Paging konusunu ExtJS kontrollerinde GridPanel Nesnesi üzerinde uygulanışını göstericem.Uzun bir yazı olacağından okumaya başlamadan önce içmek için çay,kahve bilimum artık ne içiyorsanız hazırlayınız.
 
Çay kahve hazırsa artık başlayabiliriz
Şimdi böyle bir şeyi neden yapma ihtiyacı duyarız? Kayıt sayısının fazla olduğu tablolarda verilerin hepsinin çekilmesi uygulamayı yavaşlatıyor.O sebeble hepsini değilde parça parça çekmek bize hız kazandıracaktır.
 
Her ne kadar asp.net içersindeki sunucu kontrolleri veri sayfalıyor gibi görünsede aslında sayfalamaz.Örneğin gridview kontrolü; Tüm verileri kendi belleğine çekip orda sayfalıyor.Yine yavaş çalışacaktır.Bu olay Ext.Net bileşenlerinden GridPanel nesnesinde de aynı.Tablodaki Tüm satırlar (Kayıtlar) Store nesnesine çekilip Store nesnesinden parça parça okunuyor.Bu yöntemde çok büyük veri kümelerinde yetersiz kalıyor.
 
Ulan ! o düzgün çalışmıyor. Bu düzgün çalışmıyor.Doğrusunu gösterde öğrenelim seslerini duyar gibiyim…
 
Şimdi basit bir tabloyla işe başlayalım.

Şimdi Bu tabloyu sayfalayarak listeleyecek bir stored procedure yazalım.

 
ALTER PROCEDURE [dbo].[GetCustomers]
 @PageIndex int=1, --varsayılan
 @PageSize int=3,
 @RowCount int out,
 @PageCount int out
AS
BEGIN
     DECLARE @Start INT
     DECLARE @Finish INT
 
     SET @Start=(@PageIndex*@PageSize)-@PageSize+1;
     SET @Finish=(@Start+@PageSize)-1;
 
     WITH TEMP_TBL AS(
             SELECT row_number() OVER (ORDER BY RID DESC) as RowNumber,
             * FROM TBL_CUSTOMERS)
        SELECT * FROM TEMP_TBL WHERE RowNumber BETWEEN @Start AND @Finish    
 
     SET @RowCount =(SELECT count(*) FROM TBL_CUSTOMERS)
 
     IF ((@RowCount % @PageSize)=0) --kalan 0 is tam bölünüyordur.
          SET @PageCount=@RowCount / @PageSize
        ELSE        --tam bölünmüyorsa
          SET @PageCount=(@RowCount / @PageSize)+1 --sayfa sayısına 1 ekle
END
 
/*
@PageIndex ->> Sayfa Numarası anlamına gelir."
@PageSize ->> Sayfalık kayıt sayısıdır.
@RowCount ->> Toplam Kayıt Sayısıdır"
@PageCount ->> Toplam sayfa sayısıdır"
@Start     ->> Aralık Başlangıçı"
@Finish    ->> Aralık Bitişi"
*/
 

Biz bu prosedürün giriş parametrelerine bir değer atamadığımız sürece varsayılan değerleri kullanacak.Yani hep 1 sayfadan başlayıp 3 kayıt getirecek.
Yukarıdaki prosedürü aşağıdaki gibi bir sorguyla çalıştırabiliriz.


DECLARE
      @RowCount int,@PageCount int
 
EXEC   [dbo].[GetCustomers]
             @PageIndex = 2,
             @PageSize = 5,
             @RowCount = @RowCount OUTPUT,
             @PageCount = @PageCount OUTPUT
 
SELECT @RowCount as N'@RowCount',
             @PageCount as N'@PageCount'
 

 
@RowCount ve @PageCount parametrelerini dışa atıyoruz.Şimdilik burada @RowCount parametresi ile uygulama içersinde bir şey yapmıyacağız.Program içersinde @PageCount parametresindeki değeri kullanıcaz.
Yukarıdaki sorguyu çalıştırdığınızda aşağıdaki gibi bir sonuç göreceksiniz.


@PageIndex ve @PageSize parametrelerinin değerlerini değiştirerek test edebilirsiniz.
Evet veritabanı kısmında bu işi hallettiğimize göre şimdi Ext.Net GridPanel nesnesi üzerinde nasıl uygulayarız onu görelim.

 
 
 
Daha öncede dediğim gibi Grid altındaki navigator’ler bellekteki veriyi sayfalar.O sebeble biz manuel bir PagingNavigator hazırlıyacağız.Öyle bir hazırlıyacağız ki PagingToolbar nesnesinden çok zor ayırt edilecek.
Ext.Net çok güzel bir AJAX Framework.Tüm nesneleri markup kod yazarak hazırlayabiliyorsunuz.Açık kaynak bir proje olmasıda başka bir güzelliği.Takıldığınız yerlerde en tabana kadar inip nasıl yapıldığına dair bir fikir sahibi olabiliyorsunuz.Birkaç Ajax framework kullanmış birisi olarak, bu iş için .Net tarafında Ext.Net diyorum.
 
Default.aspx

<%@ Page Language="C#"
    AutoEventWireup="true"
    CodeBehind="Default.aspx.cs"
    Inherits="ExtGridPanelPaging._Default" %>
 
<%@ Register Assembly="Ext.Net"
             Namespace="Ext.Net"
             TagPrefix="ext" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Ext GridPanel Paging</title>
    <style type="text/css">
        body
        {
            padding: 20px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <ext:ResourceManager runat="server" Theme="Default">
    </ext:ResourceManager>
    <!-- Veri Kaynağı Oluşturuluyor (Başlangıç)!-->
    <ext:Store ID="StoreCustomers" runat="server">
        <Reader>
            <ext:JsonReader>
                <Fields>
                    <ext:RecordField Name="RID" Type="Int" />
                    <ext:RecordField Name="FIRSTNAME" Type="String" />
                    <ext:RecordField Name="LASTNAME" Type="String" />
                    <ext:RecordField Name="INSERTIONTIME" Type="String" />
                </Fields>
           </ext:JsonReader>
        </Reader>
    </ext:Store>
    <!-- Veri Kaynağı Oluşturuluyor (Bitiş) !-->
    <ext:GridPanel ID="GRDCustomers"
                    Frame="false"
                    runat="server"
                    Title="Customers List"
                    Icon="Application"
                    StoreID="StoreCustomers"
                    Border="true"
                    StripeRows="true"
                    DeferRowRender="true"
                    TrackMouseOver="true"
                    Height="250"
                    Width="420">
                    
        <ColumnModel ID="ColumnModel1" runat="server">
            <Columns>
                <ext:Column DataIndex="RID"
                            Header="Indetity">
                </ext:Column>
                <ext:Column DataIndex="FIRSTNAME"
                            Header="FirstName">
                </ext:Column>
                <ext:Column DataIndex="LASTNAME"
                            Header="LastName">
                </ext:Column>
                <ext:Column DataIndex="INSERTIONTIME"
                            Header="InsertionTime">
                </ext:Column>
            </Columns>
        </ColumnModel>
       
        <LoadMask ShowMask="true" Msg="Yükleniyor." />
        <SelectionModel>
            <ext:RowSelectionModel ID="RowSelectionModel1"
                                    runat="server"
                                    SingleSelect="true">
            </ext:RowSelectionModel>
        </SelectionModel>
       
        <BottomBar>
            <ext:Toolbar runat="server" ID="PagingNavigator1">
                <Items>
                    <ext:Button runat="server"
                                ID="btnfirst"
                                Icon="ResultsetFirst">
                        <Listeners>
                            <Click Handler="#{txtPageIndex}.setValue(1);" />
                        </Listeners>
                        <DirectEvents>
                            <Click OnEvent="OnPageIndexChanged">
                                <ExtraParams>
                                    <ext:Parameter Name="pageIndex"
                                                   Value="1"
                                                   Mode="Raw">
                                    </ext:Parameter>
                                </ExtraParams>
                                <EventMask Msg="Listeleniyor.."
                                           ShowMask="true" />
                            </Click>
                        </DirectEvents>
                    </ext:Button>
                   
                    <ext:Button runat="server"
                                ID="btnprior"
                                Icon="ResultsetPrevious">
                        <Listeners>
                            <Click Handler="var pagecount=parseInt(#{lblPageCount}.getText()); var index=parseInt(#{txtPageIndex}.getValue()); if (index > 1 ) { index=index-1; #{txtPageIndex}.setValue(index);}" />
                        </Listeners>
                        <DirectEvents>
                            <Click OnEvent="OnPageIndexChanged">
                                <ExtraParams>
                                    <ext:Parameter Name="pageIndex"
                                                   Value="#{txtPageIndex}.getValue()"
                                                   Mode="Raw">
                                    </ext:Parameter>
                                </ExtraParams>
                                <EventMask Msg="Listeleniyor.."
                                           ShowMask="true" />
                            </Click>
                        </DirectEvents>
                    </ext:Button>
                   
                    <ext:ToolbarSeparator>
                    </ext:ToolbarSeparator>
                   
                    <ext:ToolbarTextItem Text="Page"
                                         runat="server"/>
                                        
                    <ext:NumberField runat="server"
                                     ID="txtPageIndex"
                                     Width="40"
                                     Text="1">
                        <DirectEvents>
                            <Change OnEvent="OnPageIndexChanged">
                                <ExtraParams>
                                    <ext:Parameter Name="pageIndex"
                                                   Value="#{txtPageIndex}.getValue()"
                                                   Mode="Raw">
                                    </ext:Parameter>
                                </ExtraParams>
                                <EventMask Msg="Listeleniyor..."
                                           ShowMask="true" />
                            </Change>
                        </DirectEvents>
                    </ext:NumberField>
                   
                    <ext:ToolbarTextItem runat="server"
                                         Text="/" />
 
                   
                    <ext:ToolbarTextItem ID="lblPageCount"
                                         runat="server"/>
 
                    <ext:ToolbarSeparator runat="server"/>
                   
                    <ext:Button runat="server"
                                ID="btnnext"
                                Icon="ResultsetNext">
                        <Listeners>
                            <Click Handler="var pagecount=parseInt(#{lblPageCount}.getText()); var index=parseInt(#{txtPageIndex}.getValue()); if (index < pagecount) { index=index+1; #{txtPageIndex}.setValue(index);}" />
                        </Listeners>
                        <DirectEvents>
                            <Click OnEvent="OnPageIndexChanged">
                                <ExtraParams>
                                   <ext:Parameter Name="pageIndex"
                                                   Value="#{txtPageIndex}.getValue()"
                                                   Mode="Raw">
                                    </ext:Parameter>
                                </ExtraParams>
                                <EventMask Msg="Listeleniyor.."
                                           ShowMask="true" />
                            </Click>
                        </DirectEvents>
                    </ext:Button>
                    <ext:Button runat="server"
                                ID="btnlast"
                                Icon="ResultsetLast">
                        <Listeners>
                            <Click Handler="#{txtPageIndex}.setValue(#{lblPageCount}.getText());" />
                        </Listeners>
                        <DirectEvents>
                            <Click OnEvent="OnPageIndexChanged">
                                <ExtraParams>
                                    <ext:Parameter Name="pageIndex"
                                                   Value="#{lblPageCount}.getText()"
                                                   Mode="Raw">
                                    </ext:Parameter>
                                </ExtraParams>
                                <EventMask Msg="Listeleniyor.."
                                           ShowMask="true" />
                            </Click>
                        </DirectEvents>
                    </ext:Button>
                    <ext:ToolbarSeparator runat="server"/>
                    <ext:ToolbarTextItem ID="lblInfo"
                                         runat="server"/>
                </Items>
            </ext:Toolbar>
        </BottomBar>
    </ext:GridPanel>
    </form>
</body>
</html>
 

 
Default.aspx.cs

using System;
using System.Configuration;
using System.Data;
using System.Web.UI;
using System.Data.SqlClient;
using Ext.Net;
 
namespace ExtGridPanelPaging
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                int RowCount, PageCount;
 
                StoreCustomers.DataSource = this.GetData(
                    1,
                    3,
                    out RowCount,
                    out PageCount);
 
                StoreCustomers.DataBind();
                lblPageCount.Text = PageCount.ToString();
            }
        }
 
 
 
        public void OnPageIndexChanged(object sender, DirectEventArgs e)
        {
            int RowCount, PageCount;
            int PageIndex int.Parse(e.ExtraParams["pageIndex"].ToString());
            StoreCustomers.DataSource = this.GetData(
                PageIndex,
                3,
                out RowCount,
                out PageCount);
            StoreCustomers.DataBind();
            lblPageCount.Text = PageCount.ToString();
        }
 
 
 
 
        public DataTable GetData
            (
            int PageIndex,
            int PageSize,
            out int RowCount,
            out int PageCount
            )
        {
 
            DataSet dataset = new DataSet();
            string execsql = string.Format(@"
                                DECLARE @RowCount int,@PageCount int
                                EXEC    [dbo].[GetCustomers]
                                        @PageIndex = {0},
                                             @PageSize = {1},
                                             @RowCount = @RowCount OUTPUT,
                                             @PageCount = @PageCount OUTPUT
 
                                SELECT @RowCount as N'@RowCount',
                                             @PageCount as N'@PageCount'",
                                        PageIndex, PageSize);
 
            using (SqlConnection connection = new SqlConnection(
                ConfigurationManager.ConnectionStrings["PagingDB"].ConnectionString))
            {
                using (SqlDataAdapter command = new SqlDataAdapter(
                    execsql, connection))
                {
                    connection.Open();
                    command.Fill(dataset);
                    connection.Close();
                }
            }
 
 
            DataTable tblCustomers = dataset.Tables[0];
            DataTable tblParameters = dataset.Tables[1];
 
            RowCount = int.Parse(tblParameters.Rows[0]["@RowCount"].ToString());
            PageCount = int.Parse(tblParameters.Rows[0]["@PageCount"].ToString());
 
            lblInfo.Text =
                RowCount.ToString() + " Kayıt ," +
                PageCount.ToString() + " Sayfa";
            return tblCustomers;
        }
 
    }
}
 

 
Evet Kodlar tamam olduğuna göre şimdi gerçek bir test yapalım. TBL_CUSTOMERS tablosu için veri hazırlayalım.Biraz dediğime bakmayın 1.000.000 satır ekliyecem.


TRUNCATE TABLE TBL_CUSTOMERS
DECLARE @sayac INT
SET    @sayac = 0
 
WHILE (@sayac < 1000000)
BEGIN
 SET @sayac = @sayac + 1
 INSERT INTO TBL_CUSTOMERS(FIRSTNAME,LASTNAME)
 VALUES
 ('FIRSTNAME'+convert(varchar(max),@sayac),
   'LASTNAME'+convert(varchar(max),@sayac))
END
select count(*) FROM TBL_CUSTOMERS

1 milyar kaydı FIRSTNAME,LASTNAME,INSERTIONTIME alanlarına TBL_CUSTOMERS tablosuna 9:53 saniyede ekledim.Bu sırada log dosyası ile birlikte veritabanı boyutu 53 mb oldu.
 
Şimdi uygulamamızı deneyebiliriz.


 
Değerlendirelim:
Amacım büyük veri kümelerini nasıl sayfalayarak performanslı bir şekilde listeleyebiliriz sorusuna cevap vermekti.Her ne kadar 1.000.000 kayıtlı bir tablo üzerinde test yapsakta yine gerçek bir test değil.Çünkü tek tablo üzerinden sorgulama yapıyoruz. Bu arada Kod kısmından PageSize değerini kendinize göre uyarlamayı unutmayın.

 
Kaynak Kodları Buradan İndirebilirsiniz
 
İsmail Kocacan(Yazılımcı Bozuntusu)

Kategori : JS-JQuery-ExtJS | 14.07.2011 16:28:00  | 1463 defa okundu  | 0 Yorum |

Yazara Ait Diğer Makaleler(51) Makaleye Yapılan Yorumlar İlk yorum yazan siz olun
Ara
 
Anket
Hangi VeriTabanı Yönetim Sistemini Kullanıyorsunuz ?