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