我正在创建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();
答案 0 :(得分:14)
要向Session提供JDBC连接,您需要实现ConnectionProvider。
默认情况下,Hibernate使用DatasourceConnectionProvider
从JNDI获取DataSource
实例。
要使用自定义DataSource
实例,请使用InjectedDataSourceConnectionProvider
并将DataSource
实例注入其中。
InjectedDataSourceConnectionProvider
上有TODO注释注意: 的setDataSource(javax.sql.DataSource中) 必须先调用 配置(java.util.Properties)。
TODO:找不到哪里 实际上调用了setDataSource。 不能这只是传递给 配置???
根据说明,请从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);
答案 1 :(得分:9)
如果您恰好将DataSource
存储在JNDI中,那么只需使用:
configuration.setProperty(
"hibernate.connection.datasource",
"java:comp/env/jdbc/yourDataSource");
但是如果您使用自定义数据源提供程序(如Apache DBCP或BoneCP)和您不想使用像Spring这样的依赖注入框架,那么您可以将其注入{{1}在创建StandardServiceRegistryBuilder
:
SessionFactory
请注意,如果使用此方法,则无需再将连接参数放在hibernate.cfg.xml中。以下是使用上述方法时兼容的hibernate.cfg.xml文件的示例:
//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 4.3上测试过。
答案 2 :(得分:3)
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;
}
}
你需要这些:
<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>
答案 3 :(得分:2)
如果您的数据源在JNDI树中有界:
configuration.setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test");
否则,如果您要在代码中使用DataSource对象:
java.sql.Connection conn = datasource.getConnection();
Session session = sessionFactory.openSession(conn);
我建议第一个,让Hibernate根据需要处理连接生命周期。在第二种方法中,确保在不再需要时关闭连接。
答案 4 :(得分:1)
我认为你不能。 Hibernate API将允许您配置JDBC属性,以便它可以自己管理连接,或者您可以为它提供一个JNDI DataSource位置,以便它可以去获取它,但我认为您不能给> em>它是一个DataSource。
如果你正在使用Spring,那就更容易 - 使用LocalSessionFactoryBean
来配置Hibernate,并将你的DataSource注入其中。 Spring在后台执行必要的魔术。
答案 5 :(得分: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>
答案 6 :(得分: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();
...
}
}
答案 7 :(得分:0)
我使用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。