Java 设计模式以更快地从数据库加载数据
我有一个学生班。当我调用获取客户机的方法时,它返回一个新创建的Student对象。Student的构造函数通过调用getStudentData方法从数据库中获取所需的数据。但是,由于数据库的性质,getStudentData需要花费非常长的时间 我最初实现了一个工厂设计模式,但它并没有像我希望的那样工作。请注意,我必须使用getStudentData,并且无法更改数据库 学生班级如下:Java 设计模式以更快地从数据库加载数据,java,database,design-patterns,Java,Database,Design Patterns,我有一个学生班。当我调用获取客户机的方法时,它返回一个新创建的Student对象。Student的构造函数通过调用getStudentData方法从数据库中获取所需的数据。但是,由于数据库的性质,getStudentData需要花费非常长的时间 我最初实现了一个工厂设计模式,但它并没有像我希望的那样工作。请注意,我必须使用getStudentData,并且无法更改数据库 学生班级如下: public class StudentImplementation implements Student {
public class StudentImplementation implements Student {
private final int key;
private String givenName;
private String surname;
private String contactNumber;
private String email;
private String address;
public StudentImplementation(Login account_tokenizer, int key) {
this.key = key;
this.givenName = Table.getInstance().getStudentData(account_tokenizer, key, "givenName");
this.surname = Table.getInstance().getStudentData(account_tokenizer, key, "surname");
this.contactNumber = Table.getInstance().getStudentData(account_tokenizer, key, "contactNumber");
this.email = Table.getInstance().getStudentData(account_tokenizer, key, "email");
this.address = Table.getInstance().getStudentData(account_tokenizer, key, "address");
}
// The rest of the class is full of getters
}
首先,您可以将调用
Table.getInstance()
的结果保存在局部变量中–尽管在不知道此方法真正在做什么的情况下,它可能只会占用您几毫秒的时间
public StudentImplementation(Login account_tokenizer, int key) {
this.key = key;
var instance = Table.getInstance();
this.givenName = instance.getStudentData(account_tokenizer, key, "givenName");
this.surname = instance.getStudentData(account_tokenizer, key, "surname");
this.contactNumber = instance.getStudentData(account_tokenizer, key, "contactNumber");
this.email = instance.getStudentData(account_tokenizer, key, "email");
this.address = instance.getStudentData(account_tokenizer, key, "address");
}
通常,您不会单独登录每个属性的数据库。但由于这是你的API,你必须接受它……在这种情况下,糟糕的性能不是你的错
然而,在StudentImplementation
的构造函数中访问数据库是一个坏主意:如何创建尚未在数据库中的新学生
而且数据库访问往往会失败,因此您的构造函数也可能会失败,而且有一条经验法则(没有法律!)即构造函数不应该从其内部操作中抛出异常(这是无法始终避免的,但您应该尝试…)
因此,有一个接受属性的构造函数和一个从数据库收集数据然后调用构造函数的工厂方法将是更好的设计,尽管这不会解决性能问题。首先,您可以保留调用
Table.getInstance()的结果
在局部变量中–尽管在不知道此方法真正在做什么的情况下,它可能只会为您节省毫秒
public StudentImplementation(Login account_tokenizer, int key) {
this.key = key;
var instance = Table.getInstance();
this.givenName = instance.getStudentData(account_tokenizer, key, "givenName");
this.surname = instance.getStudentData(account_tokenizer, key, "surname");
this.contactNumber = instance.getStudentData(account_tokenizer, key, "contactNumber");
this.email = instance.getStudentData(account_tokenizer, key, "email");
this.address = instance.getStudentData(account_tokenizer, key, "address");
}
通常,您不会单独登录每个属性的数据库。但由于这是你的API,你必须接受它……在这种情况下,糟糕的性能不是你的错
然而,在StudentImplementation
的构造函数中访问数据库是一个坏主意:如何创建尚未在数据库中的新学生
而且数据库访问往往会失败,因此您的构造函数也可能会失败,而且有一条经验法则(没有法律!)即构造函数不应该从其内部操作中抛出异常(这是无法始终避免的,但您应该尝试…)
因此,有一个接受属性的构造函数和一个从数据库收集数据然后调用构造函数的工厂方法将是更好的设计,尽管这不会解决性能问题。如果不能在一个请求中获取所有数据,如果db连接失败,您可以尝试将其并行化支持它
public StudentImplementation(Login account_tokenizer, int key) {
this.key = key;
Table table = Table.getInstance();
CompletableFuture.allOf(
CompletableFuture.runAsync(() -> this.givenName = table.getStudentData(account_tokenizer, key, "givenName")),
CompletableFuture.runAsync(() -> this.surname = table.getStudentData(account_tokenizer, key, "surname")),
CompletableFuture.runAsync(() -> this.contactNumber = table.getStudentData(account_tokenizer, key, "contactNumber")),
CompletableFuture.runAsync(() -> this.email = table.getStudentData(account_tokenizer, key, "email")),
CompletableFuture.runAsync(() -> this.address = table.getStudentData(account_tokenizer, key, "address"))
).join();
}
如果您不能在一个请求中获取所有数据,那么如果db连接支持,您可以尝试将其并行化
public StudentImplementation(Login account_tokenizer, int key) {
this.key = key;
Table table = Table.getInstance();
CompletableFuture.allOf(
CompletableFuture.runAsync(() -> this.givenName = table.getStudentData(account_tokenizer, key, "givenName")),
CompletableFuture.runAsync(() -> this.surname = table.getStudentData(account_tokenizer, key, "surname")),
CompletableFuture.runAsync(() -> this.contactNumber = table.getStudentData(account_tokenizer, key, "contactNumber")),
CompletableFuture.runAsync(() -> this.email = table.getStudentData(account_tokenizer, key, "email")),
CompletableFuture.runAsync(() -> this.address = table.getStudentData(account_tokenizer, key, "address"))
).join();
}
鉴于提供的信息,您可能无能为力。问题似乎不是您的代码,而是对student的每个属性分别进行调用,而不是在一个调用中获取所有内容。但是如果你不能更改…@dpr是的,会对数据库中的每个属性分别调用,而不是一次调用所有属性,但不幸的是,我无法更改数据库,我也没有主意。根据提供的信息,你可能无能为力。问题似乎不是您的代码,而是对student的每个属性分别进行调用,而不是在一个调用中获取所有内容。但是,如果没有什么你可以改变…@dpr是的,对数据库中的每个属性分别调用,而不是一次调用所有属性,但不幸的是,我无法更改数据库,我没有主意。