【问题标题】:Hibernate/Spring taking out class mapping. About reflectionHibernate/Spring 取出类映射。关于反射
【发布时间】:2012-08-02 23:23:07
【问题描述】:

我正在尝试编写一个使用 hibernate 写入数据库的应用程序,但是在某些操作中,我必须对 HB 制作的表中的数据使用 JDBC。

JDBS 需要为管理员提供创建 SQL 查询的能力,该查询将返回有关数据库中数据的统计信息,例如指定类型的已处理文档的数量、成功/失败的登录尝试次数或订单中产品的总价值。

为此,我做了一个 from ,它允许创建覆盖 toString() 并返回漂亮的 sql 查询字符串的类。 所有的作品,但现在我试图通过让管理员能够选择表/列名来让管理员生活得更轻松。这是一个问题,因为它们是由hibernate创建的。一些由@column 注释,另一些由字段名称。 我如何检查字段映射? 我知道反射的全部内容,但在 java 中还没有做太多。

例子

@Entity
@Table(name= "my_table_name" )
public class TableOFSomething implements Serializable{
   //This field isn't mapped into database and info about it is not requred.
   //In fact, info about it may cause an error.
   private static final long serialVersionUID = 7L;

   @Id
   @Column(name="id")
   private String id;

   private String fieldOne;

   @Column(name="field_two")
   private String fieldTwo;

   @Column(name="renamed_just_for_fun")
   private int Number;

   //code with getters & setters
}

如何编写具有类似定义的方法

public <T> String tableName(Class<T> Target); //returns name of table in database
public <T> ArrayList<String> tabelFields(Class<T> Target); //returns name of fields in database

【问题讨论】:

  • 如果你使用 JDBC、SQL、表和列名来查询你的数据库,你为什么要关心 Hibernate 实体?为什么不使用数据库元数据?如果您真的想了解实体及其属性,请使用 EntityManagerFactory 的元模型。 docs.oracle.com/javaee/6/api/javax/persistence/…
  • 您确定 HQL 不足以满足您的查询吗?它有聚合。
  • 并不是说 HQL 不适合这项任务,但工具是为知道 SQL 而不是 HQL 的人准备的。当然我可以告诉他点击按钮或学习 HQL,但是给他一个他熟悉的 SQL 工具不是更好吗? @JB Nizet 好点,但我想尝试在不连接数据库的情况下准备这些信息,并用于学习目的;)

标签: sql spring hibernate reflection


【解决方案1】:

Hibernate 有 API - getClassMetadata 可以探索映射。 API 可能会更改并且现在位于另一个地方,但我将使用它而不是为此进行反思。 查看这篇文章了解更多详情: Get the table name from the model in Hibernate

如果你想要反射,请使用link

【讨论】:

  • 谢谢,这对休眠方式有很大帮助。但是我自己找到了反射方法并稍后发布解决方案。我想知道我是否涵盖了所有可能性。
【解决方案2】:
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;

import javax.persistence.Column;
import javax.persistence.Table;

import odi.beans.statistic.QueryBean;

public class ReflectionTest {
    public static void main(String[] args) {
        ReflectionTest test=new ReflectionTest();
        System.out.println("Table name of "+QueryBean.class.getName()+" is "+test.getTableName(QueryBean.class));
        System.out.println("Column names in this table are:");
        for(String n: test.getColumnNames(QueryBean.class)){
            System.out.println("\t"+n);
        }
        System.out.println("Good bye ;)");
    }

    public <T> ArrayList<String> getColumnNames(Class<T> target) {
        ArrayList<String> ret=new ArrayList<>();
        Field[] fields = target.getDeclaredFields();
        String fieldName =null;
        for (Field f : fields) {
            //jump to next if if field is static
            if (Modifier.isStatic(f.getModifiers()))
                continue;
            if (f.isAnnotationPresent(Column.class)) {
                Column a = f.getAnnotation(Column.class);
                fieldName = a.name();
            } else {
                fieldName = f.getName();
            }
            ret.add(fieldName);
        }
        return ret;
    }

    public <T> String getTableName(Class<T> target){
        String ret=target.getSimpleName();
        if (target.isAnnotationPresent(Table.class))
        {
            Table t=target.getAnnotation(Table.class);
            ret=t.name();
        }
        return ret;
    }
}

它是否涵盖了所有可能性? 我现在知道休眠方式会更容易,但这也是学习非常有用的反射机制:)

编辑: 重要问题: 这仅适用于注释还是也适用于 xml 映射?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-12
    • 1970-01-01
    • 2010-12-11
    • 2010-10-28
    • 2011-03-17
    • 1970-01-01
    相关资源
    最近更新 更多