2010-12-10 53 views
18

我創建SessionFactory,我有我的數據源作爲對象在代碼中創建SessionFactory,但我不能將數據源設置爲Hibernate配置對象。那麼如何將我的數據源設置爲我的SessionFactory?我在創建Hibernate SessionFactory時如何設置Datasource?

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(); 

回答

13

要提供JDBC連接會話,你需要的ConnectionProvider的實現。

Bu默認,Hibernate使用DatasourceConnectionProvider,它從JNDI獲取DataSource實例。

要使用自定義DataSource實例,請使用InjectedDataSourceConnectionProvider,並將DataSource實例注入其中。

上有InjectedDataSourceConnectionProvider

注意待辦事項: 的setDataSource(javax.sql.DataSource中) 前必須 配置(java.util.Properties)被調用。

TODO:找不到 setDataSource實際上被調用。 不能這只是通過 配置???

按照說明,從configure()方法調用setDataSource()方法。

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

合同

執行者應該提供公共 默認構造函數。

如果通過配置實例設置自定義的ConnectionProvider,Hibernate將調用此構造函數。

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

我不認爲你可以。 Hibernate API可以讓你配置JDBC屬性,以便它可以管理連接本身,或者你可以給它一個JNDI數據源位置,以便它可以去取它,但我認爲你不可以將其作爲一個DataSource 。

關於你使用Spring的機會,這很容易 - 使用LocalSessionFactoryBean來配置Hibernate,並將你的DataSource注入到它。春天在後臺執行必要的魔術。

+0

你有沒有指向示例配置的任何鏈接? – newbie 2010-12-10 08:48:32

+0

@newbie:你的意思是像文檔? http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/session-configuration.html – skaffman 2010-12-10 08:49:54

+0

我的意思是我該如何使用LocalSessionFactoryBean – newbie 2010-12-10 08:50:29

2

如果您的數據源是在JNDI樹界:

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

否則,如果您在代碼中的數據源對象,要使用:

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

我建議第一一,讓Hibernate根據需要處理連接生命週期。在第二種方法中,確保在不再需要連接時關閉連接。

1

如果您使用Spring框架,那麼使用LocalSessionFactoryBean將您的數據源注入到Hibernate SessionFactory中。

<beans> 
    <bean id="YourClass" 
     class="com.YourClass. 
     <property name="sessionFactory"> 
      <ref bean="DbSessionFactory" /> 
     </property>  
    </bean> 


    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
     <property name="driverClassName"> 
      <value>org.postgresql.Driver</value> 
     </property> 
     <property name="url"> 
      <value>jdbc:postgresql://localhost/yourdb</value> 
     </property> 
     <property name="username"> 
      <value>postgres</value> 
     </property> 
     <property name="password"> 
      <value>postgres</value> 
     </property>  
    </bean> 

    <bean id="DbSessionFactory" 
     class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
     <property name="dataSource"> 
      <ref local="dataSource"/> 
     </property>  
     <property name="mappingResources"> 
      <list> 
       <value>conf/hibernate/UserMapping.hbm.xml</value>    
      </list> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect"> org.hibernate.dialect.PostgreSQLDialect </prop>  
       <prop key="hibernate.hbm2ddl.auto">update</prop> 
       <prop key="hibernate.cache.use_second_level_cache"> true </prop> 
       <prop key="hibernate.cache.use_query_cache">true</prop> 
      </props> 
     </property> 
    </bean> 
</beans> 
9

如果你碰巧有你的DataSource存儲在JNDI,然後只需使用:

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

但是,如果你使用Apache DBCP或BoneCP和自定義數據源提供你不想

//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()); 
:使用依賴注入框架如Spring
,那麼你可以創建 SessionFactory之前注入它的

請注意,如果您使用此方法,則無需再將連接參數放入您的hibernate.cfg.xml中。使用從上面的方法當這裏的一個兼容hibernate.cfg.xml文件的一個例子:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-configuration PUBLIC 
     "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 

    <session-factory> 
     <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> 
     <property name="show_sql">false</property> 
     <!-- your mappings to classes go here --> 
    </session-factory> 
</hibernate-configuration> 

代碼上休眠4.3以上測試。

1

如果您使用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(); 
     ... 
    } 
} 
2

Luiggi門多薩的回答是,爲什麼我的搜索送我來這裏,但我想我應該給我的版本,因爲我花了相當長的一段時間四處尋找如何做到這一點 - 它與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; 
    } 

} 

,你會需要這些:

<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-jdbc</artifactId> 
    <version>4.1.6.RELEASE</version> 
</dependency> 
<dependency> 
    <groupId>com.h2database</groupId> 
    <artifactId>h2</artifactId> 
    <version>1.4.184</version> 
    <scope>test</scope> 
</dependency> 
0

我用LocalContainerEntityManagerFactoryBean到c在配置類中重新創建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決賽。

相關問題