通常我们在实际工作中,经常遇到需要访问数据库的场景。
而常见的数据库又多种多样,怎么样针对不同的数据库来建立不同的数据库连接呢?
我们可以看下用抽象工厂模式加上反射技术来如何实现。
首先我们定义基本类,假设数据库中有用户表和部门表,我们定义两张基本的javabean对象。
package designpattem.abstractfactory;
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package designpattem.abstractfactory;
public class Department {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
针对两个bean对象,我们定义对应的两个访问接口。
package designpattem.abstractfactory;
public interface IUser {
public void Insert(User user);
public User GetUser(int id);
}
package designpattem.abstractfactory;
public interface IDepartment {
public void Insert(Department department);
public Department GetDepartment(int id);
}
同样,我们以sqlserver和access两种不同的数据库来作为样例,来看下怎么访问User和Department
我们先定义sqlserver的访问user和department的方法
package designpattem.abstractfactory;
public class SqlserverUser implements IUser {
@Override
public void Insert(User user) {
System.out.println("在 SQL Server中给User表增加一条记录。");
}
@Override
public User GetUser(int id) {
System.out.println("在SQL Server中根据ID得到User表一条记录");
return null;
}
}
package designpattem.abstractfactory;
public class SqlserverDepartment implements IDepartment {
@Override
public void Insert(Department department) {
System.out.println("在 SQL Server中给Department表增加一条记录。");
}
@Override
public Department GetDepartment(int id) {
System.out.println("在SQL Server中根据ID得到Department表一条记录");
return null;
}
}
同理我们定义Access数据库对user和department的访问
package designpattem.abstractfactory;
public class AccessUser implements IUser {
@Override
public void Insert(User user) {
System.out.println("在 Access 中给User表增加一条记录。");
}
@Override
public User GetUser(int id) {
System.out.println("在Access 中根据ID得到Access表一条记录");
return null;
}
}
package designpattem.abstractfactory;
public class AccessDepartment implements IDepartment {
@Override
public void Insert(Department department) {
System.out.println("在 Access 中给Department表增加一条记录。");
}
@Override
public Department GetDepartment(int id) {
System.out.println("在Access 中根据ID得到Department表一条记录");
return null;
}
}
好了,前期准备工作都处理完了,我们看下利用反射技术怎么对去创建以及读取user和department数据。
package designpattem.abstractfactory;
public class DataAccess {
private static String AssemblyName="designpattem.abstractfactory";
private static String db="Sqlserver";
public static IUser CreateUser() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
String className=AssemblyName+"."+db+"User";
return (IUser)Class.forName(className).newInstance();
}
public static IDepartment CreateDepartment() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
String className=AssemblyName+"."+db+"Department";
return (IDepartment)Class.forName(className).newInstance();
}
}
看在具体业务逻辑中如何使用
package designpattem.abstractfactory;
public class AbstractFactoryTest {
public static void main(String[] args) throws Exception {
//抽象工厂模式
func1();
}
public static void func1() throws Exception{
User user = new User();
Department dept = new Department();
IUser iu = DataAccess.CreateUser();
iu.Insert(user);
iu.GetUser(1);
IDepartment id = DataAccess.CreateDepartment() ;
id.Insert(dept);
id.GetDepartment(1);
}
}
在 SQL Server中给User表增加一条记录。
在SQL Server中根据ID得到User表一条记录
在 SQL Server中给Department表增加一条记录。
在SQL Server中根据ID得到Department表一条记录
抽象工厂模式,提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们的具体类。
抽象工厂模式最大的好处便是易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,
这使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
第二个好处就是它让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操纵实例,
产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。