让Hibernate自动识别数据库

1、问题背景

我们经常使用Spring+Hibernate的配置,但当Jndi连接的数据库发生变化时问题就来了,如Oracle与MySQL。

我们不得不为sessionFactory定义两个,一个oracleSessionFactory,一个mySqlSessionFactory

再用

<alias name="oracleSessionFactory" alias="sessionFactory" />

来切换sessionFactory,但还是要修改xml或properties

所以我想来做一个不需要修改代码,让Hibernate自动匹配数据库。

2、解决方法

对sessionFactory进行分析后发现主要是dialect不一样,所以我自己写了一个AutoDBAnnotationSessionFactoryBean类(因为我用注解所以是这个工厂类)

package org.noahx.hibernate;

import org.apache.ddlutils.PlatformUtils;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.Oracle10gDialect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * Created with IntelliJ IDEA.
 * User: noah
 * Date: 7/8/12
 * Time: 4:39 PM
 * <p/>
 * 自动根据数据库探测的类型修改dialect
 */
public class AutoDBAnnotationSessionFactoryBean extends AnnotationSessionFactoryBean {

    private static final String PROPERTY_NAME_DIALECT = "hibernate.dialect";

    private static final String ORACLE_TYPE = "Oracle";

    private static final String MYSQL_TYPE = "MySQL";

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private String dialect = null;

    @Override
    public void setDataSource(DataSource dataSource) {

        PlatformUtils platformUtils = new PlatformUtils();

        String dbType = platformUtils.determineDatabaseType(dataSource);

        logger.info("Database type is \"" + dbType + "\"");

        if (MYSQL_TYPE.equals(dbType)) {
            dialect = MySQLDialect.class.getName();
        } else if (ORACLE_TYPE.equals(dbType)) {
            dialect = Oracle10gDialect.class.getName();
        } else {
            logger.error("unknown database :" + dbType);
        }

        super.setDataSource(dataSource);
    }

    @Override
    public void setHibernateProperties(Properties hibernateProperties) {

        if (hibernateProperties.containsKey(PROPERTY_NAME_DIALECT)) {
            hibernateProperties.remove(hibernateProperties);
        }

        hibernateProperties.setProperty(PROPERTY_NAME_DIALECT, dialect);

        super.setHibernateProperties(hibernateProperties);
    }

}

做来一个很简单的判断,以后还可以再扩展。MySQL:MySQLDialect,Oracle:Oracle10gDialect。

spring xml中的内容为

    <bean id="sessionFactory" class="org.noahx.hibernate.AutoDBAnnotationSessionFactoryBean" lazy-init="false">

        <property name="dataSource" ref="dataSource"/>

        <property name="annotatedClasses">
            <list>
                <value>org.noahx.domain.Conference</value>
            </list>
        </property>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.hbm2ddl.auto" >update</prop>
                <prop key="hibernate.generate_statistics">false</prop>
                <prop key="hibernate.autoReconnect">true</prop>
                <prop key="hibernate.jdbc.batch_size">500</prop>
                <prop key="hibernate.connection.release_mode">auto</prop>
                <prop key="hibernate.cache.use_second_level_cache">false</prop>
                <!-- AutoDBAnnotationSessionFactoryBean 不需要设置hibernate.dialect-->
                <!--<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>-->
            </props>
        </property>
    </bean>

这样在改变数据库类型就不用修改代码或xml了

 

这里用到了一个ddlutils的一个工具类org.apache.ddlutils.PlatformUtils 来判断数据源的类型,在maven中加入ddlutils依赖

<dependency>
            <groupId>org.apache.ddlutils</groupId>
            <artifactId>ddlutils</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>commons-dbcp</artifactId>
                    <groupId>commons-dbcp</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>commons-digester</artifactId>
                    <groupId>commons-digester</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>commons-pool</artifactId>
                    <groupId>commons-pool</groupId>
                </exclusion>
                <exclusion>
                    <groupId>oro</groupId>
                    <artifactId>oro</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>commons-betwixt</groupId>
                    <artifactId>commons-betwixt</artifactId>
                </exclusion>
                <exclusion>
                    <artifactId>commons-beanutils</artifactId>
                    <groupId>commons-beanutils</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>commons-codec</artifactId>
                    <groupId>commons-codec</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>stax-api</artifactId>
                    <groupId>stax</groupId>
                </exclusion>
                <exclusion>
                    <groupId>commons-lang</groupId>
                    <artifactId>commons-lang</artifactId>
                </exclusion>
            </exclusions>
            <version>1.0</version>
        </dependency>

你可能感兴趣的:(Hibernate)