在创建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。