`

Hibernate通过切换SessionFactory切换数据库方言(转载备用)

 
阅读更多

Spring3 整合Hibernate3.5 动态切换SessionFactory (切换数据库方言)

 

一、缘由

数据库方言可能在当前应用的架构中意义不是很大,但是如果单纯用MyBatis或Hibernate做数据库持久化操作,还是要处理这一问题。 

那么下面将介绍怎么样动态切换SessionFactory,为什么要切换SessionFactory

因为这里切换SessionFactory就可以实现多数据源和多个SessionFactory,每个SessionFactory有自己独立的数据库配置和SessionFactory的相关配置。我们的数据库方言就配置在SessionFactory这里,所以实现了切换SessionFactory也就实现了切换数据库方言的问题。这个主要是针对Hibernate来操作的,而MyBatis则需要动态切换SqlSessionFactory才行。

 

二、实现代码

1、定义全局切换SessionFactory的工具

package com.hoo.framework.spring.support;

/**
 * <b>function:</b> 多数据源
 * @author hoojo
 * @createDate 2013-9-27 上午11:36:57
 * @file CustomerContextHolder.java
 * @package com.hoo.framework.spring.support
 * @project SHMB
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
public abstract class CustomerContextHolder {

    public final static String SESSION_FACTORY_MYSQL = "mysql";
    public final static String SESSION_FACTORY_ORACLE = "oracle";

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();  

    public static void setCustomerType(String customerType) {  
        contextHolder.set(customerType);  
    }  

    public static String getCustomerType() {  
        return contextHolder.get();  
    }  

    public static void clearCustomerType() {  
        contextHolder.remove();  
    }  
}

同样上面的静态变量和前一文章中介绍的一致,它需要和下面配置文件中的SessionFactory的key对应。

2、实现自己的SessionFactory

定义好接口

package com.hoo.framework.spring.support.core;

import org.hibernate.SessionFactory;

/**
 * <b>function:</b> 动态SessionFactory接口
 * @author hoojo
 * @createDate 2013-10-12 下午03:29:52
 * @file DynamicSessionFactory.java
 * @package com.hoo.framework.spring.support.core
 * @project SHMB
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
public interface DynamicSessionFactory extends SessionFactory {

    public SessionFactory getHibernateSessionFactory();
}

 

实现接口

package com.hoo.framework.spring.support.core;

import java.io.Serializable;
import java.sql.Connection;
import java.util.Map;
import java.util.Set;
import javax.naming.NamingException;
import javax.naming.Reference;
import org.hibernate.Cache;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.TypeHelper;
import org.hibernate.classic.Session;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.stat.Statistics;
import com.hoo.framework.spring.support.CustomerContextHolder;

/**
 * <b>function:</b> 动态数据源实现
 * @author hoojo
 * @createDate 2013-10-12 下午03:31:31
 * @file DynamicSessionFactoryImpl.java
 * @package com.hoo.framework.spring.support.core
 * @project SHMB
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
@SuppressWarnings({ "unchecked", "deprecation" })
public class DynamicSessionFactoryImpl implements DynamicSessionFactory {

    private static final long serialVersionUID = 5384069312247414885L;

    private Map<Object, SessionFactory> targetSessionFactorys;  
    private SessionFactory defaultTargetSessionFactory; 

    /**
     * @see com.hoo.framework.spring.support.core.DynamicSessionFactory#getHibernateSessionFactory()
     * <b>function:</b> 重写这个方法,这里最关键
     * @author hoojo
     * @createDate 2013-10-18 上午10:45:25
     */
    @Override
    public SessionFactory getHibernateSessionFactory() {
        SessionFactory targetSessionFactory = targetSessionFactorys.get(CustomerContextHolder.getCustomerType());  
        if (targetSessionFactory != null) {  
            return targetSessionFactory;  
        } else if (defaultTargetSessionFactory != null) {  
            return defaultTargetSessionFactory;  
        }  
        return null;
    }

    @Override
    public void close() throws HibernateException {
        this.getHibernateSessionFactory().close();
    }

    @Override
    public boolean containsFetchProfileDefinition(String s) {
        return this.getHibernateSessionFactory().containsFetchProfileDefinition(s);
    }

    @Override
    public void evict(Class clazz) throws HibernateException {
        this.getHibernateSessionFactory().evict(clazz);
    }

    @Override
    public void evict(Class clazz, Serializable serializable) throws HibernateException {
        this.getHibernateSessionFactory().evict(clazz, serializable);
    }

    @Override
    public void evictCollection(String s) throws HibernateException {
        this.getHibernateSessionFactory().evictCollection(s);
    }

    @Override
    public void evictCollection(String s, Serializable serializable) throws HibernateException {
        this.getHibernateSessionFactory().evictCollection(s, serializable);
    }

    @Override
    public void evictEntity(String entity) throws HibernateException {
        this.getHibernateSessionFactory().evictEntity(entity);
    }

    @Override
    public void evictEntity(String entity, Serializable serializable) throws HibernateException {
        this.getHibernateSessionFactory().evictEntity(entity, serializable);
    }

    @Override
    public void evictQueries() throws HibernateException {
        this.getHibernateSessionFactory().evictQueries();        
    }

    @Override
    public void evictQueries(String queries) throws HibernateException {
        this.getHibernateSessionFactory().evictQueries(queries);        
    }

    @Override
    public Map<String, ClassMetadata> getAllClassMetadata() {
        return this.getHibernateSessionFactory().getAllClassMetadata();
    }

    @Override
    public Map getAllCollectionMetadata() {
        return this.getHibernateSessionFactory().getAllClassMetadata();
    }

    @Override
    public Cache getCache() {
        return this.getHibernateSessionFactory().getCache();
    }

    @Override
    public ClassMetadata getClassMetadata(Class clazz) {
        return this.getHibernateSessionFactory().getClassMetadata(clazz);
    }

    @Override
    public ClassMetadata getClassMetadata(String classMetadata) {
        return this.getHibernateSessionFactory().getClassMetadata(classMetadata);
    }

    @Override
    public CollectionMetadata getCollectionMetadata(String collectionMetadata) {
        return this.getHibernateSessionFactory().getCollectionMetadata(collectionMetadata);
    }

    @Override
    public Session getCurrentSession() throws HibernateException {
        return this.getHibernateSessionFactory().getCurrentSession();
    }

    @Override
    public Set getDefinedFilterNames() {
        return this.getHibernateSessionFactory().getDefinedFilterNames();
    }

    @Override
    public FilterDefinition getFilterDefinition(String definition) throws HibernateException {
        return this.getHibernateSessionFactory().getFilterDefinition(definition);
    }

    @Override
    public Statistics getStatistics() {
        return this.getHibernateSessionFactory().getStatistics();
    }

    @Override
    public TypeHelper getTypeHelper() {
        return this.getHibernateSessionFactory().getTypeHelper();
    }

    @Override
    public boolean isClosed() {
        return this.getHibernateSessionFactory().isClosed();
    }

    @Override
    public Session openSession() throws HibernateException {
        return this.getHibernateSessionFactory().openSession();
    }

    @Override
    public Session openSession(Interceptor interceptor) throws HibernateException {
        return this.getHibernateSessionFactory().openSession(interceptor);
    }

    @Override
    public Session openSession(Connection connection) {
        return this.getHibernateSessionFactory().openSession(connection);
    }

    @Override
    public Session openSession(Connection connection, Interceptor interceptor) {
        return this.getHibernateSessionFactory().openSession(connection, interceptor);
    }

    @Override
    public StatelessSession openStatelessSession() {
        return this.getHibernateSessionFactory().openStatelessSession();
    }

    @Override
    public StatelessSession openStatelessSession(Connection connection) {
        return this.getHibernateSessionFactory().openStatelessSession(connection);
    }

    @Override
    public Reference getReference() throws NamingException {
        return this.getHibernateSessionFactory().getReference();
    }

    public void setTargetSessionFactorys(Map<Object, SessionFactory> targetSessionFactorys) {
        this.targetSessionFactorys = targetSessionFactorys;
    }

    public void setDefaultTargetSessionFactory(SessionFactory defaultTargetSessionFactory) {
        this.defaultTargetSessionFactory = defaultTargetSessionFactory;
    }

}

上面最重要的就是getHibernateSessionFactory重写这个方法,其他方法和原来实现的无异。重写这个方法后利用CustomerContextHolder动态设置SessionFactory类型就可以动态的切换SessionFactory。

3、动态的事务管理器,因为我们这里是动态切换SessionFactory,所以事务这块也需要动态切换SessionFactory来完成事务的操作。

package com.hoo.framework.spring.support.tx;

import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import com.hoo.framework.spring.support.core.DynamicSessionFactory;

/**
 * <b>function:</b> 重写HibernateTransactionManager事务管理器,实现自己的动态的事务管理器
 * @author hoojo
 * @createDate 2013-10-12 下午03:54:02
 * @file DynamicTransactionManager.java
 * @package com.hoo.framework.spring.support.tx
 * @project SHMB
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email hoojo_@126.com
 * @version 1.0
 */
public class DynamicTransactionManager extends HibernateTransactionManager {

    private static final long serialVersionUID = -4655721479296819154L;

    /** 
     * @see org.springframework.orm.hibernate4.HibernateTransactionManager#getDataSource()
     * <b>function:</b> 重写
     * @author hoojo
     * @createDate 2013-10-12 下午03:55:24
     */
    @Override
    public DataSource getDataSource() {
        return SessionFactoryUtils.getDataSource(getSessionFactory());
    }

    /** 
     * @see org.springframework.orm.hibernate4.HibernateTransactionManager#getSessionFactory()
     * <b>function:</b> 重写
     * @author hoojo
     * @createDate 2013-10-12 下午03:55:24
     */
    @Override
    public SessionFactory getSessionFactory() {
        DynamicSessionFactory dynamicSessionFactory = (DynamicSessionFactory) super.getSessionFactory();  
        SessionFactory hibernateSessionFactory = dynamicSessionFactory.getHibernateSessionFactory();  
        return hibernateSessionFactory;  
    }
}

这里主要重写getDataSource()/getSessionFactory()这两个方法,getSessionFactory方法是利用我们上面定义的接口来动态获取我们在上下文(CustomerContextHolder)中定义切换的SessionFactory对象。而getDataSource则是获得动态SessionFactory的DataSource,这里也不难理解。

4、至此,重写的接口和实现都完成,下面开始配置相关的代码

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd


http://www.springframework.org/schema/aop


http://www.springframework.org/schema/aop/spring-aop-3.2.xsd


http://www.springframework.org/schema/tx

    http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">

    <!-- 配置c3p0数据源 -->
    <bean id="dataSourceOracle" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${datasource.driver}"/>
        <property name="jdbcUrl" value="${datasource.url}"/>
        <property name="user" value="${datasource.username}"/>
        <property name="password" value="${datasource.password}"/>

        <property name="acquireIncrement" value="${c3p0.acquireIncrement}"/>
        <property name="initialPoolSize" value="${c3p0.initialPoolSize}"/>
        <property name="minPoolSize" value="${c3p0.minPoolSize}"/>
        <property name="maxPoolSize" value="${c3p0.maxPoolSize}"/>
        <property name="maxIdleTime" value="${c3p0.maxIdleTime}"/>
        <property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"/>
        <property name="maxStatements" value="${c3p0.maxStatements}"/>
        <property name="numHelperThreads" value="${c3p0.numHelperThreads}"/>
        <property name="preferredTestQuery" value="${c3p0.preferredTestQuery}"/>
        <property name="testConnectionOnCheckout" value="${c3p0.testConnectionOnCheckout}"/>
    </bean>

    <bean id="dataSourceMySQL" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://172.31.108.178:3306/world?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull"/>
        <property name="user" value="root"/>
        <property name="password" value="jp2011"/>

        <property name="acquireIncrement" value="${c3p0.acquireIncrement}"/>
        <property name="initialPoolSize" value="${c3p0.initialPoolSize}"/>
        <property name="minPoolSize" value="${c3p0.minPoolSize}"/>
        <property name="maxPoolSize" value="${c3p0.maxPoolSize}"/>
        <property name="maxIdleTime" value="${c3p0.maxIdleTime}"/>
        <property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"/>
        <property name="maxStatements" value="${c3p0.maxStatements}"/>
        <property name="numHelperThreads" value="${c3p0.numHelperThreads}"/>
        <property name="preferredTestQuery" value="${c3p0.preferredTestQuery}"/>
        <property name="testConnectionOnCheckout" value="${c3p0.testConnectionOnCheckout}"/>
    </bean>

    <!-- Annotation 配置sessionFactory,配置数据库连接,注入hibernate数据库配置 -->
    <bean id="mySQLSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSourceMySQL"/>
        <property name="packagesToScan" value="com.hoo.**.mysqlentity"/>
        <property name="annotatedClasses">
            <array>
                <value>com.hoo.common.entity.IDGenerator</value>
            </array>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <!-- 链接释放策略 on_close | after_transaction | after_statement | auto  -->
                <prop key="hibernate.connection.release_mode">after_transaction</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
    </bean>

    <!-- Annotation 配置sessionFactory,配置数据库连接,注入hibernate数据库配置 -->
    <bean id="oracleSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSourceOracle"/>
        <property name="packagesToScan" value="com.hoo.**.entity"/>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
                <prop key="hibernate.connection.release_mode">after_transaction</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <!--prop key="hibernate.hbm2ddl.auto">update</prop-->
            </props>
        </property>
    </bean>

    <!-- 动态SessionFactory -->
    <bean id="sessionFactory" class="com.hoo.framework.spring.support.core.DynamicSessionFactoryImpl">
        <property name="defaultTargetSessionFactory" ref="oracleSessionFactory"/>
        <property name="targetSessionFactorys">
            <map>     
                <entry value-ref="oracleSessionFactory" key="oracle"/>
                <entry value-ref="mySQLSessionFactory" key="mysql"/>
            </map> 
        </property>
    </bean>

    <!-- 自定义动态切换SessionFactory事务管理器,注入sessionFactory  -->
    <bean id="transactionManager" class="com.hoo.framework.spring.support.tx.DynamicTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- 配置事务的传播特性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
            <tx:method name="edit*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
            <tx:method name="remove*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
            <tx:method name="execute*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
            <tx:method name="*" read-only="true" />
        </tx:attributes>
    </tx:advice>

    <!-- 配置那些类、方法纳入到事务的管理 -->
    <aop:config>
        <aop:pointcut expression="execution(* com.hoo.**.service.impl.*.*(..))" id="transactionManagerMethod"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionManagerMethod" />
    </aop:config>
</beans>

配置也和我们之前的配置差不多,就是事务管理器部分注入的SessionFactory是我们自己定义的。

5、简单测试

@Test
public void testAdd() {
    // 主要就是这行代码 它才是完成SessionFactory的切换
    CustomerContextHolder.setCustomerType(CustomerContextHolder.SESSION_FACTORY_MYSQL);

    DeviceInfo entity = new DeviceInfo();
    entity.setSbbh(System.currentTimeMillis() + "");
    entity.setIpdz("my ip address2");
    entity.setJd(1234);
    try {
        service.add(entity);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

经过测试发现可以查询数据,利用hibernate查询分页也可以生成对应数据库的分页语句。同样在服务层的方法中添加完操作后,特意抛出一个异常,数据也能正常回滚操作,所以DynamicTransactionManager也是起到了该有的作用!

这里我的测试用例是手动切换CustomerContextHolder.setCustomerType的,但实际开发中我们还是得用Spring的Aop中的Interceptor进行切面编程,完成动态切换SessionFactory。上一篇文章Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法已经提到了(读者可以参考该篇博文中的第二节的3、7小节DataSourceMethodInterceptor MultipleDataSourceInterceptor),这里就不再赘述!

 

三、引发的问题

上述的实现如果在使用不当的情况下,在实际开发中很可能存在一些问题!

问题1是这样的,通常事务是在Service这层完成,这个应该是没有异议。倘若是这样的话,问题便出现了。而通常我们在MVC中的视图层中仅仅会调用Service中一个方法来完成所有当前业务的处理。如果这个Service中同时操作dbA、dbB两个数据库,事务提交的时候是用哪个数据库的事务呢?所以我们把不同数据库的操作放在一个方法,就会出现事务的问题的,除非两个数据库的事务能够同时回滚!

大致情景是:Service中的add4Oracle操作Oracle数据库,Service中的add4MySQL操作MySQL数据库,最后把Service中的add4Oracle、add4MySQL方法放到一个operation方法中,MVC视图层的业务控制调用Service中的operation。像这样的情况,如果add4Oracle或add4MySQL方法中的某一个方法出现异常,就需要把两个数据库事务都回滚。

解决办法就是在Service或Dao中的一个方法中同时操作两个数据库,手动完成事务控制。出现异常就全部回滚,没有异常就全部提交,只能这样牺牲下。

 

问题2是利用拦截器不能同时切换一个方法操作两个数据库的可能,例如一个service中的query方法即需要用query MySQL,也需要query Oracle。那么解决办法就是在query方法中调用当前service的query4Oracle和query4Oracle,那样绕过去还是能利用拦截器进行动态切换的。

 

四、总结

要完成数据库方言的切换,我们就需要配置多个SessionFactory利用自己实现的DynamicSessionFactory和CustomerContextHolder完成SessionFactory的切换。利用DynamicTransactionManager完成当前Session的事务操作。通过对这些对象的操作和配置,最终可以完成SessionFactory的动态切换。实际使用中虽然有些问题出现,但是最终还是有解决方案,尽管有些不完美。所谓的完美的东西总有它不完美的地方,这样才算完美,比如断臂的维纳斯女神~!


本文固定链接: http://www.devba.com/index.php/archives/3148.html | 开发吧

分享到:
评论

相关推荐

    java hibernate不同数据库之间的动态切换

    通过以上步骤,我们可以实现Java Hibernate应用中不同数据库之间的动态切换。这样不仅可以提高代码的可维护性和灵活性,还能满足多种环境下的部署需求。然而,这种方法可能会影响性能,因为每次切换数据库都需要重新...

    达梦数据库7.6最新的驱动包及hibernate方言包

    4. 创建SessionFactory,然后通过Session对象进行数据库操作。 通过以上介绍,我们可以看到这个压缩包提供了完整的工具,使Java开发者能够顺利地在项目中集成达梦数据库7.6,并利用Hibernate进行高效的数据访问。...

    使用 HibernateSessionFactory 类

    它通过读取`hibernate.cfg.xml`或`hibernate.properties`配置文件来初始化,这些文件定义了数据库连接参数、方言、缓存策略等。创建`SessionFactory`的基本步骤如下: 1. **配置文件**: 首先,我们需要一个配置文件...

    HibernateSessionFactory 代码

    总结,`HibernateSessionFactory`在Hibernate中扮演着关键角色,它管理数据库连接并为应用提供数据库操作的入口。通过`SessionFactory`,我们可以轻松地执行对数据库的增、删、查、改操作,极大地简化了传统SQL语句...

    Hibernate 符合JAVA习惯的关系数据库持久化.pdf

    通过提供一套API和元数据描述,Hibernate能够将Java类与数据库表进行映射,使得开发者可以避免编写大量的SQL代码,更加专注于业务逻辑的实现。 ### Hibernate基础 1. **对象关系映射(ORM)**:ORM是Hibernate的...

    HibernateSessionFactory.java

    HibernateSessionFactory.java

    Hibernate不同数据库的连接及SQL方言.pdf

    然而,与不同的数据库系统交互时,由于各个数据库的SQL语法和特性存在差异,Hibernate需要适配这些差异,这就涉及到了SQL方言(Dialect)的概念。 SQL方言是Hibernate为特定数据库系统提供的一个抽象层,它确保...

    hibernate连接金仓数据库所需jar包集合lib.7z

    在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者通过Java对象来操作数据库,极大地简化了数据库操作。金仓数据库,又称为Kingbase,是一款国产的高性能、高可靠性的关系型数据库管理...

    hibernate动态数据库进化版

    2. **多数据库支持**:为了适应不同的数据库,如MySQL、Oracle、SQL Server等,需要使用Hibernate的`Dialect`机制,动态选择合适的数据库方言。通过自定义`Dialect`类,可以实现特定数据库的特性,如存储过程、函数...

    国产达梦dialect方言jar包.rar

    在Java开发中,当使用诸如Hibernate、MyBatis等ORM(对象关系映射)框架时,需要指定数据库的方言,以便框架能够生成适应特定数据库的SQL语句。这个jar包包含了达梦数据库特有的SQL转换规则和函数实现,使得开发人员...

    hibernate框架下对oracle数据库操作所需jar包.zip

    Hibernate通过SessionFactory创建Session对象,Session是与数据库交互的接口。SessionFactory是一个线程安全的单例对象,用于创建Session实例。 7. **持久化操作** 使用Session对象,可以执行增删改查操作。例如...

    hibernate同时配置多个数据库连接

    - **实体类和数据库关联**:为每个数据库的实体类指定相应的`sessionFactory`,可以在实体类的注解`@Entity`中通过`@Table`的`schema`属性来区分数据库,或者在映射文件`hbm.xml`中设置`table`元素的`schema`属性。...

    hibernate根据字段生成数据库表

    - **跨数据库迁移**:当项目需要支持多种数据库时,可以通过修改配置文件轻松地在不同数据库之间切换,而无需修改业务代码。 - **快速开发测试环境**:对于快速搭建的测试环境,可以自动创建数据库表,节省时间。 - ...

    springboot集成hibernate

    通过以上步骤,我们就完成了Spring Boot与Hibernate的集成,且在DAO层使用SessionFactory进行数据库操作。这种方式允许我们充分利用Hibernate的灵活性,同时避免了JPA的一些限制。在实际项目中,根据需求选择适合的...

    spring配置sessionFactory(spring3.2.3+hibernate4.2.2)

    然后,创建Hibernate的配置文件(hibernate.cfg.xml),设置数据库连接信息、方言、缓存策略等。例如: ```xml &lt;hibernate-configuration&gt; &lt;property name="hibernate.dialect"&gt;org.hibernate.dialect.MySQL5...

Global site tag (gtag.js) - Google Analytics