【问题标题】:How can I get data from a Table that does not have a Model?如何从没有模型的表中获取数据?
【发布时间】:2016-10-26 02:06:18
【问题描述】:

简介

我正在做一个项目,遇到了一个奇怪的用例,也许 ActiveJDBC 不适合,我保证耐心,因为这个项目中的许多事情都不是我能控制的:

我有 10 到 15 个小型/中型数据库(每个约 30 个表,最多 40000 条记录),其中大多数共享一个由 15 个表组成的“核心”架构,但同时它们有一些针对每个数据库唯一的特定表,它们都由我无权访问的遗留系统维护。

目标

我们(我和一些同事)需要将数据集中在一种“复杂的数据仓库”中。不幸的是,出于更高的原因,我不能使用除 ActiveJDBC 之外的任何技术以及需要我们编写的所有其他技术(我知道这可以使用 MongoDB 和/或 Liquibase 更好地处理)

我们已经处理了数据库之间的连接,并且项目本身在很大程度上进展顺利。处理所有数据库共享的核心模式的程序部分已经“工作”了,但是我们在处理它们的唯一表时遇到了问题。

我通过在运行时进行的查询(也不是我的选择)从数据库中获取所有表名。我们需要将类的数量保持在最低限度

最后是我的问题

我可以创建一个通用/动态模型或类似的东西,可以在运行时保存来自查询的数据吗?类似:

Model a = Base.findall("select * from ?", TableName)

Model a = Model.fromTable(Tablename)

我知道以这种方式使用模型很奇怪,但如果我们能以这种方式获取表数据,那将大大简化我们的生活。

我们将主要使用这种模型来从表中获取“原始”数据并满足接口,因此现在无需担心每个表的关系。

提前致谢

@Edit:感谢 Igor 提供了这个很棒的工具!

我们(几乎)做到了!谢谢你。我们对“核心架构”使用了类似的方法,但您给了我们一些启发。

正如我所评论的:

我们需要像使用模型一样使用 Base.findall() 的结果,这可能吗?

【问题讨论】:

    标签: java activejdbc


    【解决方案1】:

    您可以请客了。我从您对 ActiveJDBC 的引用中感觉到这不是您的选择,但您会对它的灵活性感到惊讶。让我先澄清两件事:MongoDB 不是关系数据库,而 Liquibase 是数据库迁移系统。 JavaLite 提供了一个更简单的DB-Migrator

    现在,回答的重点。正如您可能已经知道的那样,ActiveJDBC 实际上是一个非常强大的 Map。这意味着你可以这样做:

    Person p = new Person();
    p.fromMap(aMap); 
    

    看,Model#fromMap(Map) 方法从映射中读取属性,只要它们对应于该模型属性的名称,并用映射中的值覆盖其值。

    让我们写一些代码:

    例如,在第一个数据库中有一个名为 PEOPLE 的表,在“其他”数据库中有一个名为 USERS 的表:

    create table USERS( first_name VARCHAR(56));
    create table PEOPLE( firstname VARCHAR(56));
    

    如您所见,“名字”列存在于两个数据库/表中,但具有不同的名称

    所以,让我们编写代码从用户那里读取并保存到人:

    // define model 
    public class Person extends Model {}
    
    ...
    
    Base.open(...) // open default database
    DB otherDB = new DB("other_database"); 
    otherDB.open(...); // open other database
    
    // read users from "other" database
    List<Map> users = db.findAll("select first_name \"firstname\" from users");
    
    // save people into default database
    for(Map user: users){
       Person p = new Person(); 
       p.fromMap(user); 
       p.saveIt;
    }
    
    Base.close(); 
    otherDb.close();
    

    希望这能解决你的问题!

    【讨论】:

    • 另外一个小问题:我可以以某种方式将“where().limit().offset()”与 base.findall 一起使用吗?我知道我可以直接在查询中传递它们,但是我需要在得到结果后进行过滤
    • 最好在数据库中执行此操作,因为 findAll() 采用原始 SQL 查询:db.findAll("select first_name "first_name" from users order by first_name limit 10 offset 50")
    • @LouizFC,谢谢你的好话!对于您的另一个问题:“我们需要像使用模型一样使用 Base.findall() 的结果,这可能吗?”。 Base#find 方法的结果是地图或地图列表。键是您从数据库中选择的,值是 JDBC 驱动程序根据您的数据库到 Java 类型的映射返回的任何值。因此,Base 的结果不是模型。但是,正如我所展示的,您可以轻松地将这些结果转换为模型。
    猜你喜欢
    • 1970-01-01
    • 2020-03-17
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多