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();
}
}
}