`
liaobinxu
  • 浏览: 43289 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

DSL-SQL源码分析

阅读更多
第一次分析源代码,不太会描述,部分文字摘自 在CLR之上的构建领域特定语言
http://www.infoq.com/cn/articles/internal-dsls-java
针对特定域语言(DSL)的定义问题,提出了一种基于对象的语言构造方法,该方法将特定域语言语义划分为领域相关语义和领域无关语义,针对领域相关语义,采用对象将其封装,并通过视图对象和模型对象分别完成领域相关语义的定义与解释;针对领域无关语义,利用现有语言开发工具,直接定义并生成语言基本特性的解释模块,最后将对象和语言基本特性相集成,从而完成DSL的定义与实现.采用基于对象的构造方法可迅速地定义DSL,且具有较强的扩展性.

1.简介
领域特定语言(DSL)通常被定义为一种特别针对某类特殊问题的计算机语言,它不打算解决其领域外的问题。对于DSL的正式研究已经持续很多年,直到最近,在程序员试图采用最易读并且简炼的方法来解决他们的问题的时候,内部DSL意外地被写入程序中。近来,随着关于Ruby和其他一些动态语言的出现,程序员对DSL的兴趣越来越浓。这些结构松散的语言给DSL提供某种方法,使得DSL允许最少的语法以及对某种特殊语言最直接的表现。但是,放弃编译器和使用类似Eclipse这样最强大的现代集成开发环境无疑是该方式的一大缺点。然而,作者终于成功地找到了这两个方法的折衷解决方式,并且,他们将证明该折衷方法不但可能,而且对于使用Java这样的结构性语言从面向DSL的方式来设计API很有帮助。本文将描述怎样使用Java语言来编写领域特定语言,并将建议一些组建DSL语言时可采用的模式。

Java适合用来创建内部领域特定语言吗?

在我们审视Java语言是否可以作为创建DSL的工具之前,我们首先需要引进“内部DSL”这个概念。一个内部DSL在由应用软件的主编程语言创建,对定制编译器和解析器的创建(和维护)都没有任何要求。Martin Fowler曾编写过大量各种类型的DSL,无论是内部的还是外部的,每种类型他都编写过一些不错的例子。但使用像Java这样的语言来创建DSL,他却仅仅一笔带过。

另外还要着重提出的很重要的一点是,在DSL和API两者间其实很难区分。在内部DSL的例子中,他们本质上几乎是一样的。在联想到DSL这个词汇的时候,我们其实是在利用主编程语言在有限的范围内创建易读的API。“内部DSL”几乎是一个特定领域内针对特定问题而创建的极具可读性的API的代名词。

任何内部DSL都受它基础语言的文法结构的限制。比如在使用Java的情况下,大括弧,小括弧和分号的使用是必须的,并且缺少闭包和元编程有可能会导致DSL比使用动态语言创建来的更冗长。

但从光明的一面来看,通过使用Java,我们同时能利用强大且成熟的类似于Eclipse和IntelliJ IDEA的集成开发环境,由于这些集成开发环境“自动完成(auto-complete)”、自动重构和debug等特性,使得DSL的创建、使用和维护来的更加简单。另外,Java5中的一些新特性(比如generic、varargs 和static imports)可以帮助我们创建比以往任何版本任何语言都简洁的API。

一般来说,使用Java编写的DSL不会造就一门业务用户可以上手的语言,而会是一种业务用户也会觉得易读的语言,同时,从程序员的角度,它也会是一种阅读和编写都很直接的语言。和外部DSL或由动态语言编写的DSL相比有优势,那就是编译器可以增强纠错能力并标识不合适的使用,而Ruby或Pearl会“愉快接受”荒谬的input并在运行时失败。这可以大大减少冗长的测试,并极大地提高应用程序的质量。然而,以这样的方式利用编译器来提高质量是一门艺术,目前,很多程序员都在为尽力满足编译器而非利用它来创建一种使用语法来增强语义的语言。

利用Java来创建DSL有利有弊。最终,你的业务需求和你所工作的环境将决定这个选择正确与否。
2.将Java作为内部DSL的平台
动态构建SQL是一个很好的例子,其建造了一个DSL以适合SQL领域,获得了引人注意的优势。

传统的使用SQL的Java代码一般类似于:
String sql="SELECT t.id " + "FROM table AS t "
				+ "INNER JOIN table1 AS t1 ON (t.id=t1.id) "
				+ "WHERE ((t.id='a') AND (t1.time BETWEEN '1900' AND '2000')) "
				+ "GROUP BY t.id HAVING (t.id>1) " + "ORDER BY t.id ASC "

现在用DSL语言的java实现比表示SQL
Table t = table("table").as("t");
		Table t1 = table("table1").as("t1");
		Field tId = t.field("id");
		Field t1Id = t1.field("id");
		Field t1Time = t1.field("time");
Query query = select(tId).from(t).join(inner(t1, tId.eq(t1Id))).where(
				and(tId.eq("'a'"), t1Time.between("'1900'", "'2000'")))
				.groupBy(tId).having(tId.gt("1")).orderBy(asc(tId));

String sql=query.toString();

这个DSL版本有几项优点。后者能够透明地适应转换到使用PreparedStatement的方法——用String拼写SQL的版本则需要大量的修改才能适应转换到使用捆绑变量的方法。如果引用不正确或者一个integer变量被传递到date column作比较的话,后者版本根本无法通过编译。代码“nvl(foo, 'X') != 'X'”是Oracle SQL中的一种特殊形式,这个句型对于非Oracle SQL程序员或不熟悉SQL的人来说很难读懂。例如在SQL Server方言中,该代码应该这样表达“(foo is null or foo != 'X')”。但通过使用更易理解、更像人类语言的“isNotNullOr(rejectedValue)”来替代这段代码的话,显然会更具阅读性,并且系统也能够受到保护,从而避免将来为了利用另一个数据库供应商的设施而不得不修改最初的代码实现。
3.现在介绍DSL-SQL
DSL-SQL是thoughtWorks的开源项目
域代码 http://code.google.com/p/sql-dsl/
附件有源代码分析
分享到:
评论
1 楼 lost_alien 2010-06-29  
复杂的sql恐怕用这个就够呛了。。。。

相关推荐

    dsl-maker:Kotlin多平台库,可帮助使用ANTLR或简单的内置解析器创建DSL

    在“dsl-maker-main”这个压缩包中,很可能是包含了DSL-maker库的源码,通过查看和学习这些源码,开发者可以深入了解DSL-maker的工作原理,甚至对其进行扩展或定制,以满足特定需求。总的来说,DSL-maker为Kotlin...

    antlr4-master 源码

    它广泛应用于构建语言、工具和框架,包括SQL解析器、配置文件解析器、DSL(领域特定语言)以及各种编程语言的编译器或解释器。ANTLR4生成的解析器具有高效、灵活和可扩展的特点。 在这个"antlr4-master"源码仓库中...

    Apache Camel 源码分析.rar

    源码分析可以帮助我们理解 Camel 是如何执行 SQL 查询、处理结果集,以及如何处理事务和异常的。这对于我们理解如何在分布式环境中安全地操作数据库至关重要。 最后,我们来看 `mybatis` 组件,它结合了流行的 ...

    Java_使用SQL查询Elasticsearch.zip

    首先,Elasticsearch虽然原生支持JSON格式的查询语句(即DSL),但为了满足开发人员对SQL的熟悉度和习惯,出现了诸如Elasticsearch SQL这样的项目,它允许我们使用SQL语法来操作ES数据。 1. **Elasticsearch SQL...

    奥克托。jl:octopus:是Julia中的一个SQL查询DSL

    **源码分析** 压缩包中的"Octo.jl-master"可能包含Octo.jl的源代码,供开发者深入研究其内部工作原理,或者进行自定义扩展。通过查看源码,你可以了解如何构建这样一个DSL,以及它是如何将Julia表达式转化为SQL语句...

    西门子PLC数据采集源码

    4. **循环读取**:源码具备循环读取功能,这意味着它可以持续不断地从PLC获取数据,这对于实时监控或数据分析至关重要。用户可以根据需要自定义循环间隔和读取次数。 5. **地址列表设定**:用户可以预先设定要读取...

    camel-connector-oracle-commerce:适用于 Apache Camel 的 Oracle Commerce Connector

    4. **路由规则**:通过 Camel 的 DSL(Domain Specific Language),开发者可以定义复杂的路由规则,将 Oracle Commerce 的数据流导向不同的处理路径。 5. **集成测试**:连接器可能包括一套测试用例,以确保与 ...

    纯函数SQL生成

    源码分析可以帮助我们学习以下内容: 1. **类型安全的构建器**:了解如何使用Scala的类型系统来确保生成的SQL语句是正确的,避免在运行时出现语法错误。 2. **模式和组合**:查看如何设计函数和数据结构,以便于...

    亮剑Java web源代码+ppt教程05——08

    "亮剑Java web源代码+ppt教程05——08"是一个关于Java Web开发的教育资源,结合了实际项目案例和理论讲解。这个压缩包包含了第五到...同时,结合源代码分析,能更好地理解和应用所学知识,为实际项目开发打下坚实基础。

    ES2.3.4 的sql插件

    ES 2.3.4 的 SQL 插件极大地提升了 ES 对 SQL 查询的支持,使得那些熟悉 SQL 的开发者可以更方便地使用 ES 进行数据分析和搜索。通过 REST API 或 JDBC 驱动,我们可以轻松地集成 SQL 插件到各种系统中,提升开发...

    cclfow 完整源码

    - 源码中的数据访问层包含了实体类、DAO 接口和实现,以及 SQL 脚本。 8. **安全与权限** - cclfow 通常有用户认证和权限管理机制,确保只有授权的用户能操作流程实例。 - 源码中可能包含身份验证、授权的实现,...

    在rust - cch123/elastic-rs中将bool表达式转换为elasticsearch DSL

    在 Rust 开发环境中,`cch123/elastic-rs` 是一个针对 Elasticsearch 的...通过阅读和学习这些源码,你将能够掌握如何使用 Rust 和 Elasticsearch 的 DSL 来构建复杂的查询逻辑,并提升在数据检索和分析方面的能力。

    kotlin源码

    Kotlin源码的分析可以帮助我们理解其内部机制,提高开发效率。 1. **Kotlin在Android开发中的应用**: - Kotlin的类和对象支持使得在Android中构建模块化、可维护的代码变得更加容易。 - 非空类型系统提高了代码...

    antlr4-4.5

    - **SQL解析器**:用于处理SQL查询,提取数据或者进行查询优化。 - **配置文件解析器**:用于读取和验证配置文件的格式。 - **DSL(领域特定语言)**:构建定制的语言,用于特定领域的任务,如图形渲染或数据处理。 ...

    之基于Java+大数据的定位电商用户画像实现精准营销项目源码.zip

    项目可能使用Hadoop进行大规模数据的分布式存储和计算,使用Spark进行实时或近实时的数据处理,以及使用Hive进行数据仓库建设,提供SQL查询能力。同时,可能会用到数据挖掘算法如关联规则、聚类等来挖掘用户行为模式...

    wms-parent-master-master JAVA 代码

    - **Gradle**:另一种构建工具,提供更大的灵活性,支持Groovy和Kotlin DSL来定义构建脚本。 - **IntelliJ IDEA** 或 **Eclipse**:流行的Java IDE,提供代码提示、自动完成、调试等功能。 - **JUnit**:用于编写和...

    从实现原理谈谈低代码.docx

    6. 声明式语言在专业研发中的应用:声明式语言在部分领域已经是主流了,如 HTML+CSS 是一种页面展现的 DSL,SQL 是一种数据查询及处理的 DSL,K8S 的 yaml 是一种服务部署的 DSL,NGINX conf 是一种反向代理的 DSL。...

    Agile Web Development with Rails 2nd Edition源码

    源码是学习和理解任何编程技术的基石,通过分析书中的源码,我们可以更深入地掌握Rails的精髓。 1. **Agile Development**: 敏捷开发是一种强调快速响应变化、迭代式开发和团队协作的软件开发方法。它鼓励通过短期...

    Learn-More-Do-Less:Java资料库

    源码分析 JDK 线程相关源码 框架使用 web 层框架 Spring MVC Webflux 持久层框架 Hibernate Mybatis 消息中间件框架 ActiveMQ kafka 全文搜索引擎 ElasticSearch DSL语法 Kibana 微服务架构 Spring Boot Spring ...

Global site tag (gtag.js) - Google Analytics