【问题标题】:Hibernate: Avoid using column names as stringsHibernate:避免使用列名作为字符串
【发布时间】:2015-07-08 15:05:08
【问题描述】:

我想避免在代码中将列名作为字符串。有没有其他方法可以做到这一点?:

String query = "SELECT c.foo1.columnA, c.foo1.foo2.columnB FROM Table c";
session.createQuery(query).list();

我可以通过拆分和获取ClassMetadata、属性Type 和其他Hibernate 函数来迭代列作为c.foo1.foo2.columnB 之类的字符串,直到我到达最后一个元素。但是,我想不出一种从 Java bean 获取列字符串的方法,也可以遍历属性。

【问题讨论】:

  • 我的建议:保持你的代码不变。这种方式更具可读性。实施单元测试以确保您的查询是有效的,并做他们应该做的事情。使用命名查询,以便在部署时对其进行验证。
  • 但它们不是列名。它们是您的实体的类属性名称。而且您也不是从特定表中进行选择,而是在查询实体实例。这读起来像是一个 X/Y 问题——为什么要让属性名称变量?您想对不同的实体重复使用相同的查询吗?
  • 实际上,我不得不重组数据库中的一些表和列。因此,我不得不更改我的 Java bean。但是,我还必须在所有代码中搜索使用某些已更改列的查询。因此,我想知道是否有更好的方法来解决这个问题。
  • 标准呢?

标签: java hibernate javabeans hibernate-mapping


【解决方案1】:

不知道目的是什么。几个想法

如果您担心属性名称错误的可能性,当前的 IDE 通过验证 JPA 查询中的属性名称做得很好

对象反射可以给你属性名称。但不一定所有属性都映射到列。您可以查看 this 并通过反射将其与 bean 属性名称一起使用。

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    没有办法实现您正在寻找的东西。但是,如果您担心这些查询的正确性并担心在执行到此之前不会知道问题,您可以使用NamedQuery

    @Entity
    @NamedQuery(
        name="findAllEmployeesByFirstName",
        queryString="SELECT OBJECT(emp) FROM Employee emp WHERE emp.firstName = 'John'"
    )
    
    public class Employee implements Serializable {
    ...
    }
    

    用法

    List employees = em.createNamedQuery("findAllEmployeesByFirstName").getResultList();
    

    好处是NamedQuery 注释中定义的查询在启动时被编译为实际的 SQL。所以不正确的字段引用(错字等)将导致启动错误,应用程序将无法启动。

    另一个选项将在另一个答案中提到,以信任一个好的 IDE 在重命名字段时正确重构所有出现(Idea 在这方面做得很好,任何其他 IDE 也一样)

    编辑:我不认为命名查询有任何性能下降。相反,它可能看起来更快,因为已编译的查询被缓存(非常主观)

    最后,最好按照 cmets 中提到的原样使用实际查询。它在其上下文中更具可读性和调试性。如果您担心正确性,请对它进行单元测试并保持信心。

    【讨论】:

    • 如果使用NamedQuery 我得到启动错误,这将是对我的代码的巨大改进。我觉得字符串查询容易出现执行错误。谢谢!
    • 启动时查询编译的性能是否受到影响?
    猜你喜欢
    • 2021-09-08
    • 2016-03-27
    • 2014-06-05
    • 2023-02-09
    • 1970-01-01
    • 2021-03-09
    • 2015-12-16
    • 2011-04-19
    • 1970-01-01
    相关资源
    最近更新 更多