在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.
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.
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.
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。
相关推荐
WebLogic和JDBC是企业级应用开发中的两个关键组件,它们在构建分布式、数据库驱动的...在实际开发中,应根据项目需求合理配置WebLogic的JDBC设置,优化数据源,以及高效使用JDBC API,以实现高效、稳定的企业级应用。
在《OReilly - Database Programming With Jdbc And Java 2nd Edition》这本书中,你将深入了解到JDBC的各个方面,包括最佳实践、高级特性以及如何在实际项目中高效使用JDBC。这本书可能会探讨如何优化JDBC代码,...
`sqljdbc4`是Microsoft SQL Server针对Java平台提供的一个驱动,使得Java开发者能够使用JDBC API来连接和操作SQL Server数据库。 **JDBC驱动类型** JDBC驱动主要有四种类型,`sqljdbc4`属于Type 4,即纯Java的非...
** JDBC使用参考手册详解 ** Java Database Connectivity (JDBC) 是Java编程语言中用于与数据库交互的一组标准API。这个英文版的JDBC使用参考手册是开发者的重要资源,提供了全面的指南来帮助理解和掌握JDBC的各个...
SQLJDBC和SQLJDBC4是Microsoft为Java...总之,SQLJDBC和SQLJDBC4是Java连接SQL Server数据库的重要工具,提供了稳定且高效的连接方式。正确选择和使用这些驱动,可以帮助Java开发者更好地管理和操作SQL Server数据库。
在Android开发中,有时我们需要实现从移动设备上访问位于外网的数据库,这通常涉及到使用Java Database Connectivity(JDBC)来实现数据交互,并通过Secure Shell(SSH)建立安全的网络通道。本文将深入探讨如何在...
本话题将深入讲解如何使用Java JDBC(Java Database Connectivity)API来连接Oracle、MySQL和SQL Server这三种常见关系型数据库。JDBC提供了一种标准的接口,使得Java开发者可以方便地与各种数据库系统进行通信。 ...
在本文中,我们将深入探讨如何使用Spring JDBC进行数据库操作,并结合使用不同的连接池技术,包括Spring自带的、C3P0、DBCP和Druid。此外,我们还将介绍一个自定义的行映射器工具类,它在处理数据库查询结果时能提供...
### Matlab中使用JDBC访问SQL Server #### 概述 在科研、数据分析及工程领域,Matlab 是一种广泛使用的高级编程语言与交互式环境。它不仅支持数学计算、算法开发和数据可视化等功能,还能通过Java Database ...
学习这些内容有助于深入理解Spring JDBC的使用,从而更高效地进行数据库操作。 总之,Spring JDBC是Spring框架中强大的数据库访问工具,它通过提供一系列的模板类和事务管理机制,极大地简化了JDBC编程,提高了代码...
Java连接MySQL数据库主要依赖于Java Database ...正确配置和使用JDBC驱动,能确保Java应用程序与MySQL数据库之间的高效、稳定通信。在选择jar包时,应根据项目的MySQL版本和稳定性需求来决定使用哪个版本的驱动。
"JSP中使用JDBC访问数据库" JSP(Java Server Pages)是一种动态网页技术,允许开发者在网页中嵌入Java代码,从而实现网页的动态化。在JSP中,经常需要访问数据库以获取或存储数据,而JDBC(Java Database ...
相比于直接使用JDBC,Spring Data JDBC提供了以下优势: 1. **自动配置**: Spring Boot通过自动配置,可以快速设置数据源和JDBC模板。 2. **Repository接口**: 开发者只需定义Repository接口,Spring会自动提供实现...
sqljdbc41.jar提供了诸如自动重连、性能优化和更好的Unicode支持等功能,确保了与SQL Server的高效稳定连接。 接着,sqljdbc42.jar则是为JRE 8准备的,它符合JDBC 4.1和4.2规范。这些规范是Java SE 8及更高版本的一...
在使用SQL Server JDBC时,开发者需要配置JDBC URL,它包含了数据库的地址、端口、实例名等信息,例如:"jdbc:sqlserver://localhost:1433;databaseName=myDatabase"。此外,还需要提供数据库用户名和密码来建立连接...
在Java编程中,数据库操作是不可或缺的一部分,而SQLJDBC42则是Oracle公司提供的一款高效、可靠的Java数据库连接(JDBC)驱动程序,专为Java开发者设计,使得Java应用程序能够与SQL Server数据库进行无缝交互。...
**JDBC(Java Database Connectivity)**是Java编程语言中用于与数据库交互的一种接口,它允许Java应用程序连接到各种类型的数据库,实现数据的...通过理解并熟练运用JDBC,我们可以构建出高效且可靠的数据库应用程序。
3. **连接池jar**:为了高效管理数据库连接,我们通常会使用数据库连接池。常见的连接池工具有Apache DBCP、C3P0和HikariCP等。对应的jar包如`commons-dbcp.jar`(Apache DBCP)或者`hikaricp.jar`(HikariCP)。 ...
"Java Servlet 中使用 JDBC 访问数据库" Java Servlet 是一种服务器端的 Java 应用程序,用于处理 HTTP 请求和响应,而 JDBC(Java Database Connectivity)是 Java 语言中用来访问数据库的 API。现在,在 Servlet ...
在IT行业中,数据库操作是必不可少的一部分,特别是在Java开发中,JDBC(Java Database ...同时,确保在实际应用中,遵循最佳实践,如使用预编译语句、事务管理以及合理的错误处理,以确保代码的健壮性和高效性。