2017-04-01 48 views
1

我有一个数据库,其中包含多个表和相应的表格数据对象。对于(几乎)所有表,我有一个Model类,用于处理与相应表的交互(添加记录,获取数据并实例化一个包含数据的对象)如何从数据库中获取的数据通用构造对象

所有Model类都有一个getById(int id)方法,所以我认为它将它放在一个超类(CoreModel)中是很好的

但是这里的东西: 由于Model类只是一种交互层,所以我认为我没有用它来创建一个实例。使类最终,它的方法是静态的,但然后问题出现super()方法不能从静态方法调用。

我的问题:这通常如何完成?我对面向对象很陌生,并且对整个多态性事物感到困惑。是否有任何设计模式或标准解决方案以通用方式解决此问题?

示例代码:

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

回答

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

由于示范类只是一种相互作用的层,我看到 没有用在创造它的一个实例。所以我认为我使得类 final,它的方法是静态的,但是随后出现的问题是,不能从静态方法调用super()方法。

第一件事是,你CoreModelfinal类,你不能扩展你在你的PersonModelfinal类和您的代码将无法编译。

而且,将是很好的重命名CoreModel作为CoreDAO & PersonModelPersonDAO(这实际上是数据访问对象),因为它们包含的逻辑来访问数据库表/连接/等。 (这被称为DAO层,看起来这个模式为here)。

一般来说,模型对象(如PersonProduct等。与getter/setter方法明文数据类),它们是NOT单身而DAO对象(如PersonDAOCoreDAO,等等。)是单例。

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

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

为了避免样板代码加载对象(如Person,等)从数据库,你可以实际使用ORM(对象关系映射)构架(实施JPA的)像Hibernatespring-data-jpa等, 这些框架将为您提供API来加载/保存对象从/到持久存储没有我们直接处理很多PreparedStatementResultSet对象

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

相关问题