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

高效使用JDBC

    博客分类:
  • Java
阅读更多

在JavaEE应用中,使用ORM操作数据库虽然简单快捷(参考“高效使用JavaEE ORM”),但是毕竟是对JDBC的封装,很多时候,ORM还是不能满足我们的需求,主要是两个问题:

1. 速度不如JDBC,毕竟是封装JDBC,有额外的开销;

2. ORM提供的xQL很多时候无法满足需求,还需要数据库相关的SQL,这时,必须使用JDBC。

使用JDBC虽然麻烦点,但是,按照软件设计的思想,一步一步封装必要的代码,还是可以做到性能与开发效率并存。

首先,要坚决避免的就是不断重复编写try... catch... finally...。对于查询、更新、插入和删除操作,每一种操作只允许编写一次try... catch... finally...。如何实现?有两个方法。

第一个办法是找一个现成的封装了这些JDBC操作的框架,最好的方案当然就是Spring的JDBC框架了,顺便可以参考JdbcTemplate的源码,以便提升自己的JavaEE功力。

如果不使用Spring,那就采用第二个办法,自己造轮子,封装一个JDBC框架。

很多人反对自己造轮子,原因不外乎费事。不过很多时候,造轮子并不麻烦,而且可以满足特定的需求。今天要造的轮子就是一个封装JDBC的框架:Express-Persist

Express-Persist是ExpressMe的持久化子项目,目标是封装JDBC并提供简单的数据库操作接口。

为什么不使用Spring JDBC呢?主要原因只有一个:Spring的JDBC目前还是1.4兼容的,不支持1.5的泛型。Express-Persist要提供的接口除了基本的数据库操作外,还要实现:

1. 简单的ORM映射,注意是简单的,没有Hibernate那样完整而强悍,本质上就是把ResultSet的每一条记录变成一个JavaBean,可以参考Spring JDBC的RowMapper,实现非常容易;

2. 充分利用Java 5泛型支持,都是类型安全的参数和返回值,不用做强制转化;

3. 利用Java 5的注解(Annotation)把SQL标记在接口方法上,比如:

1.@Query("select * from User where u.id=:id")
2.public User get(String id);

4. 最后,最重要的,只编写接口,没有实现类!

没有实现类,那JDBC代码写在哪?当然由Express-Persist框架自动生成了。如何自动生成?运行一个命令自动生成Java类?在“高效使用JavaEE ORM”一文中我们已经对JDO的这种静态增强方式表示了强烈的鄙视和唾弃,因此绝不可重蹈覆辙。Express-Persist会在启动时根据接口动态创建出类,不过我们不采用Hibernate使用的CGLIB库,而是直接通过JDK的动态代理功能实现动态类。

如何绑定SQL参数

DAO接口的方法参数要自动绑定到SQL参数中,由于方法参数的顺序与SQL参数的顺序可能不一致,因此,只能使用命名参数来绑定,即:SQL参数定义为:xxx,对应的方法参数用@Param("xxx")标记。

当SQL参数很多的时候(尤其是INSERT语句),方法参数也非常多,调用起来非常不方便,比如:

1.@Update("insert into User values(:id, :email, :password, :name)")
2.public int create(@Param("id") String id, @Param("email") String email,@Param("password") String password, @Param("name") String name);

而且都是String类型,调用起来容易出错。

因此,Express-Persist允许使用JavaBean绑定,把上述代码变为:

1.@Update("insert into User values(:u.id, :u.email, :u.password, :u.name)")
2.public int create(@Param("u") User u);

这样,调用起来只需要传入一个User对象即可,简单且不易出错。

如何分页查询

绝大多数数据库支持分页查询,但语法各不相同。如果让开发者自己写分页SQL语句,难度较大,而且不易复用。因此,Express-Persist仿照Hibernate的做法,为每一种数据库定义一个Dialect,处理分页,这样,无需考虑数据库的特定分页语法,只需额外添加@FirstResult和@MaxResults这两个注解,以便传入分页参数:

1.@Query("select * from User u order by id")
2.List<User> queryAll(@FirstResult int first, @MaxResults int max);

Express-Persist已经内置HSQLDB、MySQL和Oracle的Dialect支持,也可以编写其他数据库的Dialect,只需实现Dialect接口即可。

如何把ResultSet映射为Java对象

要把ResultSet映射为Java对象,我们采用Spring JDBC使用的RowMapper方案,改进之处在于采用了泛型,并且,提供一个BeanRowMapper,实现ResultSet到JavaBean的转换,因为大部分的转换都是到JavaBean。

利用Java 5的泛型支持,可以非常容易地生成一个BeanRowMapper,而无需编写任何方法:

1.public class UserRowMapper extends BeanRowMapper<User> {}

@MappedBy用于告诉Express-Persist如何映射ResultSet:

1.@MappedBy(UserRowMapper.class)
2.@Query("select * from User u order by id")
3.List<User> queryAll(@FirstResult int first, @MaxResults int max);

如果返回结果仅有一个,例如根据主键查询,则必须加上一个@Unique注解,这样,Express-Persist将自动检查返回的记录数,如果不为1,则抛出异常:

1.@Unique
2.@MappedBy(UserRowMapper.class)
3.@Query("select * from User u where id=:id")
4.User queryById(@Param("id") String id);

如果返回结果允许多个,则返回值应该定义为泛型List,如List<User>。

Batch支持

批量插入或修改时,使用和不使用JDBC Batch,其性能将有数量级的差距。Express-Persist提供Batch支持,通过继承BatchSupport接口:

1.public class UserDao extends BatchSupport {
2.@Update("update User set name=:name where id=:id")
3.void updateUserName(@Param("id") String id, @Param("name") String name);
4.}

Batch操作的代码稍微复杂一点,必须用try... finally执行,以便正确释放资源:

01.try {
02.dao.prepareBatch();
03.// now the batch prepared:
04.dao.updateUserName("id-1""change A's name");
05.dao.updateUserName("id-2""change B's name");
06.dao.updateUserName("id-3""change C's name");
07.// execute:
08.int[] results = dao.executeBatch();
09.}
10.finally {
11.dao.closeBatch();
12.}

事务控制

Express-Persist仅支持JDBC事务,因此无法远程传播事务。事务代码通常写在Web应用程序的Filter或Interceptor中,只需编写一次:

01.TransactionManager txManager = ...;
02.Transaction tx = txManager.beginTransaction();
03.try {
04.// TODO: DAO operations here...
05.tx.commit();
06.}
07.catch (Exception e) {
08.tx.rollback();
09.}

如果你想体验一下Express-Persist带来的全新Java持久化方案,可以从http://express-me.googlecode.com/files/express-persist.jar下载Jar包(含源代码)。完整的文档请参考http://code.google.com/p/express-me/wiki/ExpressPersist

12
6
分享到:
评论
14 楼 chenchangqun11 2011-01-06  
你这文章与标题不符啊
13 楼 rain16881 2009-10-19  
请问有没一个完整的测试代码啊!!..
不清楚怎样用呢.
本人e-mail
rain16881@hotmail.com

thanks you ..
12 楼 qbq 2009-09-18  
感觉这个很像seasar的s2dao
有对这种方式感兴趣的可以看看
个人感觉s2dao封装得更好,更易用
11 楼 xiaoban0514 2009-09-17  
treblesoftware 写道
用ORM提高的是开发效率。不是程序效率。而且,ORM用好,在某些方面效率不比JDBC差,综合来说,ORM更加实用。

想把ORM用好也不是简单的事,反正个人觉得还是JDBC效率更加好点。
10 楼 asklxf 2009-09-17  
mathfox 写道
感觉怎么文不对题呢?

有一点广告成分
9 楼 asklxf 2009-09-17  
superdandy 写道
为什么要使用jdk的动态代理呢? 既然使用薄层封装jdbc,就是为了提高性能。 那么为什么要使用jdk的接口动态代理机制呢? 速度明显比cglib慢的

动态代理很快,可以忽略不计,不用cglib是为了尽量少依赖jar
8 楼 pangbuddy 2009-09-17  
treblesoftware 写道
用ORM提高的是开发效率。不是程序效率。而且,ORM用好,在某些方面效率不比JDBC差,综合来说,ORM更加实用。


顶你!
7 楼 xly_971223 2009-09-17  
en 受够了hibernate的可以试试这个
6 楼 superdandy 2009-09-17  
为什么要使用jdk的动态代理呢? 既然使用薄层封装jdbc,就是为了提高性能。 那么为什么要使用jdk的接口动态代理机制呢? 速度明显比cglib慢的
5 楼 caizhongda 2009-09-16  
我感觉是跟风啊。。为什么啥都想用Annotation呢。?
4 楼 唯快不破 2009-09-16  
我自己的项目是jdbc查询,orm用来增,删,改。
3 楼 treblesoftware 2009-09-16  
用ORM提高的是开发效率。不是程序效率。而且,ORM用好,在某些方面效率不比JDBC差,综合来说,ORM更加实用。
2 楼 mathfox 2009-09-16  
感觉怎么文不对题呢?
1 楼 myseo 2009-09-16  
用dbutils吧

相关推荐

    weblogic和jdbc

    WebLogic和JDBC是企业级应用开发中的两个关键组件,它们在构建分布式、数据库驱动的...在实际开发中,应根据项目需求合理配置WebLogic的JDBC设置,优化数据源,以及高效使用JDBC API,以实现高效、稳定的企业级应用。

    JAVA数据库编程JDBC .rar

    在《OReilly - Database Programming With Jdbc And Java 2nd Edition》这本书中,你将深入了解到JDBC的各个方面,包括最佳实践、高级特性以及如何在实际项目中高效使用JDBC。这本书可能会探讨如何优化JDBC代码,...

    在使用jdbc连接数据库(sqljdbc4)

    `sqljdbc4`是Microsoft SQL Server针对Java平台提供的一个驱动,使得Java开发者能够使用JDBC API来连接和操作SQL Server数据库。 **JDBC驱动类型** JDBC驱动主要有四种类型,`sqljdbc4`属于Type 4,即纯Java的非...

    jdbc使用参考手册

    ** JDBC使用参考手册详解 ** Java Database Connectivity (JDBC) 是Java编程语言中用于与数据库交互的一组标准API。这个英文版的JDBC使用参考手册是开发者的重要资源,提供了全面的指南来帮助理解和掌握JDBC的各个...

    sqljdbc和sqljdbc4 sqlserver最新驱动

    SQLJDBC和SQLJDBC4是Microsoft为Java...总之,SQLJDBC和SQLJDBC4是Java连接SQL Server数据库的重要工具,提供了稳定且高效的连接方式。正确选择和使用这些驱动,可以帮助Java开发者更好地管理和操作SQL Server数据库。

    Android使用JDBC+SSH连接外网数据库

    在Android开发中,有时我们需要实现从移动设备上访问位于外网的数据库,这通常涉及到使用Java Database Connectivity(JDBC)来实现数据交互,并通过Secure Shell(SSH)建立安全的网络通道。本文将深入探讨如何在...

    使用JDBC连接Oracle,MySql,SQLServer数据库

    本话题将深入讲解如何使用Java JDBC(Java Database Connectivity)API来连接Oracle、MySQL和SQL Server这三种常见关系型数据库。JDBC提供了一种标准的接口,使得Java开发者可以方便地与各种数据库系统进行通信。 ...

    使用Spring JDBC 案例

    在本文中,我们将深入探讨如何使用Spring JDBC进行数据库操作,并结合使用不同的连接池技术,包括Spring自带的、C3P0、DBCP和Druid。此外,我们还将介绍一个自定义的行映射器工具类,它在处理数据库查询结果时能提供...

    Matlab中使用JDBC访问SQL Server

    ### Matlab中使用JDBC访问SQL Server #### 概述 在科研、数据分析及工程领域,Matlab 是一种广泛使用的高级编程语言与交互式环境。它不仅支持数学计算、算法开发和数据可视化等功能,还能通过Java Database ...

    SpringJDBC.rar_jdbc spring_spring jd_spring jdbc_spring使用JDBC进行数

    学习这些内容有助于深入理解Spring JDBC的使用,从而更高效地进行数据库操作。 总之,Spring JDBC是Spring框架中强大的数据库访问工具,它通过提供一系列的模板类和事务管理机制,极大地简化了JDBC编程,提高了代码...

    java连接mysql使用jdbc的jar包

    Java连接MySQL数据库主要依赖于Java Database ...正确配置和使用JDBC驱动,能确保Java应用程序与MySQL数据库之间的高效、稳定通信。在选择jar包时,应根据项目的MySQL版本和稳定性需求来决定使用哪个版本的驱动。

    2022年在JSP中使用JDBC访问数据库.pptx

    "JSP中使用JDBC访问数据库" JSP(Java Server Pages)是一种动态网页技术,允许开发者在网页中嵌入Java代码,从而实现网页的动态化。在JSP中,经常需要访问数据库以获取或存储数据,而JDBC(Java Database ...

    Spring Data JDBC与JDBC的区别

    相比于直接使用JDBC,Spring Data JDBC提供了以下优势: 1. **自动配置**: Spring Boot通过自动配置,可以快速设置数据源和JDBC模板。 2. **Repository接口**: 开发者只需定义Repository接口,Spring会自动提供实现...

    sqljdbc41、sqljdbc42的官方jar包

    sqljdbc41.jar提供了诸如自动重连、性能优化和更好的Unicode支持等功能,确保了与SQL Server的高效稳定连接。 接着,sqljdbc42.jar则是为JRE 8准备的,它符合JDBC 4.1和4.2规范。这些规范是Java SE 8及更高版本的一...

    JDBCDriver3.0.rar_jdbc driver 3.0_sql jdbc 3.0_sql server jdbc_s

    在使用SQL Server JDBC时,开发者需要配置JDBC URL,它包含了数据库的地址、端口、实例名等信息,例如:"jdbc:sqlserver://localhost:1433;databaseName=myDatabase"。此外,还需要提供数据库用户名和密码来建立连接...

    sqljdbc42 jdbc for java

    在Java编程中,数据库操作是不可或缺的一部分,而SQLJDBC42则是Oracle公司提供的一款高效、可靠的Java数据库连接(JDBC)驱动程序,专为Java开发者设计,使得Java应用程序能够与SQL Server数据库进行无缝交互。...

    JDBC使用的简单示例

    **JDBC(Java Database Connectivity)**是Java编程语言中用于与数据库交互的一种接口,它允许Java应用程序连接到各种类型的数据库,实现数据的...通过理解并熟练运用JDBC,我们可以构建出高效且可靠的数据库应用程序。

    activeMQ使用JDBC所需要的jar包

    3. **连接池jar**:为了高效管理数据库连接,我们通常会使用数据库连接池。常见的连接池工具有Apache DBCP、C3P0和HikariCP等。对应的jar包如`commons-dbcp.jar`(Apache DBCP)或者`hikaricp.jar`(HikariCP)。 ...

    2022年在Servlet中使用JDBC访问数据库.pptx

    "Java Servlet 中使用 JDBC 访问数据库" Java Servlet 是一种服务器端的 Java 应用程序,用于处理 HTTP 请求和响应,而 JDBC(Java Database Connectivity)是 Java 语言中用来访问数据库的 API。现在,在 Servlet ...

    使用jdbc_oracle实现的分页功能

    在IT行业中,数据库操作是必不可少的一部分,特别是在Java开发中,JDBC(Java Database ...同时,确保在实际应用中,遵循最佳实践,如使用预编译语句、事务管理以及合理的错误处理,以确保代码的健壮性和高效性。

Global site tag (gtag.js) - Google Analytics