引言

今天看到一片热门的博客, .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目标和规范》。

二、使用代码生成器

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

SqlMapDemo.SqlMapDAL

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

将复杂查询写到SQL配置文件--SOD框架的SQL-MAP技术简介的更多相关文章

  1. Git.Framework 框架随手记--SQL配置文件的使用

    前面几篇文章讲到了如何使用框架进行简单结构的增删改查操作,由于个人能力有限在对于复杂的SQL操作面前也是无能为力,只能自己动手来写SQL语句.在Git.Framework中提供了一个公共的接口来直接操 ...

  2. 【Mybatis】MyBatis之Sql配置文件的使用(四)

    上一章[Mybatis]MyBatis对表执行CRUD操作(三),已经讲了基本操作,本章介绍Sql配置文件中常用功能 1.插入返回主键 2.参数值的获取方式 3.resultMap使用 插入返回主键 ...

  3. [转]如何写出高效能TSQL -深入浅出SQL Server Relational Engine (含 SQL 2014 in-memory Engine)

    [转]如何写出高效能TSQL -深入浅出SQL Server Relational Engine (含 SQL 2014 in-memory Engine) http://blogs.technet. ...

  4. 一对一关联查询时使用relation连贯操作查询后,调用getLastSql()方法输出的sql语句

    如题: 一对一关联查询时使用relation连贯操作查询后,调用getLastSql()方法输出的sql语句不是一条关联查询语句. 例如: $list = $db->relation(true) ...

  5. (转载)将DELPHI数据库连接写进INI配置文件中

    将DELPHI数据库连接写进INI配置文件中 procedure TDM.DataModuleCreate(Sender: TObject); var piececonfg:Tinifile; pat ...

  6. 用游标实现查询当前服务器所有数据库所有表的SQL

    declare @name varchar(100) DECLARE My_Cursor CURSOR --定义游标 FOR (SELECT Name FROM Master..SysDatabase ...

  7. 图解“管道过滤器模式”应用实例:SOD框架的命令执行管道

    管道和过滤器 管道和过滤器是八种体系结构模式之一,这八种体系结构模式是:层.管道和过滤器.黑板.代理者.模型-视图-控制器(MVC) 表示-抽象-控制(PAC).微核.映像. 管道和过滤器适用于需要渐 ...

  8. DataSet的灵活,实体类的方便,DTO的效率:SOD框架的数据容器,打造最适合DDD的ORM框架

    引言:DDD的困惑 最近,我看到园子里面有位朋友的一篇博客 <领域驱动设计系列(一):为何要领域驱动设计? >文章中有下面一段话,对DDD使用产生的疑问: •没有正确的使用ORM, 导致数 ...

  9. Oracle 免费的数据库--Database 快捷版 11g 安装使用与"SOD框架"对Oracle的CodeFirst支持

    一.Oracle XE 数据库与连接工具安装使用 Oracle数据库历来以价格昂贵出名,当然贵有贵的道理,成为一个Oracle DBA也是令人羡慕的事情,如果程序员熟悉Oracle使用也有机会接触到大 ...

随机推荐

  1. 用Ant来做一键部署

    部署Java Web项目到远程服务器上,以前经常用的操作方式: 1.在eclipse上导出项目war包 2.把war包通过ftp方式传到服务器上,比如Tomcat的webapps目录下 3.启动tom ...

  2. Oracle补习班第三天

    In every triumph, there's a lot of try. 每个胜利背后都有许多尝试 Oracle管理实例组件 主要组件分为两部分例程,与数据库: 例程分为两部分SGA跟进程: S ...

  3. 【转】Linux查看内存大小和插槽

    原文https://wsgzao.github.io/post/linux-memory/ Linux 查看内存的插槽数,已经使用多少插槽,每条内存多大,已使用内存多大 dmidecode | gre ...

  4. inux grep 命令 搜索含有"zynq"字符的文件

    使用命令grep -rl 'zynq' /work/xilinx/u-boot-xlnx-master (有引号)-r 选项表示递归(recursive)遍历所有子目录-l 选项表示只列出文件名 /w ...

  5. 安装libudev-dev,解决依赖错误

    http://stackoverflow.com/questions/17181073/ubuntu-12-04-libudev-dev-wont-install-because-of-depende ...

  6. mysql日志与备份恢复

    一.mysql日志: mysql的日志种类有很多,常见的有二进制日志,一般查询日志,满查询日志,中继日志,事务日志等,具体信息可以通过 mysql> SHOW GLOBAL VARIABLES ...

  7. This kind of launch is configured to open the Debug perspective when it suspends.

    This kind of launch is configured to open the Debug perspective when it suspends. 因为设置了断点才会弹出这个,不需要调 ...

  8. select问题总结

    select 从后台取来的值如何放到select里面的文本框中? $(".type option").each(function(){ if($(this).val() == de ...

  9. 低版本的xcode打开xcode8上的xib错误

    XIB和Storeboard适配 在Xcode8之前,创建一个XIB或SB文件,都是一个600*600的方块XIB文件.在Xcode8之后,创建的XIB文件默认是6s尺寸的大小. 但是Xcode8打开 ...

  10. arcgis_engine_develop_error_42

    解决: 今天在VS2013打开程序时,手工添加了pageLayoutControl隔一会弹出错误窗口:Provide your license server administrator with th ...