在创建Hibernate SessionFactory时如何设置Datasource?

我正在创建SessionFactory,我将数据源作为对象在我创建SessionFactory的代码中,但是我无法将数据源设置为Hibernate Configuration对象。 那么如何将我的数据源设置为SessionFactory?

Configuration configuration = new Configuration(); Properties properties = new Properties(); properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect"); configuration.setProperties(properties); configuration.setProperty("packagesToScan", "com.my.app"); SessionFactory sessionFactory = configuration.configure().buildSessionFactory(); 

要向Session提供JDBC连接,您需要ConnectionProvider的实现。

默认情况下,Hibernate使用DatasourceConnectionProvider从JNDI获取DataSource实例。

要使用自定义DataSource实例,请使用InjectedDataSourceConnectionProvider ,并将DataSource实例注入其中。

InjectedDataSourceConnectionProvider上有TODO注释

注意:必须在configure(java.util.Properties)之前调用setDataSource(javax.sql.DataSource)。

TODO:找不到实际调用setDataSource的位置。 这不能只是传入配置???

根据注释,从configure()方法调用setDataSource() configure()方法。

 public class CustomConnectionProvider extends InjectedDataSourceConnectionProvider { @Override public void configure(Properties props) throws HibernateException { org.apache.commons.dbcp.BasicDataSource dataSource = new BasicDataSource(); org.apache.commons.beanutils.BeanUtils.populate( dataSource, props ); setDataSource(dataSource); super.configure(props); } } 

您还可以扩展UserSuppliedConnectionProvider 。

根据ConnectionProvider的合同

实现者应该提供公共默认构造函数。

如果通过Configuration实例设置了自定义ConnectionProvider,Hibernate将调用此构造函数。

 Configuration cfg = new Configuration(); Properties props = new Properties(); props.put( Environment.CONNECTION_PROVIDER, InjectedDataSourceConnectionProvider.class.getName() ); cfg.addProperties(props); 

如果您碰巧将DataSource存储在JNDI中,那么只需使用:

 configuration.setProperty( "hibernate.connection.datasource", "java:comp/env/jdbc/yourDataSource"); 

但是如果您使用Apache DBCP或BoneCP之类的自定义数据源提供程序并且您不想使用像Spring这样的dependency injection框架 ,那么您可以在创建SessionFactory之前将其注入StandardServiceRegistryBuilder

 //retrieve your DataSource DataSource dataSource = ...; Configuration configuration = new Configuration() .configure(); //create the SessionFactory from configuration SessionFactory sf = configuration .buildSessionFactory( new StandardServiceRegistryBuilder() .applySettings(configuration.getProperties()) //here you apply the custom dataSource .applySetting(Environment.DATASOURCE, dataSource) .build()); 

请注意,如果使用此方法,则无需再将连接参数放在hibernate.cfg.xml中。 以下是使用上述方法时兼容的hibernate.cfg.xml文件的示例:

     org.hibernate.dialect.MySQLInnoDBDialect false    

上面的代码在Hibernate 4.3上测试过。

如果您的数据源在JNDI树中有界:

 configuration.setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test"); 

否则,如果您在代码中有一个DataSource对象,则要使用该对象:

 java.sql.Connection conn = datasource.getConnection(); Session session = sessionFactory.openSession(conn); 

我建议第一个,让Hibernate根据需要处理连接生命周期。 在第二种方法中,确保在不再需要时关闭连接。

Luiggi Mendoza的回答是为什么我的搜索发送给我的原因,但我认为我应该给出我的版本,因为我花了很长时间四处寻找如何做到这一点 – 它使用Spring内存数据库进行测试,一个SessionContext和如果您没有使用注释,请使用hbm.xml:

 /** * Instantiates a H2 embedded database and the Hibernate session. */ public abstract class HibernateTestBase { private static EmbeddedDatabase dataSource; private static SessionFactory sessionFactory; private Session session; @BeforeClass public static void setupClass() { dataSource = new EmbeddedDatabaseBuilder(). setType(EmbeddedDatabaseType.H2). addScript("file:SQLResources/schema-1.1.sql"). addScript("file:SQLResources/schema-1.2.sql"). build(); Configuration configuration = new Configuration(); configuration.addResource("hibernate-mappings/Cat.hbm.xml"); configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect"); configuration.setProperty("hibernate.show_sql", "true"); configuration.setProperty("hibernate.current_session_context_class", "org.hibernate.context.internal.ThreadLocalSessionContext"); StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder(); serviceRegistryBuilder.applySetting(Environment.DATASOURCE, dataSource); serviceRegistryBuilder.applySettings(configuration.getProperties()); StandardServiceRegistry serviceRegistry = serviceRegistryBuilder.build(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); sessionFactory.openSession(); } @AfterClass public static void tearDown() { if (sessionFactory != null) { sessionFactory.close(); } if (dataSource != null) { dataSource.shutdown(); } } @Before public final void startTransaction() { session = sessionFactory.getCurrentSession(); session.beginTransaction(); } @After public final void rollBack() { session.flush(); Transaction transaction = session.getTransaction(); transaction.rollback(); } public Session getSession() { return session; } } 

你需要这些:

  org.springframework spring-jdbc 4.1.6.RELEASE   com.h2database h2 1.4.184 test  

我认为你不能。 Hibernate API将允许您配置JDBC属性,以便它可以自己管理连接,或者您可以为它提供JNDI DataSource位置,以便它可以去获取它,但我认为您不能它一个DataSource。

如果您使用Spring的LocalSessionFactoryBean ,那么使用LocalSessionFactoryBean来配置Hibernate,并将DataSource注入其中。 Spring在后台执行必要的魔术。

如果您使用的是Spring框架,那么请使用LocalSessionFactoryBean将数据源注入Hibernate SessionFactory。

        org.postgresql.Driver   jdbc:postgresql://localhost/yourdb   postgres   postgres         conf/hibernate/UserMapping.hbm.xml      org.hibernate.dialect.PostgreSQLDialect  update  true  true     

如果您已经使用javax.sql.DataSource实现了一个类,则可以通过配置属性来设置Hibernate的DataSource

 import javax.sql.DataSource; public class HibernateDataSource implements DataSource { ... } import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; public class MyHibernateCfg { public void initialize() { HibernateDataSource myDataSource = new HibernateDataSource(); Configuration cfg = new Configuration(); // this is how to configure hibernate datasource cfg.getProperties().put(Environment.DATASOURCE, myDataSource); ... } } import org.hibernate.cfg.Configuration; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.service.ServiceRegistry; import org.hibernate.SessionFactory; import org.hibernate.Session; public class TableClass { public void initialize() { MyHibernateCfg cfg = new MyHibernateCfg(); Configuration conf = cfg.getCfg(); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build(); SessionFactory sessionFactory = conf.buildSessionFactory(serviceRegistry); Session sessionFactory.openSession(); ... } } 

我使用LocalContainerEntityManagerFactoryBean在配置类中创建EntityManagerFactory实例。

如果需要设置另一个DataSource,那么可以在运行时使用实体管理器工厂实例更新它:

 @Service("myService") public class MyService { .... @Autowired private LocalContainerEntityManagerFactoryBean emf; .... public void replaceDataSource(DataSource dataSource) { emf.setDataSource(dataSource); emf.afterPropertiesSet(); } .... } 

它适用于Hibernate 5.2.9 Final。