Java 如何从数据库中获取的数据一般地构造对象
我有一个数据库,其中包含多个表和对应于表数据的对象。对于(几乎)所有的表,我都有一个模型类,它处理与相应表的交互(添加记录、获取数据和实例化保存数据的对象) 所有模型类都有一个Java 如何从数据库中获取的数据一般地构造对象,java,oop,polymorphism,Java,Oop,Polymorphism,我有一个数据库,其中包含多个表和对应于表数据的对象。对于(几乎)所有的表,我都有一个模型类,它处理与相应表的交互(添加记录、获取数据和实例化保存数据的对象) 所有模型类都有一个getById(intid)方法,所以我认为最好将它放在一个超类(CoreModel)中 但问题是: 由于模型类只是一种交互层,我认为创建它的实例是没有用的。所以我认为我将类设置为final,并且它的方法是静态的,但是问题是,super()方法不能从静态方法调用 我的问题:这通常是怎么做到的?我对OOP有点陌生,对整个多态
getById(intid)
方法,所以我认为最好将它放在一个超类(CoreModel)中
但问题是:
由于模型类只是一种交互层,我认为创建它的实例是没有用的。所以我认为我将类设置为final,并且它的方法是静态的,但是问题是,super()方法不能从静态方法调用
我的问题:这通常是怎么做到的?我对OOP有点陌生,对整个多态性问题感到困惑。有没有设计模式或标准解决方案可以用通用的方式解决这个问题
示例代码:
public final class CoreModel {
public static ResultSet getById(int id, String table){
Statement stat = null;
ResultSet res = null;
try {
stat = DatabaseModel.getStatement();
res = stat.executeQuery("SELECT * FROM `"+table+"` WHERE `id` = " +id);
res.next();
stat.close();
res.close();
} catch (SQLException ex) {
// handle any errors
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
return res;
}
}
public final class PersonModel extends CoreModel {
public static Person getById(int id) {
ResultSet personResult = super.getById(id, "person");
// instatiate Person object
return personObj;
}
}
因为模型类只是一种交互层,我明白了
创建一个实例是没有用的,所以我想我创建了这个类
final和它的方法是静态的,但问题是
无法从静态方法调用super()方法
首先,你的CoreModel
是final
类,你不能扩展你在PersonModel
中所做的final
类,你的代码将无法编译
另外,最好将CoreModel
重命名为CoreDAO
,PersonModel
为PersonDAO
(实际上是数据访问对象),因为它们包含访问数据库表/连接等的逻辑(称为DAO层,寻找此模式)
通常,模型对象(如Person
、Product
等)是带有getter/setter的普通数据类,它们不是单例,而DAO对象(如PersonDAO
、CoreDAO
等)是单例
DAO层类需要是(整个应用程序的单线程安全实例),只包含行为(即,包含从数据库获取/存储数据的逻辑)
是否有任何设计模式或标准解决方案来解决此问题
以一般方式解决问题
为了避免样板代码从数据库加载对象(如Person
等),您实际上可以使用ORM(对象关系映射)框架(实现JPA)等。,
这些框架将为您提供API,以便将对象从/保存到持久存储,而无需直接处理大量的PreparedStatement
和ResultSet
对象
我建议您不需要重新设计/重写这个样板逻辑,而是直接使用JPA API。这里还有一点是,如果您使用JPA,那么您就不会被锁定在单一的ORM供应商中,而是可以在供应商之间进行切换。您需要的是ORM。crea有两种设计模式对于ORM,您可以阅读有关DataMapper或ActiveRecord的内容,以便更好地理解这个概念 根据您的代码,仅获取Id并生成对象是不够的。您需要有一个可区分的Id,以便超类可以与不同的对象不同 创建用于创建不同对象的超类的一种方法是Factory design模式 类似于以下代码的内容:
//Character Class
public class Character implements Model {
public String age;
}
//Person Class
public class Person implements Model {
public String name;
}
//Model
public interface Model {
}
//CoreModel
public class CoreModel {
public static <T extends Model> T getById( int id) throws Exception {
int idType = id % 10; // the id has to be distinguishable
// get data from DB
switch (idType) {
case 0:
Person person = new Person();
person.name = "test";
return (T) Person.class.cast(person);
case 1:
Character character = new Character();
character.age = "100";
return (T) Character.class.cast(character);
default:
throw new Exception("Type Not Found");
}
}
}
//Main Class
public class Main {
public static void main(String[] args) {
try {
Person p = CoreModel.getById(100);
Character c = CoreModel.getById(101);
System.out.println(p.name);
System.out.println(c.age);
} catch (Exception e) {
e.printStackTrace();
}
}
}
//字符类
公共类字符实现模型{
公共字符串年龄;
}
//人类
公共类Person实现模型{
公共字符串名称;
}
//模型
公共接口模型{
}
//核心模型
公共类核心模型{
公共静态T getById(int id)引发异常{
int idType=id%10;//该id必须是可区分的
//从数据库获取数据
开关(idType){
案例0:
Person=新人();
person.name=“测试”;
返回(T)人.类别.演员(人);
案例1:
字符=新字符();
character.age=“100”;
return(T)Character.class.cast(Character);
违约:
抛出新异常(“未找到类型”);
}
}
}
//主类
公共班机{
公共静态void main(字符串[]args){
试一试{
Person p=CoreModel.getById(100);
字符c=CoreModel.getById(101);
System.out.println(p.name);
系统输出打印项次(c.age);
}捕获(例外e){
e、 printStackTrace();
}
}
}