如何从数据库中提取的数据进行通用构造

时间:2017-04-01 12:05:41

标签: java oop polymorphism

我有一个包含多个表的数据库以及表数据的相应对象。对于(几乎)所有表,我有一个Model类,它处理与其对应表的交互(添加记录,获取数据并实例化一个包含数据的对象。

所有Model类都有getById(int id)方法,所以我认为把它放在超类(CoreModel)中会很好。

但是这里的事情: 由于Model类只是一种交互层,我认为在创建它的实例时没有用处。所以我认为我使类最终并且它的方法是静态的,但随后出现的问题是无法从静态方法调用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;
    }
}

2 个答案:

答案 0 :(得分:2)

  

由于Model类只是一种交互层,我明白了   没有用于创建它的实例。所以我以为我上课了   final和它的方法是静态的,但问题就出现了   无法从静态方法调用super()方法。

首先,您的CoreModelfinal类,并且您无法扩展final中的PersonModel类,并且您的代码将无法编译。

此外,CoreModel重命名为CoreDAO& PersonModelPersonDAO (实际上是数据访问对象),因为它们包含访问数据库表/连接/等的逻辑。 (称为DAO图层,对此图案看here)。

通常,Model对象(如PersonProduct等等是带有getter / setter的普通数据类),它们不是单例,而是DAO对象(如PersonDAO,{ {1}}等等。)是单身人士。

DAO图层类需要是singleton(整个应用程序的单线程安全实例),它只保存行为(即包含从数据库获取/存储数据的逻辑)。

  

是否有任何设计模式或标准解决方案可以解决这个问题   通用方式的问题?

为了避免样板代码从数据库加载对象(如CoreDAO等),你可以实际使用 ORM(对象关系映射)框架(实现 JPA ),例如Hibernatespring-data-jpa等。即,  这些框架将为您提供从持久存储加载/保存对象的API,而不用我们直接处理大量PersonPreparedStatement对象

我建议你不需要重新编写/重写这个样板逻辑,而是直接使用JPA API。这里还有一点是,如果您使用JPA,那么您不会被锁定到单个ORM供应商,而是可以在供应商之间切换。

答案 1 :(得分:1)

你所问的是ORM。有几种用于创建ORM的设计模式,您可以阅读有关DataMapper或ActiveRecord的信息,以便更好地理解这个概念。

根据你的代码只获取一个Id并生成一个对象是不够的。你需要有一个可区分的Id,所以超类可以与不同的对象不同。

创建用于创建不同对象的超类的一种方法是工厂设计模式。

类似于以下代码:

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