【问题标题】:Virtual attribute of ActiveJDBC modelActiveJDBC 模型的虚拟属性
【发布时间】:2021-09-23 14:34:36
【问题描述】:

我有一个名为Job 的ActiveJDBC 模型,并定义了一些静态属性,如titlesalaryworkplace 等。

public class Job extends Model {

  public String getTitle() {
    return getString("title");
  }

  public void setTitle(String title) {
    setString("title", title);
  }

  public Integer getSalary() {
    return getInteger("salary");
  }

  public void setSalary(Integer salary) {
    setInteger("salary", salary);
  } 

  public String getWorkplace() {
    return getString("workplace");
  }

  public void setWorkplace(String workplace) {
    setString("workplace", workplace);
  }  
}

现在我想通过下面的sql根据几何距离找工作:

String sql = "select *, ST_distance(...) as distance from jobs... order by distance asc";
LazyList<Job> jobs = Job.findBySql(sql);

如何从Job模型中读取虚拟属性distance

我尝试在jobs表中添加distance列,报错ERROR: ORDER BY "distance" is ambiguous

【问题讨论】:

  • 请提供您的型号的相关代码。另外,ERROR: ORDER BY "distance" is ambiguous 显然是 SQL 错误
  • @ipolevoy 我更新了模型。是的,这是 sql 错误,因为我添加了 distance 列以获取结果集中的距离值。我的问题是如何获得表中未定义的虚拟属性distance

标签: activejdbc javalite


【解决方案1】:

不确定您所说的“虚拟”属性是什么意思,但 ActiveJDBC 模型只是 Java 类,因此您可以向它们添加任何您想要的东西。 JavaLite 不会为您处理它们。您有责任添加适当的 setter 和 getter 并维护它们的状态,就像这是一个常规的 Java 类一样。

因此,您希望将其包装到模型中:

String sql = "select *, ST_distance(...) as distance from jobs... order by distance asc";
LazyList<Job> jobs = Base.findAll(sql);

你走在正确的道路上。请仔细阅读此方法的 JavaDoc:

http://javalite.github.io/2.4-j8/org/javalite/activejdbc/Model.html#findBySQL-java.lang.String-java.lang.Object...-

特别关注这部分:“确保查询返回与此模型关联的所有列,以便生成的模型可以正确地进行水合。”。

查询中的“*”负责第一部分,第二部分将被模型自动忽略,但将参与选择:“ 不属于此模型的返回列将被被忽略,但可用于上述子句。"

所以,你所要做的就是写一个这样的方法:


public class Job{

  public List<Map> getNearJobs(){

     String sql = "select *, ST_distance(. ? . ? .) as distance from jobs... order by distance asc";
     return Base.findAll(sql, getLogitude(), getLatitude());
  }

}

这样,您将构建一个查询,该查询将带来(并排序)正确的地图,并适当填充其属性。

因此,您将获得一份地图列表,而不是职位列表,但它会包含您需要的所有数据。您可以将此方法与一些代码杂技一起使用,从地图列表 (Model.fromMap()) 中创建新模型,并在每个模型中单独注入您的“距离”属性。但是,我个人反对这一点,因为模型不是模型,因为模型映射到表。

【讨论】:

  • 我的意思是“虚拟”属性是从其他属性计算出来的。在我的示例中,属性distance 是根据workplace 长/纬度坐标和home 坐标计算得出的。你是对的,我可以通过一些模型代码获得distance 属性值。换一种说法,postgresql提供了ST_distance函数,我想在执行sql时计算值,想从model中获取。
  • 将方法getNearJobs() 称为距离并将其视为您的“虚拟”属性。以上方法你试过了吗?
  • 我试过了。 getNearJobs 返回没有 distance 属性的作业列表,但我需要该值。
  • 正如我在上面的答案中提到的:“不属于此模型的返回列将被忽略,但可用于上述子句。”。这意味着,如果您需要将距离作为结果的一部分,则不能使用模型。我会更新答案。
  • 我根据这个更新了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多