【问题标题】:In @Table(name = "tableName") - make "tableName" a variable in JPA在 @Table(name = "tableName") - 使“tableName”成为 JPA 中的变量
【发布时间】:2011-01-27 13:08:34
【问题描述】:

我正在使用 JPA,我需要将“tableName”设为变量。

在数据库中,我有很多表,我的代码需要访问我指定要读取的表。

@Entity
@Table(name = "tableName")
public class Database implements Serializable {...............}

有什么想法吗?

【问题讨论】:

  • “我的代码需要访问我指定要读取的表。”您能否说明您要执行的操作。
  • 请看我的评论回答1。谢谢。
  • 重新表述:我需要动态架构。动态创建表的位置。
  • 你想在运行时创建一个新表吗???
  • 每当我听说数据库模式包含可变数量的表时,我就知道有人缺少基本的关系数据库原则。

标签: java jpa ejb-3.0


【解决方案1】:

我有一个解决方法。
它使用 javax.persistence.EntityManager 和 String.format 来做到这一点。

package com.example.test.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import javax.persistence.EntityManager;

@Component
public class SomeDao {
    @Autowired
    EntityManager em;

    public List<?> listFoodMoneyDateOfPayment(int departmentId, String sumKey, String tableName) {
        String s = "SELECT SUM(%s) AS money, CONCAT(YEAR(apply_time), '-', MONTH(apply_time)) AS yearmonth " +
                "FROM (%s) WHERE department_id = %d GROUP BY yearmonth";
        String sql = String.format(s, sumKey, tableName, departmentId);
        System.out.println(sql);

        List<?> test = em.createNativeQuery(sql).getResultList();

        return test;
    }
}

调用代码是:

@RestController
@RequestMapping("/api")
public class TestController {

    @Autowired
    private SomeDao dao;

    @RequestMapping("/test2")
    public HttpEntity test2() {
        var l = dao.listFoodMoneyDateOfPayment(12, "food_payment", "payment_application");
        System.out.println(l.getClass());
        System.out.println(JSON.toJSONString(l));
        return ResultBean.success();
    }
}

而且效果很好。
但是你应该检查传入的参数。

【讨论】:

    【解决方案2】:

    你可以做这样的事情,如果那是你的担心,我猜。 从未尝试过,这只是一个疯狂的猜测。但这是通常的做法——我遵循命名查询;是的,那完全是另一回事。

    @Entity
    @Table(name = Database.tableName)
    public class Database implements Serializable {
        public static final String tableName = "TABLE_1";
        ...............
    }
    

    但我不明白为什么有人会这样做。你能告诉我们你在做什么吗?为什么你有几个表完全相同的定义?

    [已编辑]

    我尝试了您的解决方案。它没 工作,它说:价值 注释属性 Table.name 必须 是一个常量表达式。

    那么,这还不够清楚吗?我的意思是你不能那样做。我相信这很合乎逻辑。如果您希望 Hibernate 生成您的架构,那么您可以在架构中定义您想要的所有实体,并使用适当的关系。

    【讨论】:

    • 好的,这是我的方案。我有一个名为“数据库”的 JPA 类,我可以有许多表(取决于来自客户端的输入数据)。因此,目前,Database 类仅在运行时创建一个表(@Table = name)。但是我需要这个类在运行时使用来自其他地方的 TableName 变量创建表。我试过你的解决方案。它不起作用,它说:注释属性 Table.name 的值必须是一个常量表达式。
    • 重新表述:我需要动态模式。动态创建表的位置。
    • @zengr:查看我的帖子附录。
    • 感谢您的帮助。 :) 我正在使用 JPA 和另一个问题,“em.createNativeQuery(创建表 SQL 查询)”会起作用吗?其中EntityManager em。
    • 而且,这篇文章是一种解决方法吗? java.dzone.com/articles/hibernate-dynamic-table-routin
    【解决方案3】:

    如果要从不同的表中选择数据,

    然后你可以使用:

    @Subselect("")

    而不是:

    @Table(name = "tableName").

    【讨论】:

      【解决方案4】:

      如果您只想引用/读取表名,可以如下面的代码所示。如果你想改变,就像帕斯卡说的那样是不可能的。

      @Entity
      @Table(name = Database.tableName)
      public class Database implements Serializable {
          public static final String tableName = "TABLE_1";//this variable you can reference in other portions of your code. Of course you cannot change it.
          ...............
      }
      

      【讨论】:

        【解决方案5】:

        无法在运行时指定表名,这根本不是 JPA 的工作方式(我仍然不确定是否能满足您的要求)。要么在你的表集上映射不同的实体并运行各种查询,要么根据来自客户端的输入动态构建它们(可能使用 Criteria API)使用 JPA 以外的其他东西(如 iBATIS)。

        【讨论】:

        • 这是一种可能的解决方法吗? java.dzone.com/articles/hibernate-dynamic-table-routin
        • @zengr 我无法回答这个问题,我仍然不明白您要做什么。动态表?不同的架构?这个不清楚。
        • @zengr 它看起来确实像这个链接做你想要的(尽管它可以完全混淆维护工程师的东西)。 Hibernate Shards 也是一个有趣的选择。但是当你朝着这个方向前进时,请多次问自己“你真的需要这个吗?”。您的项目真的很复杂,无法保证这个复杂的解决方案吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-04-07
        • 2010-11-22
        • 2011-08-27
        • 2017-07-09
        • 2021-03-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多