1. 程式人生 > 其它 >將複雜查詢寫到SQL配置檔案--SOD框架的SQL-MAP技術簡介

將複雜查詢寫到SQL配置檔案--SOD框架的SQL-MAP技術簡介

引言

今天看到一片熱門的部落格, .NET高階工程師面試題之SQL篇 ,要求找出每一個系的最高分,並且按系編號,學生編號升序排列。這個查詢比較複雜,也比較典型,自從用了ORM後,很久沒有寫過SQL語句了,於是我研究了下,自己也寫了一個:

 WITH cte1 as (
 select stu.deptID,
        D.depName, 
        stu.stuid ,
        stu.stuName,
        score_sum.AllScore
    from dbo.Student stu
      inner join (select stuid ,SUM(score) as AllScore from dbo.Score group by stuid) score_sum      
          on  stu.stuid =score_sum.stuid 
      inner join dbo.Department D on stu.deptID= D.depID
)
 select cte1.* from cte1 
      inner join (select deptID, max(AllScore) maxScore from cte1  group by deptID) M
            on cte1.AllScore = M.maxScore and cte1.deptID=M.deptID
 order by cte1.deptID,
          cte1.stuid

我們工作中常常遇到類似的複雜查詢,但常見的做法是把它寫到BLL程式中,也有同學喜歡寫在儲存過程中,它有什麼問題呢?

  • 寫到程式中,
    • 容易養成拼接SQL的習慣,
    • 並且SQL語句零散的分佈到程式的各個地方,不好維護,
    • 並有可能發生安全問題;
  • 寫到儲存過程,
    • 如果多了也不好維護,
    • 並且程式呼叫不如直接呼叫SQL語句方便,
    • 部署的時候還得部署這些儲存過程,系統上線複雜的時候,常常忘記更新一兩個儲存過程。

除此之外,SQL語句不論寫到程式中或者寫在儲存過程中,都有一個很大的缺點,程式無法跨資料庫平臺!

如果把所有的SQL語句都集中管理在一個配置檔案中,那麼程式編寫和維護、釋出都要方便很多,也容易跨資料庫平臺,甚至可以根據這個SQL配置檔案,寫個程式碼生成器,自動生成DAL層程式碼。 大名鼎鼎的 iBatis,MyBaits.Net 就是這樣的功能,但它定義了一套複雜的規則,配置起來很複雜,專案可能80%的時間都在寫查詢配置,如果沒有程式碼工具開發工作量很大的。

當然,與MyBatis不一樣之處,SOD框架並不主張將專案的查詢都用SQL寫到SqlMap檔案,建議大家僅將複雜的SQL查詢寫到SqlMap配置檔案,一般專案這類複雜查詢也就20%左右,而對於80%的一般查詢,使用ORM即可,框架同時支援ORM與SqlMap技術,這是SOD框架的一大特點

SQL-MAP--集中管理SQL查詢

PDF.NET SOD框架SQL-MAP功能借鑑了iBaits的思想,但是大力簡化它的配置並提供程式碼生成工具,可以自動化的完成DAL程式碼生成,下面是它的工作過程:

SOD框架提供了SqlMap配置檔案管理器來管理和編寫SQL配置檔案,然後通過程式碼生成器生成DAL層程式碼,最後交給SODk框架執行。

編寫SQL配置檔案,如果通過上面說的配置工具來做,可以參考這篇文章:

PDF.NET之SQL-MAP使用圖解

但這個程式太老,一直沒有更新,工具的下載地址是:

http://ft.codeplex.com/releases/view/65308

工具包含在這個“整合開發工具” 內,通過選單或者圖示即可操作。下面是整合開發工具開啟資料庫並執行本文的查詢的介面:

SQL-MAP配置管理工具不太好用,初學者學習概念可以試一試,但是要想熟練應用,推薦使用VS來寫這個SQL配置檔案更方便。本文將向大家詳細介紹這個過程。

一、編寫SQL-MAP配置檔案

1.1,建立SQL-MAP應用專案

如下圖所示,新建一個 SqlMapDemo專案,在它裡面先新增一個XML檔案,檔案命名為 SqlMap.config ,然後,找到上面的“整合開發工具”的安裝目錄,新增 SqlMap.xsd 檔案。該檔案很重要,它是我們在VS裡面編寫XML檔案能夠有 智慧提示 的關鍵。

添加了這個XSD檔案到專案後,還需要把下面的內容

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:noNamespaceSchemaLocation="SqlMap.xsd"  

注意:有關此詳細內容,請參見《PDF.NET(PWMIS資料開發框架)之SQL-MAP目標和規範》。

1.2 使用XML智慧提示

將上面的內容新增到剛才的SqlMap.config 檔案中,這樣,輸入尖括號,或者輸入空格,智慧提示內容就出來,如下所示:

這是新增完整的SqlMap.config 檔案,該檔案完全手寫,在智慧提示的幫助下,編寫還是很方便的。請注意配置檔案內各個節點屬性的內容,詳細內容請看上面連結的檔案。注意,這裡要用 CDATA 來寫SQL查詢。

注意:如果要執行獲得結果集的查詢,需要在Sql-Map檔案的命令節點裡面使用 Select 節點,並且需要指明 ResultClass 的型別,它有下面幾種可選值:

  1. ValueType --結果為值物件,比如Int,String之類的查詢單值結果
  2. DataSet --資料集,預設
  3. EntityObject --單個實體類物件
  4. EntityList --實體類列表

注意:如果指定 ResultClass="EntityObject" / ResultClass="EntityList" ,那麼需要同時申明 ResultMap 屬性,表示結果要對映到的具體型別,比如:

ResultClass="EntityObject" ResultMap="XXXNameSpace.YYYEntityClass"

有關此詳細內容,請參見《PDF.NET(PWMIS資料開發框架)之SQL-MAP目標和規範》。

注意:<Script > 配置節,出了有Type表面資料庫型別之外,還必須有 ConnectionString ="" Version="" 這樣的內容,否則,下面的程式碼生成不能生成程式碼。

二、使用程式碼生成器

2.1 配置程式碼生成器

開啟PDF.NET整合開發工具,選擇選單 “配置”--SQL-MAP程式碼生成器配置,出現下面的介面:

在編輯區域,滑鼠右鍵選單,啟用用編輯,如果是第一次配置,請一定刪除配置檔案內的中文註釋,否則配置檔案格式無法識別。

這裡主要配置SqlMap.config檔案所在的完整路徑,輸出程式碼的目錄,以及名稱空間之類。

編輯完成,在編輯區的滑鼠右鍵選單上,啟用“儲存檔案”的功能。

2.2 生成程式碼

如果上面配置正確,點選第二個工具欄的圖示,就可以自動呼叫處 PDFCodeMaker.exe 程式,讀取配置檔案資訊,自動生成DAL程式碼檔案,如下圖:

6

之後,我們新增剛才生成的DAL程式碼檔案到專案中,如上圖。

三、使用SqlMap配置檔案

3.1 SqlMap配置檔案的使用方式

SqlMap配置檔案有2種使用方式,

  • 在應用程式配置檔案的AppSeting 配置節裡面指定檔案路徑
  • 嵌入到程式集檔案作為資原始檔使用

在本示例中,採用嵌入式編譯的方式,這樣SQL語句的安全性更高,並且支援一個專案中使用多個SqlMap配置檔案,但是不如作為獨立檔案使用修改方便。如下圖:

這種方式編譯,該資原始檔的名字就是 “程式集預設名字空間.目錄名字.檔名字” ,這裡的例子是 SqlMapDemo.SqlMap.config ,由於在跟目錄下面,沒有目錄名字。

注意,要正確使用嵌入式SQL配置檔案,還必須在該檔案中指出"嵌入檔案的程式集名稱,資原始檔名字“,如本例如下圖紅色邊框標記的部分所示:

SqMap.config 檔案修改完成後,在此啟動 PDFCodeMaker.exe 程式,重新生成DAL檔案,如下所示,增加了簽入式檔案的設定:

3.2 生成SqlMapDAL檔案

檢查發現,DAL類檔案的名字空間不正確,這裡修改下配置檔案的 RootNameSpace 部分,如下圖:

重新生成DAL類檔案,我們看看最後生成的SqlMapDAL類的內容:

//使用該程式前請先引用程式集:PWMIS.Core,並且下面定義的名稱空間字首不要使用PWMIS,更多資訊,請檢視 http://www.pwmis.com/sqlmap 
// ========================================================================
// Copyright(c) 2008-2010 公司名稱, All Rights Reserved.
// ========================================================================
using System;
using System.Data;
using System.Collections.Generic;
using PWMIS.DataMap.SqlMap;
using PWMIS.DataMap.Entity;
using PWMIS.Common;

namespace SqlMapDemo.SqlMapDAL
{
/// <summary>
/// 檔名:TestSqlMapClass.cs
/// 類 名:TestSqlMapClass
/// 版 本:1.0
/// 建立時間:2015/5/12 17:16:32
/// 用途描述:SQL-MAP示例測試程式
/// 其它資訊:該檔案由 PDF.NET Code Maker 自動生成,修改前請先備份!
/// </summary>
public partial class TestSqlMapClass
    : DBMapper 
{
    /// <summary>
    /// 預設建構函式
    /// </summary>
    public TestSqlMapClass()
    {
        Mapper.CommandClassName = "TestGroup";
        //CurrentDataBase.DataBaseType=DataBase.enumDataBaseType.SqlServer;
        Mapper.EmbedAssemblySource="SqlMapDemo,SqlMapDemo.SqlMap.config";//SQL-MAP檔案嵌入的程式集名稱和資源名稱,如果有多個SQL-MAP檔案建議在此指明。
    }


    /// <summary>
    /// 找出每一個系的最高分,並且按系編號,學生編號升序排列
    /// </summary>
    /// <returns></returns>
    public DataSet QueryStudentSores( ) 
    { 
            //獲取命令資訊
            CommandInfo cmdInfo=Mapper.GetCommandInfo("QueryStudentSores");
            //執行查詢
            return CurrentDataBase.ExecuteDataSet(CurrentDataBase.ConnectionString, cmdInfo.CommandType, cmdInfo.CommandText ,null);
        //
    }//End Function


}//End Class

}//End NameSpace 

3.3 團隊開發

團隊開發常常涉及到檔案修改衝突,SqlMap配置檔案也會遇到,如果大家不去修改同一個Command配置,用原始碼管理器的自動合併功能是沒有問題的。

如果是獨佔式簽出管理,那麼一個開發人員使用SqlMap檔案,另外一個就只有等待了,但框架提供了變通的方式來解決這個問題。

  • 按功能模組劃分DAL程式集,每個DAL程式集一個SqlMap.config檔案,選擇嵌入式編譯;
  • 在一個DAL程式專案上建立多個SqlMap.config檔案,選擇嵌入式編譯 。

注意:建議每一個開發人員負責一個SqlMap.config檔案的管理,然後各自配置自己的PDFCodeMaker.exe.config

3.4 切換資料庫

在同一個SqlMap.config 檔案裡面新增新的 <Script Type="" 節點,比如Oracle ,然後將原來資料庫型別的SQL查詢改寫成當前型別的SQL查詢語句 ,程式會根據DBMapper的AdoHelper的實際型別自動選擇正確的<Script Type="" 節點,從而完成資料庫切換,實現你的應用系統跨資料庫的功能。

另外,也可以另外建立一個SqlMap.config 檔案,裡面專門寫新的資料庫下面的SQL語句,我們以前一個銀行的專案,就是這樣從SqlServer移植到PostgreSql的。

四、執行SQL-MAP程式

4.1 配置連線字串

SQL-MAP DAL類程式仍然通過AdoHelper 物件來執行,這裡新增一個應用程式配置檔案:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name ="default" connectionString="Data Source=.;Initial Catalog=TestDB;Integrated Security=True" providerName="SqlServer"/>
  </connectionStrings>
</configuration>

4.2 執行程式

然後,就可以寫如下的程式碼來測試SQL-MAP程式了:

 class Program
 {
     static void Main(string[] args)
     {
         Console.WriteLine("PDF.NET SOD框架 SqlMap示例程式--2015.5.12-------");
         Console.WriteLine("http://www.pwmis.com/sqlmap ---------");
        
         SqlMapDemo.SqlMapDAL.TestSqlMapClass test = new SqlMapDAL.TestSqlMapClass();

         //AdoHelper db = new SqlServer();
         //取最後一個連線配置
         AdoHelper db = MyDB.GetDBHelper();
         //SQL-MAP DAL 預設也會取最後一個連線配置,所以下面一行程式碼可以註釋
         //test.CurrentDataBase = db;
         DataSet data = test.QueryStudentSores();

         Console.WriteLine("查詢到記錄數量:{0}",data.Tables[0].Rows.Count);
         Console.WriteLine("測試完成。");
         Console.Read();
     }
 }

結果執行如下:

設定一個斷點,我們來看看 ”SQL-MAP DAL物件“的Mapper物件有哪些內容:

在及時視窗輸入 test.Mapper ,回車,就可看到上面的內容了。這裡顯示了剛才配置的SQL-MAP嵌入式檔案的位置和檔案獨特的路徑:SqlMapFile 屬性。

 下面是詳細的結果:

test.Mapper
{PWMIS.DataMap.SqlMap.SqlMapper}
    _CommandClassName: "TestGroup"
    _DataBase: {PWMIS.DataProvider.Data.SqlServer}
    _dataBaseType: SqlServer
    _embedAssemblySource: "SqlMapDemo,SqlMapDemo.SqlMap.config"
    _ParaChar: "@"
    _ParamsMap: {PWMIS.Common.ParamMapType[0]}
    _ParasLenth: 0
    _ResultClass: ValueType
    _ResultMap: ""
    _SqlMapFile: "@R://SqlMapDemo,SqlMapDemo.SqlMap.config"

 結語

測試完全正確,使用 SOD框架的SQL-MAP 技術是不是很簡單?

後續都只需要修改下檔案裡面的SQL語句就行了,

一次配置,一鍵生成!

這就是,SOD框架的SQL-MAP 技術的特點!結合SOD框架的ORM功能,它完全可以代替MyBatis.Net 。

感謝大家關注PDF.NET SOD框架,這是一個開源免費的框架,詳細資訊請看官網 http://www.pwmis.com/sqlmap

框架開源專案地址:http://pwmis.codeplex.com ,本專案示例程式碼已經簽入到codeplex 上,大家可以通過SVN下載使用。

本篇程式已經提供了獨立的下載:

Sql-Map Demo

本文相關視訊播放和下載點選這裡》》