http://www.35java.com/zhibo/forum.php?mod=viewthread&tid=261&extra=page%3D2
4.利用Singleton模式来控制连接池对象的惟一性 我们已经有了管理数据库连接的连接池类ConnectionPool,但要注意一点:连接池对象在系统运行时应该是惟一的。原因很简单,如果不惟一的话,对不同的数据库访问产生不同的连接池对象,那么连接池对象的作用就根本没有起。当然,也可以在程序中只创建一个连接池对象,但这不能保证别的程序员也能做到这一点,这时,应该采用singleton模式,通过getInstance()方法获取惟一的连接池对象。 public class ConnectionPool…… public class ConnectionPool { private static ConnectionPool instance = null; public static synchronized ConnectionPool getInstance() { if (instance==null) instance=new ConnectionPool (); return instance; } private ConnectionPool () { …… } } 到这里,要产生数据库连接的任务已经完成了。 5.利用Template Method模式来提取操作框架 对数据库的操作可以分为两类:对于第一类操作,会产生一定的结果集,如查询数据库;另一类操作,则只是对原有的数据库的变更,不会产生结果集,比如插入操作、更新操作。对于这两种情况,我们可以分别封装成相应的类。但我们发现,这两个类在操作时有很多的相同点。基本流程都是先获取数据库连接,然后生成Statement对象,再在这个Statement对象上调用方法执行SQL语句,这些步骤可以提取成一个方法execute()到一个父类里面,可称为DbBean类。这个父类只用公布出一个方法让子类去重载,这种方法往往被称为勾子方法,在这里不妨称为executeSql()。有了这个父类,对于两种不同的操作类型,会产生两个子类,不妨称为SelectBean与UpdateBean。对于不同的子类,只是重载父类中的勾子方法executeSql(),执行不同的数据库访问,不用去关心准备这个访问所要做的事。 6.引入Adapter模式来解决已有接口的不一致 在JDBC提供的接口里面,对数据库访问的方法分别为executeQuery()与executeUpdate(),在以上引入Template Method模式后,得在子类中去重载父类中公布出来的勾子方法executeSql(),这个勾子方法的名字是惟一的,这样,为了让我们的特定数据库访问能很好地衔接上去,我们可以引入Adapter模式,把这两个不同的方法适配成executeSql()。注意,因为executeQuery()方法有一个返回值,我们有必要在包含它的子类里面加上一个ResultSet类的成员变量rs。这样,在executeSql()方法里面,只要把executeQuery()的返回值赋给rs就可以了。 7.引入Facade模式使操作接口更接近业务逻辑 在对数据库查询时,使用JDBC已经提供的接口executeQuery()时,返回给我们的是一个ResultSet对象,里面依次存放着要查询的每一列。程序员如果要获取所需的信息,往往得通过调用返回对象的getObject(int i)方法。这样做,一方面,很不直观,另一方面,代码的耦合性很高。对此,我们想到了引入Adaptor模式,这样可使我们的接口更进一步脱离数据库操作,从而可更关注业务逻辑。 假设现在有一个学生信息表T_Student,里面的信息为ID,Name,Age,其基本表结构如下: 对于这个表的查询,我们的目的就是能用getId(),getName(),getAge()这样的方法来获取数据。基于这样的目的,现在要做的就是把查询所得到的数据如何正确地定位到我们方法的返回值。对于数据库查询,我们发现,在查询语句中要查询的记录的序号与返回结果中的序号是一一对应的,利用这一点,可以把要查询的字段名放在一个Vector里面,如上面Vector中的内容可以是(“Id”,“Name”,“Age”),我们要执行的SQL语句很容易通过这些字段名来拼接,其执行结果是按给出的顺序放在ResultSet对象里面的。最后,对于特定的函数调用,如getId(),可以通过Java提供的Reflection机制获取函数名,然后去掉前面的get字符,再在字段名Vector里用indexOf(Object o)方法获取字段名所对应的序号index,这也是其查询结果ResultSet里的序号,通过它可以从查询结果ResultSet里面通过getObject(index)得到我们要的结果。我们可以把这些不变的代码提取到父类SelectBean中,这样做的好处是以后对于不同的表结构可以生成相应的子类。我们只用定义一个Vector变量,放上我们要查询的字段名字符串,并定义相应的get函数。当我们调用它们时,只需调用以上父类的公共匹配代码,即可获得正确的数据。以下是针对以上表结构引入Facade模式后的效果图与代码片断: …… String name,id,age; StudentSelect student = new StudentSelect(); student.execute(); name =student.getName(); id =student.getId(); age= student.getAge() …… 对于对数据库更新的SQL语句,也可利用以上的机制,做法是类似的,在此不再赘述。 本文提供了在Java数据库编程中引入设计模式的一个思路。在实际中,我们基于以上的设计思路实现了一个框架,基于这个框架,编写Java数据软件的效率大大提高。当然,本文提供了一个整体的设计思路,在实际中,可以根据特定的情况,修改其中的一些模块,比如,数据库的连接可以从J2EE中的数据源获取。对此,读者可以自行取舍。 |