对于JAVA程序员而言,在编程时时常需要面临混合面向对象思维和一般命令式编程的方法,如何将两者巧妙的结合起来是检测一个程序员水平的关键之处。
但是当JAVA程序员写SQL语句时,程序员所遇到的问题就不一样了。因为SQL是说明性语言而非面向对象或是命令式编程语言。在SQL中要写个查询语句是很简单的。但在JAVA里类似的语句却并不相同,往往会出现不少问题,因为此时不仅要反复考虑编程范式,还需要考虑算法的问题。
下面小编整理了一些JAVA程序员在写SQL时最常出现的10个错误,并在下方提供了解决方法,希望能够帮助大家尽量避免类似的问题出现。
1、忘掉NULL
许多JAVA程序员在写SQL时都会因为两个原因对NULL产生误解,一个因为NULL也称作UNKNOWN。另一个则是因为当我们从数据库拿东西或是绑定变量时,JDBC将SQL NULL 和Java中的null对应了起来。这样就导致了NULL = NULL(SQL)和null=null(Java)的误解。
解决方法:
轻率地使用null可能会导致很多令人惊愕的问题。通过学习Google底层代码库,我们发现95%的集合类不接受null值作为元素。这里提议,相比默默地接受null,使用快速失败操作拒绝null值对开发者更有帮助。
2、使用UNION 代替UNION ALL
当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以Oracle UNION ALL的方式被合并,然后在输出最终结果前进行排序。假如用 Oracle UNION ALL替代UNION,这样排序就不是必要了。效率就会因此得到提高。
需要注意的是,Oracle UNION ALL将重复输出两个结果集合中相同记录。因此各位还是要从业务需求分析使用Oracle UNION ALL的可行性。UNION 将对结果集合排序,这个操作会使用到SORT_AREA_SIZE这块内存。对于这块内存的优化也是相当重要的。
3、在JAVA内存中处理数据
很多JAVA开发者会将SQL数据加载到内存中,然后将这些数据转换成某些相近的集合类型,然后在那些集合上面使用边界循环控制结构(至少在Java8的集合升级以前)执行令人生厌的数学运算。
但是一些SQL数据库支持先进的OLAP特性,,这样可以使开发者使用起来更方便一些,举个例子来说,让数据库做处理之后将结果带到JAVA内存中。以上操作,你可以通过通过将OLAP移到数据库,获得以下两项好处:
1)便利性,这种操作比在JAVA中编写正确的SQL来的更加容易。
2)效率,数据库比算法处理起来更加快,并且,操作人员不必再去传递百万条记录了,极大的提高了工作效率。
所以,当开发者使用JAVA实现一个以数据为中心的算法时,可以先问问自己,有没有一种方法可以让数据库来代替为我做这种麻烦事,这样也能大幅度的提高工作效率。
4、在java内存中加入数据
每个开发者在使用SQL初期,对于在其中使用JOIN语句,都并不是十分的确认。如果基于成本的优化去选择实现实现嵌套循环,在创建一张连接表源前,可能加载所有的表在数据库内存中,这可能是可行的,但是发生的概率太低了。
不少JAVA开发人员在加载两张表通过分开查询到一个映射中,并且在某种程度上把他们加到了内存中。其实正确的做法是,当你在各个步骤中都有从各种表的查询操作,那么先好好想想是否可以表达你的查询操作在单条语句中,再去实践。
5、不使用MERGE语句
许多开发者不用MERGE语句的最大原因可能是缺少知识,或者对其强大语句信心不足,但是MERGE语句在数据库中着实强大,以至于大幅度的扩展了SQL的标准,例如SQL SERVER。
所以开发者完全可以尝试使用这一强大的语句,当你使用像联合联合INSERT和UPDATE或者联合SELECT .. FOR UPDATE然后在INSERT或UPDATE等更新插入时,完全可以使用一个更简单的MERGE语句来远离冒险竞争条件。
6、使用内存间接排序
有很多开发者因为SQL排序慢或是功能性达不到的原因,不会选择在JAVA内存中排序数据。这时候SQL的ORDER BY语句就可以派上用场,它支持支持很多类型的表达式,包括CASE语句,对于间接排序十分有用。
当你在内存中排序任何SQL数据,要先考虑一下能否在数据库中排序。这对于数据库分页数据十分有用。
7、通过JDBC分页技术给大量的结果进行分页操作
几乎大部分的数据库都会支持一些分页命令实现分页效果,譬如LIMIT..OFFSET,TOP..START AT,OFFSET..FETCH语句等,因为这些比在内存中实现分页更为快速,尤其在处理大量数据中,更为明显。
往往仅仅使用这些语句,那么一个工具(例如JOOQ)就可以模拟这些语句的操作。
8、一条一条的插入大量纪录
不要使用INSERT语句来一条一条的出入成千上万的记录,(因为)每次都会创建一个新的PreparedStatement对象。如果你的所有记录都插入到同一个表时,那么就创建一个带有一条SQL语句以及附带很多值集合的插入批处理语句。
你可能需要在达到一定量的插入记录后才提交来保证UNDO日志瘦小,这依赖于你的数据库和数据库设置。
网友评论