Java程序员编程时需要混合面向对象思维和一般命令式编程的方法,但是Java程序员在写SQL语句时,一切都变了。SQL是说明性语言而非面向对象或是命令式编程语言,而且它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统, 可以使用相同的结构化查询语言作为数据输入与管理的接口。结构化查询语言语句可以嵌套,这使它具有极大的灵活性和强大的功能。
下面则是一些Java程序员在写SQL时常犯的错误,你有吗?
第一:Java程序员写SQL时对NULL的误解可能是最大的错误。当你从数据库拿东西或是绑定变量时,JDBC将SQL NULL 和Java中的null对应了起来。这样导致了NULL = NULL(SQL)和null=null(Java)的误解。对于NULL最大的误解是当NULL被用作行值表达式完整性约束条件时。最好是当你写SQL时要不停得想到NULL的用法来避免错误。
第二就是通过JDBC分页技术给大量的结果进行分页操作,实际上大部分的数据库都会支持一些分页命令实现分页效果,譬如LIMIT…OFFSET,TOP…START AT语句等。即使没有支持这些语句的数据库,仍有可能对ROW NUMBER() OVER()过滤(DB2,SQL Server2008等),这些比在内存中实现分页更快速。在处理大量数据中,效果尤其明显。
第三是在Java内存中处理数据中,很少有Java开发者能将SQL理解的很好。许多的Java开发者将SQL数据加载到内存中,将这些数据转换成某些相近的集合类型,然后在那些集合上面使用边界循环控制结构执行数学运算。 尽量在每次你使用Java实现一个以数据为中心的算法时,多想一下有没有一种方法可以让数据库代替。
第四是使用聚合函数代替窗口函数(window functions),在SQL中聚合数据意味着使用GROUP BY语句与聚合函数相映射。在很多情形下都工作得很好,如聚合数据需要浓缩常规数据,那么就在join子查询中使用group查询。其实在SQL:2003中定义了窗口函数,这个在很多主流数据库都实现了它。窗口函数能够在结果集上聚合数据,但是却没有分组。事实上,每个窗口函数都有自己的、独立的PARTITION BY语句。并且使用窗口函数,能够使SQL更易读,像关系数据库管理系统能够更容易优化窗口函数。其实当你在子查询中使用GROUP BY语句时,可以多想一下是否可以使用窗口函数完成。
第五是使用内存间接排序,SQL的ORDER BY语句支持很多类型的表达式,包括CASE语句,对于间接排序十分有用。你可能重来不会在Java内存中排序数据,因为你会想:SQL排序很慢,SQL排序办不到。其实当你在内存中排序任何SQL数据是,可以考虑一下是否不能在数据库中排序。这对于数据库分页数据十分有用。
第六是不去使用MERGE语句,其实这并不是一个错误,可能者是对于强大的MERGE语句的某种畏惧。一些数据库知道其他形式的UPSERT语句,例如,MYSQL的 ON DUPLICATE KEY UPDATE 分句。但是MERGE真的是如此强大,在大多数重视扩展SQL标准的数据库,如SQL Server中是很重要的。但是如果你正在通过链接INERT和UPDATE,或者通过链接SELECT…FOR UPDATE进行UPSERT,然后进行INSERT或者UPDATE,请三思。在冒此风险之外,你还可以选择使用一个简单的MERGE语句进行表达。
以上就是关于程序员在写SQL程序时常犯的错误,你中了吗?如果有要尽量避免哟。