快速应用JDBC控件访问数据库资源
发表于:2007-07-04来源:作者:点击数:
标签:
JDBC控件是Beehive1.0中提供的访问JDBC数据源的 Java 控件。通过继承JDBC控件,我们根本无须关注访问数据库资源的通讯细节,只需要定义自己的业务方法,增加相应的注释来描述该继承子类,我们就可以非常轻松的实现企业应用中JDBC数据源的访问。 JDBC控件的所
JDBC控件是Beehive1.0中提供的访问JDBC数据源的
Java控件。通过继承JDBC控件,我们根本无须关注访问数据库资源的通讯细节,只需要定义自己的业务方法,增加相应的注释来描述该继承子类,我们就可以非常轻松的实现企业应用中JDBC数据源的访问。
JDBC控件的所有注释在org.apache.beehive.controls.system.jdbc.JdbcControl接口中定义,Beehive编译器在编译时将检查这些注释是否使用正确。
本节中首先将通过一个简单的例子来演示如何通过继承JDBC控件来访问JDBC数据源,完成一个数据表的增加、删除、修改、查询等业务逻辑,随后将介绍如何使用JDBC控件访问JDBC数据源的更多技巧。
本文中所有例子的源代码可以通过
下载资源区的链接下载。
本节中所有演示例子对应的JDBC数据源均为
MySQL数据库。
第一个JDBC控件的例子 接下来的这段例子将演示如何通过继承JDBC控件来完成JDBC数据源的访问,实现JDBC数据源中一个数据表中记录增加、删除、修改和查询的业务逻辑。
在演示例子中,为了保证演示的简洁,我们使用JDBC直接连接到数据库,而没有使用通常访问数据库所采用的DataSource技术。
建立数据表 在本地MySQL数据库的Demo数据库实例中按照如下DDL建立相应的数据表。
clearcase/" target="_blank" >cccccc width="90%" align=center bgColor=#e7e9e9 border=1>
create table demo( id int(5) primary key auto_increment, name varchar(20) not null default '', value varchar(20) not null default '' ); |
建立表征Demo对象的JavaBean 创建新的应用目录,然后创建表征Demo对象的JavaBean
清单1 src\org\vivianj\beehive\controls\examples\controls\beans\
Demo.
java
1. package org.vivianj.beehive.controls.examples.beans; 2. 3. 4. /** 5. * Demo 用于表征Beehive JDBC控件例子中的Demo对象 6. */ 7. public class Demo implements java.io.Serializable{ 8. private int id; 9. 10. private String name; 11. 12. private String value; 13. 14. public int getId() { 15. return id; 16. } 17. 18. public void setId(int id) { 19. this.id = id; 20. } 21. 22. public String getName() { 23. return name; 24. } 25. 26. public void setName(String name) { 27. this.name = name; 28. } 29. 30. public String getValue() { 31. return value; 32. } 33. 34. public void setValue(String value) { 35. this.value = value; 36. } 37. 38. } |
继承JDBC控件,增加自己的业务方法
清单2 src\org\vivianj\beehive\controls\examples\controls\
DemoMySQLControl.java
1. package org.vivianj.beehive.controls.examples.controls; 2. 3. import org.apache.beehive.controls.api.bean.ControlExtension; 4. import org.apache.beehive.controls.system.jdbc.JdbcControl; 5. import org.vivianj.beehive.controls.examples.beans.Demo; 6. 7. /** 8. * DemoMySQLControl 用于封装访问MySQL数据库中的Demo数据 9. 表的所有业务逻辑 10. * 包括新增、删除、修改、根据id查找对应的记录、查找所有Demo 11. 数据表中的记录、根据条件查找所有数据表中的记录 12. * 数据库访问时根据参数从DriverManager中获取数据库连接 13. */ 14. 15. @ControlExtension 16. @JdbcControl.ConnectionDriver( 17. databaseDriverClass = "org.gjt.mm.mysql.Driver", 18. databaseURL = "jdbc:mysql://localhost/estore ", 19. userName = “root”, password = “root”) 20. public interface DemoMySQLControl extends JdbcControl { 21. /** 22. * 向数据表demo中增加新的记录 23. * 24. * @param demo 25. * 新增加的Demo对象 26. */ 27. @SQL(statement = "insert into demo(name,value) 28. values({demo.name},{demo.value})") 29. public void createDemo(Demo demo); 30. 31. /** 32. * 修改数据表demo中demo.id对应记录的name和value信息 33. * 34. * @param demo 35. * 被修改的Demo对象 36. */ 37. @SQL(statement = "update demo set name={demo.name}, 38. value={demo.value} where id={demo.id}") 39. public void updateDemo(Demo demo); 40. 41. /** 42. * 删除数据表demo中demoId对应的记录 43. * 44. * @param demoId 45. * 被删除的Demo对象的id属性 46. */ 47. @SQL(statement = "delete from demo where id={demoId}") 48. public void deleteDemo(int demoId); 49. 50. /** 51. * 根据demoId查找Demo数据库中对应的记录,返回对应的 52. Demo对象 53. * 54. * @param demoId 55. * 查找Demo对象的id属性 56. * @return id属性为demoId的记录 57. */ 58. @SQL(statement = "select id,name,value from demo 59. where id={demoId}") 60. public Demo getDemoById(int demoId); 61. 62. /** 63. * 返回Demo数据表中所有记录集合 64. * 65. * @return Demo数据表中所有记录集合 66. */ 67. @SQL(statement = "select id,name,value from demo") 68. public Demo[] getDemos(); 69. 70. /** 71. * 72. * @param name 73. * @return 74. */ 75. @SQL(statement = "select id,name,value from demo 76. where name like {sql: name}") 77. public Demo[] getDemosFilterByName(String name); 78. } |
控件调用 我们可以编写DemoMySQLControl控件的测试类,然后通过如下方式来完成控件中业务方法的调用。
在测试类中采用声明式控件实例化方式来实例化DemoMySQLControl控件。
·@Control
DemoMySQLControl _control;
调用控件的相关业务方法来实现业务逻辑。
下面的代码段可以完成Demo对象的新增功能。
Demo demo = new Demo(); demo.setName(“name”); demo.setValue(“value”); _control.createDemo(demo); |
实例分析 从上面的例子中我们可以看到,通过继承JDBC控件来完成JDBC数据源的访问是一件非常简单的事情,
开发者需要完成的工作被简化为两项:编写表征访问对象的JavaBean和使用声明完成业务方法和逻辑的实现,这样的开发过程大大的简化了开发者的工作,极大地减少了开发者的代码编写量。
下面我们详细的分析一下继承JDBC控件的子类DemoMySQLControl:
在程序的第15行,我们使用@ControlExtension来注释将要创建的这个接口继承了另外的控件接口
16.@JdbcControl.ConnectionDriver( 17.databaseDriverClass = “org.gjt.mm.mysql.Driver”, 18.databaseURL = "jdbc:mysql://localhost/estore ", 19.userName = “root”, password = “king”) |
在程序的第16~19行我们使用@JdbcControl.ConnectionDriver注释来为将要创建的接口指定一些需要传递的参数,这里主要是一些数据库访问时所需要的JDBC驱动类、JDBC访问URL、数据库访问用户名和密码等必要信息。
20.public interface DemoMySQLControl extends JdbcControl { 在程序的第20行使用extends关键字表示将要创建的接口DemoMySQLControl和JdbcControl接口之间的继承关系 27.@SQL(statement = "insert into demo(name,value) 28.values({demo.name},{demo.value})") |
在程序的第27~28行使用@SQL关键字注释接下来定义的这个业务方法所需要执行的业务逻辑,其中的{}表示对传入参数的调用,{}包含的内容表示了需要处理的参数,这些参数的表示方法遵循
面向对象的属性调用方式,JDBC控件的解析器会将这些代码转化为对应的getter方法调用。
29.public void createDemo(Demo demo); |
在程序的第29行,采用常用的接口方法声明了该控件的一个访问接口。
后面的代码采用和27~29行相应的原理定义了其它需要实现的业务方法。需要注意的是,定义查询类方法时,如果只需要返回一条记录,目前通常的做法是返回一个Demo对象。如果返回的记录有超过一条的可能性,返回的是符合查询条件的Demo对象数组、List对象等,请参考《JDBC控件返回类型》部分的内容。
前面的内容中,我们已经通过继承JDBC控件完成了访问数据库资源的全部内容,现在你可以编写
单元测试代码来测试控件是否符合要求了。请大家参考《控件入门》中的步骤完成JDBC控件的编译和单元测试工作。
到现在为止,我们已经知道了如何使用JDBC控件和注释来访问数据库资源的基本步骤和方法,但是还没有学习如何使用注释来让JDBC控件和业务内容的结合起来。这部分的内容分作两部分进行介绍:一是如何通过注释定制JDBC控件,提供访问数据库的信息(比如数据库访问方式、URL、用户名和密码等),一是如何确定每次业务方法执行的返回对象。
使用注释订制JDBC控件 本节中的内容将给大家介绍如何使用JDBC控件提供的注释根据不同的环境和要求来订制JDBC控件,完成JDBC数据源的访问和业务逻辑的封装。
JDBC控件支持的四个注释:ConnectionDataSource、ConnectionDriver、ConnectionOptions、SQL。四个注释中ConnectionDataSource、ConnectionDriver、ConnectionOptions是用于类级别的注释,用于描述JDBC控件继承类,SQL注释是方法级别的注释,用于描述JDBC继承类中的业务方法。
使用ConnectionDataSource注释可以指定JDBC控件访问数据库时根据采用DataSource方式获取数据库连接。使用ConnectionDriver注释可以指定JDBC控件访问数据库时使用指定的参数通过DriverManager获取数据库连接。ConnectionOptions注释描述了数据库访问时的一些扩展特性,比如数据库访问时是否使用READONLY优化(仍然可以进行UPDATE操作)等。
下面开始详细的介绍这些注释,并且通过提供简单的代码段来说明如何使用这些注释来配置JDBC控件的继承类。
ConnectionDriver注释 ConnectionDriver用于注释JDBC控件的继承类,控制JDBC控件在访问数据库的时候通过DriverManager获取数据库连接。ConnectionDriver注释支持5个参数:databaseDriverClass、databaseURL、userName、password、properties。
·databaseDriverClass
String类型,用于设定数据库驱动类的全名。使用ConnectionDriver注释时必须设置的参数。
比如访问MySQL数据库,可以使用databaseDriverClass= “org.gjt.mm.mysql.Driver”,访问Oracle数据库的时候可以使用databaseDriverClass= “
oracle.jdbc.driver.OracleDriver”
·databaseURL
String类型,用于设定数据库访问的JDBC URL,使用ConnectionDriver注释时必须设置的参数。
比如访问MySQL可以使用databaseURL=“ jdbc:mysql://localhost/estore”,访问Oracle数据库时可以使用databaseURL=“ jdbc:oracle:thin:@localhost:1521:www”
·userName
String类型,设置访问数据库时使用的用户名,可选参数。
·password
String类型,设置访问数据库时使用的密码,可选参数。
·properties
String类型,设置访问数据库时的一些其它参数,可以一次性传递多个参数,两个参数之间用逗号隔开。
在《第一个JDBC控件的例子》中,我们提供的代码已经演示了如何使用ConnectionDriver注释JDBC控件,请参见 清单2 。
ConnectionDriver注释的JDBC控件运行时,必须保证databaseDriverClass中指定的数据库驱动类位于classpath中,否则控件运行时将抛出违例。
ConnectionDataSource注释 ConnectionDataSource注释用于指定JDBC控件在访问数据库时通过DataSource获取数据库连接,它有两个属性:jndiName和jndiContextFactory。
·jndiName
String类型,用于设置DataSource在目标容器内的jndiName属性
·jndiContextFactory
Class类型,用于设置数据库访问时可以获取jndi上下文环境的类,被传入的参数类必须继承org.apache.beehive.controls.system.jdbc.JdbcControl. JndiContextFactory类,并且覆盖JndiContextFactory类的getContext()方法,getContext()将获取访问目标容器的上下文环境(Context)。
下面的章节中我们将看到如何通过JDBC控件和ConnectionDataSource注释访问
Tomcat服务器,获取jndiName为jndi/samplesDataSource的DataSource资源,该DataSource连接到MySQL数据库的Demo实例,Web应用部署在Tomcat环境中。
修改Tomct配置文件,创建DataSource资源 ·如何创建Tomcat环境下的DataSource资源请参考Tomcat的帮助文档。
修改Web应用的配置文件web.xml,增加如下内容,增加对资源的引用
Datasource example jndi/samplesDataSource javax.sql.DataSource Container |
·创建访问Tomcat服务器Jndi上下文的类JndiContextFactory
JndiContextFactory类继承自JdbcControl.JndiContextFactory父类,覆盖父类中的抽象方法----getContext(),清单3 中显示了JndiContextFactory类定义和实现的完整代码。
清单3 src\ org\vivianj\beehive\controls\examples\controls\
jndicontext\JndiContextFactory.java
1. package org.vivianj.beehive.controls.examples.controls.jndicontext; 2. 3. import java.util.Hashtable; 4. 5. import javax.naming.Context; 6. import javax.naming.InitialContext; 7. 8. import org.apache.beehive.controls.system.jdbc.JdbcControl; 9. 10. /** 11. * JndiContextFactory 用于从Tomcat服务器中获取访问JNDI内容的上下文环境 12. */ 13. public class JndiContextFactory extends JdbcControl.JndiContextFactory { 14. /** 15. * 获得本地Tomcat服务器中访问JNDI内容的上下文环境 16. * 17. */ 18. public Context getContext() { 19. 20. Context ctx = null; 21. 22. try { 23. ctx = (Context)(new InitialContext().lookup("java:/comp/env")); 24. } catch (Exception e) { 25. 26. } 27. 28. return ctx; 29. } 30. } |
我们可以使用ConnectionDataSource注释和新创建的JndiContextFactory类来注释JDBC控件了。
下面的代码片断就是一个简单的例子,使用这段代码注释的JDBC控件,调用任何业务方法时,将通过本地Tomcat服务器上、JNDI名为“jndi/ samplesDataSource”的DataSource资源获取数据库连接。
@JdbcControl.ConnectionDataSource( jndiName = "jndi/samplesDataSource", jndiContextFactory=JndiContextFactory.class) |
ConnectionOptions注释 ConnectionOptions可以用于定义访问数据库时的一些扩展特性,可以选择性的和ConnectionDataSource或者ConnectionDriver一起使用。ConnectionOptions支持三个参数:readOnly、resultSetHoldability、typeMappers。
·readOnly
boolean类型,如果设置为true,数据库连接将优化为ReadOnly的访问方式,但是仍然可以进行更新和删除操作。默认为false。
·resultSetHoldability
org.apache.beehive.controls.system.jdbc.JdbcControl.HoldabilityType类型,可以选择为HOLD_CURSORS_OVER_COM
MIT或者CLOSE_CURSORS_AT_COMMIT,用于设置ResultSet指针的关闭策略,默认值是CLOSE_CURSORS_AT_COMMIT,表示在每次commit之后关闭ResulSet对象指针。
·typeMappers
org.apache.beehive.controls.system.jdbc.JdbcControl.TypeMapper数组类型。设置SQL自定义类型和Java类型之间的映射。TypeMappers类中指定的Java类型必须实现java.sql.SQLData接口