Hibernate가 데이터베이스를 자동으로 인식

6542 단어 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는 데이터 원본의 유형을 판단하고 마ven에 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>

좋은 웹페이지 즐겨찾기