【问题标题】:AnyLogic: Correct way to select a dataset from internal databaseAnyLogic:从内部数据库中选择数据集的正确方法
【发布时间】:2019-11-11 02:54:19
【问题描述】:

在我的 anylogic 项目中,我从内部数据库中查询数据集。我要查询的表结构如下:

Name: product_innovation_level
--------------------------------
ID|level_customer|level_employee|
--|--------------|--------------|
 1|            10|            14|

我能找到的唯一示例使用元组类,如下所示。它可以工作,但感觉很笨拙,我必须从项目中手动提取所需的值。

Tuple innovationLevel = selectFrom(product_innovation_level).
                        where(product_innovation_level.id.eq(1)).
                        firstResult(product_innovation_level.level_customer, product_innovation_level.level_employee);

double ngEmployee = innovationLevel.get(product_innovation_level.level_employee);
double ngCustomer = innovationLevel.get(product_innovation_level.level_customer);

有没有更好的方法将值直接选择到模型类中?我正在寻找这样的东西:

xxx innovationLevel = selectFrom(product_innovation_level).
                                  where(product_innovation_level.id.eq(1)).
                                  firstResult(xxx);

我应该为 xxx 使用什么类?我找到了一个自动创建的类 Qproduct_innovation_level,但我没有找到访问该数据集值的方法。

Qproduct_innovation_level innovationLevel = selectFrom(product_innovation_level).
                                  where(product_innovation_level.id.eq(1)).
                                  firstResult(product_innovation_level);
int i  = innovationLevel.level_customer.intValue();
Error: Type mismatch: cannot convert from NumberExpression<Integer> to int

我尝试自己编写模型类,但出现类型不匹配错误(无法从 Qproduct_innovation_level 转换为 InnovationLevelModel)。

【问题讨论】:

  • 您的第二个代码 sn-p 这正是您直接执行此操作的方式(如果您知道您的查询仅返回 1 个值)。有什么问题?
  • 嗨本杰明。我扩展了我的问题,我不知道分别使用什么类来访问所需的值。

标签: database class anylogic


【解决方案1】:

好吧,我的回答可能有点荒谬,但也许这就是你想要的……

使用以下构造函数和变量创建一个类:

public class MyClass implements Serializable {

    public double ngEmployee;
    public double ngCustomer;
    /**
     * Default constructor
     */
    public MyClass(Tuple innovationLevel) {
        this.ngEmployee = innovationLevel.get(product_innovation_level.level_employee);
        this.ngCustomer = innovationLevel.get(product_innovation_level.level_customer);
    }

}

然后您可以像这样创建该类的实例:

MyClass mc=new MyClass(selectFrom(product_innovation_level).
                        where(product_innovation_level.id.eq(1)).
                        firstResult(product_innovation_level.level_customer, product_innovation_level.level_employee));

魔术...现在您可以使用mc.ngEmployeemc.ngCustomer 访问变量

【讨论】:

  • 这会将对话从 Tuple 集中到我的 MyClass,但如果我想对所有表执行此操作,则需要大量手动工作。我希望会有一些自动生成的方法。
  • 那么你别无选择,只能使用你已经在使用的东西
【解决方案2】:

您可以在这里使用 AnyLogic 从数据库表中以可视方式自动创建代理群体(包括代理类型定义)。

使用Agent 向导(从代理面板顶部):通过使用数据库表创建新类型的群体,AnyLogic 将

  • 使用与表中的列匹配的参数创建新的代理类型
  • 创建此代理类型的群体,每行一个实例(其他变体也是可能的),将列映射到适当的代理参数

因此,在您的情况下,您可以拥有代理类型 InnovationLevel 的人口 innovationLevels,其中该代理具有参数

  • id(输入int
  • levelCustomer(输入int
  • levelEmployee(输入int

(并且向导会自动定义此代理类型及其在数据库表驱动的群体中的使用)。

请参阅帮助中的 AnyLogic 帮助 > 基于代理的建模 > 基于 DB 数据创建新的代理群体

如果您的 ID 是连续的(例如,1、2、3、...),您还可以通过列表中的位置访问给定的创新级别(例如,innovationLevels(1) 表示列表中的第二个可能是 id 2)。如果您希望能够通过 ID“随机访问”创新级别(如果 ID 不是连续的),您还可以创建一个 ID 到 InnovationLevel 的映射(使用集合)。

其他代理可以根据需要包含对 InnovationLevel 实例的引用。

【讨论】:

  • 在我的模拟中,我按照您的描述从数据库中创建了我的主要代理。此外,我将一些计算封装在单独的类中,在这里我想从数据库中选择特定的数据。在我看来,为这些数据单独设置代理有点矫枉过正。
  • 与更简单的类相比,创建代理并没有太多开销,并且由于这看起来像经典的“查找数据”,因此在模型初始化时将其加载到数据结构中是正常的(所以以最小化查询并将所有输入数据处理/验证隔离到模型初始化中)。您也可以只创建一个类,然后编写几行代码来查询表并遍历所有行以使用这些类创建所需的查找数据结构。
  • 根据定义,关系数据库数据和对象之间存在分歧(这就是存在像 Hibernate 这样的 OR-mapping 框架的原因)。 OR 映射工具您通常用来执行从关系表数据到对象的“自动”映射的工具,而 AnyLogic 中的 QueryDSL 东西并没有这样做/试图这样做。
  • ...代理群体的自动创建 AnyLogic 原生地朝着这个 OR 映射方向发展的一种方式。
猜你喜欢
  • 1970-01-01
  • 2019-11-07
  • 1970-01-01
  • 2013-08-07
  • 2021-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多