2010-12-10 57 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决赛。

相关问题