Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 如何从实体管理器获取数据库元数据_Hibernate_Jpa - Fatal编程技术网

Hibernate 如何从实体管理器获取数据库元数据

Hibernate 如何从实体管理器获取数据库元数据,hibernate,jpa,Hibernate,Jpa,我有一个使用hibernate和jpa的应用程序。我需要找出它连接到哪个数据库,以便基于数据库执行一些本地sql查询,比如oracle和postgres。如果我使用纯jdbc,那么直接获取db元数据是很简单的,但不知道如何从实体管理器获取 多亏了作为一种解决方法,您可以获取EntityManagerFactory属性以获取底层数据库配置,这是特定于实现的 Hibernate:Hibernate.connection.driver\u class EclipseLink:EclipseLink.

我有一个使用hibernate和jpa的应用程序。我需要找出它连接到哪个数据库,以便基于数据库执行一些本地sql查询,比如oracle和postgres。如果我使用纯jdbc,那么直接获取db元数据是很简单的,但不知道如何从实体管理器获取


多亏了作为一种解决方法,您可以获取
EntityManagerFactory
属性以获取底层数据库配置,这是特定于实现的

  • Hibernate
    Hibernate.connection.driver\u class

  • EclipseLink:
    EclipseLink.target database
    此属性指定目标数据库。在您的情况下,对于相应的数据库,它的值可能为
    Oracle
    PostgreSQL

  • 常规:
    javax.persistence.jdbc.driver

根据此信息,可以获取当前连接的数据库

EntityManagerFactory emf = entityManager.getEntityManagerFactory();     
Map<String, Object> emfProperties = emf.getProperties();

String driverClass = (String)emfProperties.get(PROPERTY);
//-- For PostgreSQL, it will have value "org.postgresql.Driver"

if(driverClass.lastIndexOf("postgresql") != -1)
    postGreSQL_DB = true;
现在,您可以从中获取数据库产品名称、驱动程序等。

如果其他人(如我)想要获取一些jdbc信息,并且您正在使用hibernate 4.x,您可以这样尝试:

导入java.sql.Connection;
导入java.sql.SQLException;
导入org.hibernate.jdbc.Work;
公共类ConnectionInfo实现工作{
公共字符串数据库URL;
公共字符串数据库产品名称;
公共字符串驱动程序名;
@凌驾
public void execute(连接)引发SQLException{
dataBaseUrl=connection.getMetaData().getURL();
dataBaseProductName=connection.getMetaData().getDatabaseProductName();
driverName=connection.getMetaData().getDriverName();
}
公共字符串getDataBaseProductName(){
返回dataBaseProductName;
}
公共无效setDataBaseProductName(字符串dataBaseProductName){
this.dataBaseProductName=dataBaseProductName;
}
公共字符串getDataBaseUrl(){
返回数据库URL;
}
public void setDataBaseUrl(字符串dataBaseUrl){
this.dataBaseUrl=dataBaseUrl;
}
公共字符串getDriverName(){
返回驱动器名称;
}
公共无效setDriverName(字符串driverName){
this.driverName=driverName;
}
}
现在您可以像这样检索您的信息:

/--snip
org.hibernate.ejb.EntityManagerImpl EntityManagerImpl=(org.hibernate.ejb.EntityManagerImpl)genericdaccess.getEntityManager().getDelegate();
Session Session=entityManagerImpl.getSession();
connectionInfo=新的connectionInfo();
session.doWork(connectionInfo);
//“啪

希望有帮助!在Hibernate 4中,您可以使用以下代码从实体管理器获取数据库信息:

org.hibernate.engine.spi.SessionImplementor sessionImp = 
     (org.hibernate.engine.spi.SessionImplementor) eManager.getDelegate();
DatabaseMetaData metadata = sessionImp.connection().getMetaData();
//do whatever you need with the metadata object...
metadata.getDatabaseProductName();
干杯


Emmanuel

基于Emmanuel回答如何使用Spring和hibernate:

 @Repository
 public class UserRepository {

    @PersistenceContext
    private EntityManager em;

    public void getMeta() {
        org.hibernate.engine.spi.SessionImplementor sessionImp = (org.hibernate.engine.spi.SessionImplementor) em.getDelegate();
        DatabaseMetaData metadata = null;
        try {
            metadata = sessionImp.connection().getMetaData();
            ResultSet res = metadata.getColumns(null, null, "USERS", "USERNAME");
            System.out.println("List of columns: ");
            while (res.next()) {
                System.out.println(
                        "  " + res.getString("TABLE_SCHEM")
                                + ", " + res.getString("TABLE_NAME")
                                + ", " + res.getString("COLUMN_NAME")
                                + ", " + res.getString("TYPE_NAME")
                                + ", " + res.getInt("COLUMN_SIZE")
                                + ", " + res.getInt("NULLABLE"));
            }
            res.close();
            System.out.println();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

使用以下行获取与连接和数据源相关的信息

entityManager.getEntityManagerFactory().getProperties().get("hibernate.connection.datasource");

如果您想从url获取dba名称

public String getDbName() throws SQLException {
    SessionImplementor sessionImp = (SessionImplementor) em.getDelegate();
    DatabaseMetaData metadata = sessionImp.connection().getMetaData(); 

    String dbName="";
    Pattern urlDbName = Pattern.compile("databaseName=([A-Za-z0-9\\-\\_]+)");
    Matcher m = urlDbName.matcher(metadata.getURL());
    while (m.find()) {
        dbName = m.group(1);
    }

    return dbName;   
}

谢谢Nayan提供的这些有用的提示。当我试图从em获取emf时,我没有看到它们,所以我提出了以下代码DatabaseMetaData dbmd=((会话)entityManager.getDelegate()).connection().getMetaData();dbName=dbmd.getDatabaseProductName();我不知道这段代码是否可以移植到diff server,也不知道正确的方法,因为hibernate将从版本4.x中删除connection()方法。但现在这对我有用。@user509755很高兴你发现它很有用。正如您在问题中提到的,我在实体管理器中试用过。另外,当您尝试使用实体管理器时发生了什么。您可以将其作为答案发布,可能会对某人有所帮助。我在entitymanager上没有看到名为getEntityManagerFactory()的方法。这就是我必须找到我前面提到的备用选项的原因。@user509755它在JavaEE6中,可以参考
public String getDbName() throws SQLException {
    SessionImplementor sessionImp = (SessionImplementor) em.getDelegate();
    DatabaseMetaData metadata = sessionImp.connection().getMetaData(); 

    String dbName="";
    Pattern urlDbName = Pattern.compile("databaseName=([A-Za-z0-9\\-\\_]+)");
    Matcher m = urlDbName.matcher(metadata.getURL());
    while (m.find()) {
        dbName = m.group(1);
    }

    return dbName;   
}