jef.database.DbClientBuilder.java Source code

Java tutorial

Introduction

Here is the source code for jef.database.DbClientBuilder.java

Source

/*
 * JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jef.database;

import java.io.File;
import java.sql.SQLException;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.easyframe.enterprise.spring.TransactionMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jef.codegen.EntityEnhancer;
import jef.common.log.LogUtil;
import jef.database.datasource.MapDataSourceLookup;
import jef.database.datasource.RoutingDataSource;
import jef.database.datasource.SimpleDataSource;
import jef.database.dialect.AbstractDialect;
import jef.database.dialect.DatabaseDialect;
import jef.database.jpa.JefEntityManagerFactory;
import jef.database.meta.MetaHolder;
import jef.database.support.DbInitHandler;
import jef.database.support.QuerableEntityScanner;
import jef.tools.JefConfiguration;

/**
 * ??DbClient
 * 
 * 
 */
public class DbClientBuilder {

    private Logger log = LoggerFactory.getLogger(DbClientBuilder.class);
    /**
     * ??? Spring?????
     * 
     * <pre>
     * <code>
     * &lt;property name="dataSources"&gt;
     *    &lt;map&gt;
     *     &lt;entry key="dsname1" value-ref="ds1" /&gt;
     *     &lt;entry key="dsname2" value-ref="ds2" /&gt;
     *    &lt;/map&gt;
     * &lt;/property&gt;
     * </code>
     * </pre>
     */
    private Map<String, DataSource> dataSources;

    /**
     * ???
     */
    protected DataSource dataSource;

    /**
     * ???????
     */
    private String defaultDatasource;

    /**
     * 
     */
    private int maxPoolSize = JefConfiguration.getInt(DbCfg.DB_CONNECTION_POOL_MAX, 50);

    /**
     * ?
     */
    private int minPoolSize = JefConfiguration.getInt(DbCfg.DB_CONNECTION_POOL, 3);

    /**
     * ??
     */
    private String namedQueryFile;

    /**
     * ??
     */
    private String namedQueryTable;

    /**
     * ?
     * 
     * @see #setTransactionMode(String)
     */
    private TransactionMode transactionMode;

    /**
     * ??????<br>
     * ??packagesToScan<br>
     * ??????"none"
     * 
     * @deprecated
     */
    private String enhancePackages = "none";

    /**
     * ??,? <code><pre>
     * &lt;list&gt;
     *  &lt;value&gt;org.easyframe.test&lt;/value&gt;
     *  &lt;value&gt;org.easyframe.entity&lt;/value&gt;
     * &lt;/list&gt;
     * </pre></code>
     */
    private String[] packagesToScan;

    /**
     * ????
     */
    private boolean enhanceScanPackages = true;

    /**
     * ??? <code><pre>
     * &lt;list&gt;
     *  &lt;value&gt;org.easyframe.testp.jta.Product&lt;/value&gt;
     *  &lt;value&gt;org.easyframe.testp.jta.Users&lt;/value&gt;
     * &lt;/list&gt;
     * </pre></code>
     */
    private String[] annotatedClasses;

    /**
     * ?????????
     */
    private String dynamicTables;

    /**
     * ???
     */
    private boolean registeNonMappingTableAsDynamic;

    /**
     * ?????? <br>
     * ?
     */
    private boolean createTable = true;

    /**
     * ????? <br>
     * ?
     */
    private boolean alterTable = true;

    /**
     * ?????? <br>
     * 
     */
    private boolean allowDropColumn;

    /**
     * ???
     * 
     * @see DbInitHandler
     */
    private String dbInitHandler;
    /**
     * ????
     * <p>
     * ?class?? <i>class-name</i>.txt??
     * ?????
     */
    private boolean initData;

    /**
     * ???
     */
    private boolean useDataInitTable = JefConfiguration.getBoolean(DbCfg.USE_DATAINIT_FLAG_TABLE, false);;

    /**
     * ???
     */
    private String initDataCharset = "UTF-8";

    /**
     * ????
     */
    private String initDataExtension = JefConfiguration.get(DbCfg.INIT_DATA_EXTENSION, "txt");

    /**
     *  ??
     */
    private String initDataRoot = JefConfiguration.get(DbCfg.INIT_DATA_ROOT, "/");

    /**
     * ?
     */
    protected JefEntityManagerFactory instance;

    /**
     * 
     */
    public DbClientBuilder() {
    }

    /**
     * 
     * 
     * @param jdbcURL
     * @param user
     * @param password
     * @param maxPool
     */
    public DbClientBuilder(String jdbcURL, String user, String password, int maxPool) {
        this.dataSource = DbUtils.createSimpleDataSource(jdbcURL, user, password);
        this.maxPoolSize = maxPool;
    }

    /**
     * ???
     * 
     * @param dbType
     * @param host
     * @param port
     * @param pathOrName
     * @param user
     * @param password
     * @return
     */
    public DbClientBuilder(String dbType, String host, int port, String pathOrName, String user, String password) {
        DatabaseDialect profile = AbstractDialect.getDialect(dbType);
        if (profile == null) {
            throw new IllegalArgumentException("The DBMS:[" + dbType + "] is not supported yet.");
        }
        String dbURL = profile.generateUrl(host, port, pathOrName);
        this.dataSource = DbUtils.createSimpleDataSource(dbURL, user, password);
    }

    /**
     * ?
     * 
     * @param dbName
     *            ???
     * @param user
     *            
     * @param pass
     *            ?
     * @return
     * @throws SQLException
     */
    public DbClientBuilder(String dbType, File dbFolder, String user, String password) {
        int port = JefConfiguration.getInt(DbCfg.DB_PORT, 0);
        String host = JefConfiguration.get(DbCfg.DB_HOST, "");
        DatabaseDialect profile = AbstractDialect.getDialect(dbType);
        if (profile == null) {
            throw new IllegalArgumentException("The DBMS:[" + dbType + "] is not supported yet.");
        }
        String dbURL = profile.generateUrl(host, port, dbFolder.getAbsolutePath());
        this.dataSource = DbUtils.createSimpleDataSource(dbURL, user, password);
    }

    /**
     * ?JDBC???
     * 
     * @param jdbcUrl
     * @param user
     * @param password
     * @throws SQLException
     */
    public DbClientBuilder(String jdbcUrl, String user, String password) {
        this.setDataSource(DbUtils.createSimpleDataSource(jdbcUrl, user, password));
    }

    /**
     * ?DbClient
     * 
     * @return DbClient
     * @see DbClient
     */
    public DbClient build() {
        if (instance == null) {
            instance = buildSessionFactory();
        }
        return instance.getDefault();
    }

    /**
     * ??
     * 
     * @return ?
     * @see TransactionMode
     */
    public String getTransactionMode() {
        return transactionMode == null ? null : transactionMode.name();
    }

    /**
     * ????
     * <ul>
     * <li><strong>JPA</strong></li><br>
     * JPA??Spring
     * {@linkplain org.springframework.orm.jpa.JpaTransactionManager
     * JpaTransactionManager}, ef-orm??
     * <li><strong>JTA</strong></li><br>
     * JTA??JTA??????JMS??<br>
     * ??atomikosJTA? Spring
     * {@linkplain org.springframework.transaction.jta.JtaTransactionManager
     * JtaTransactionManager}<br>
     * ????
     * <li><strong>JDBC</strong></li><br>
     * JDBC?Hibernate?HibernateHibernate
     * JdbcTemplate? ?DataSourceJDBC Spring
     * {@linkplain org.springframework.orm.hibernate3.HibernateTransactionManager
     * HibernateTransactionManager} 
     * {@linkplain org.springframework.jdbc.datasource.DataSourceTransactionManager
     * DataSourceTransactionManager}
     * Hibernate/Ibatis/MyBatis/JdbcTemplate?
     * </ul>
     * {@code JPA}
     * 
     * @param txType
     *            ???JPA?JTA?JDBC
     * 
     * @see TransactionMode
     */
    public DbClientBuilder setTransactionMode(TransactionMode txType) {
        this.transactionMode = txType;
        return this;
    }

    /**
     * 0??
     * 
     * @param maxConnection
     * @return
     */
    public DbClientBuilder setMaxPoolSize(int maxConnection) {
        this.maxPoolSize = maxConnection;
        return this;
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    /**
     * ??
     * 
     * @param dataSource
     *            ??
     */
    public DbClientBuilder setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
        return this;
    }

    /**
     * ??
     * 
     * @param url
     * @param user
     * @param password
     * @return
     */
    public DbClientBuilder setDataSource(String url, String user, String password) {
        this.dataSource = new SimpleDataSource(url, user, password);
        return this;
    }

    /**
     * ???
     * 
     * @return ????
     */
    public DbClientBuilder setPackagesToScan(String[] scanPackages) {
        this.packagesToScan = scanPackages;
        return this;
    }

    /**
     * 
     * @return
     */
    public boolean isAlterTable() {
        return alterTable;
    }

    /**
     * ???????
     * 
     * @param alterTable
     *            'true' , EF-ORM will alter tables in database.
     */
    public DbClientBuilder setAlterTable(boolean alterTable) {
        this.alterTable = alterTable;
        return this;
    }

    /**
     * ?
     * 
     * @param debug
     * @return
     */
    public DbClientBuilder setDebug(boolean debug) {
        ORMConfig.getInstance().setDebugMode(debug);
        return this;
    }

    /**
     * ??
     * 
     * @return
     */
    public boolean isDebug() {
        return ORMConfig.getInstance().isDebugMode();
    }

    /**
     * ?
     * 
     * @return
     */
    public boolean isCreateTable() {
        return createTable;
    }

    /**
     * ??????
     * 
     * @param createTable
     *            true
     */
    public DbClientBuilder setCreateTable(boolean createTable) {
        this.createTable = createTable;
        return this;
    }

    public boolean isAllowDropColumn() {
        return allowDropColumn;
    }

    /**
     * ????
     * 
     * @param dynamicTables
     *            ???
     */
    public DbClientBuilder setDynamicTables(String dynamicTables) {
        this.dynamicTables = dynamicTables;
        return this;
    }

    public boolean isRegisteNonMappingTableAsDynamic() {
        return registeNonMappingTableAsDynamic;
    }

    public String[] getAnnotatedClasses() {
        return annotatedClasses;
    }

    /**
     * ???
     * 
     * <pre>
     * <code>
     * &lt;list&gt;
     *  &lt;value&gt;org.easyframe.testp.jta.Product&lt;/value&gt;
     *  &lt;value&gt;org.easyframe.testp.jta.Users&lt;/value&gt;
     * &lt;/list&gt;
     * </code>
     * </pre>
     */
    public DbClientBuilder setAnnotatedClasses(String[] annotatedClasses) {
        this.annotatedClasses = annotatedClasses;
        return this;
    }

    public String[] getPackagesToScan() {
        return packagesToScan;
    }

    public boolean isInitData() {
        return initData;
    }

    public DbClientBuilder setInitData(boolean initData) {
        this.initData = initData;
        return this;
    }

    public void setMinPoolSize(int minPoolSize) {
        this.minPoolSize = minPoolSize;
    }

    /**
     * ????schema?
     * 
     * @param registeNonMappingTableAsDynamic
     */
    public DbClientBuilder setRegisteNonMappingTableAsDynamic(boolean registeNonMappingTableAsDynamic) {
        this.registeNonMappingTableAsDynamic = registeNonMappingTableAsDynamic;
        return this;
    }

    public Map<String, DataSource> getDataSources() {
        return dataSources;
    }

    public String getDefaultDatasource() {
        return defaultDatasource;
    }

    /**
     * ???????
     * 
     * @param defaultDatasource
     *            name of the datasource.
     */
    public DbClientBuilder setDefaultDatasource(String defaultDatasource) {
        this.defaultDatasource = defaultDatasource;
        return this;
    }

    /**
     * ??? Spring?????
     * 
     * <pre>
     * <code>
     * &lt;property name="dataSources"&gt;
     *    &lt;map&gt;
     *     &lt;entry key="dsname1" value-ref="ds1" /&gt;
     *     &lt;entry key="dsname2" value-ref="ds2" /&gt;
     *    &lt;/map&gt;
     * &lt;/property&gt;
     * </code>
     * </pre>
     */
    public DbClientBuilder setDataSources(Map<String, DataSource> datasources) {
        this.dataSources = datasources;
        return this;
    }

    /**
     * ?????xml?classpath
     * 
     * @param namedQueryFile
     *            ????
     */
    public DbClientBuilder setNamedQueryFile(String namedQueryFile) {
        this.namedQueryFile = namedQueryFile;
        return this;
    }

    public String getNamedQueryTable() {
        return namedQueryTable;
    }

    /**
     * ?????
     * 
     * @param namedQueryTable
     *            ???
     */
    public DbClientBuilder setNamedQueryTable(String namedQueryTable) {
        this.namedQueryTable = namedQueryTable;
        return this;
    }

    /**
     * ???Alter???
     * 
     * @param allowDropColumn
     *            true?
     */
    public DbClientBuilder setAllowDropColumn(boolean allowDropColumn) {
        this.allowDropColumn = allowDropColumn;
        return this;
    }

    public String getEnhancePackages() {
        return enhancePackages;
    }

    /**
     * ? ?classjarclass
     * 
     * @deprecated 1.12??instrument??????
     * @param enhancePackages
     *            ???
     */
    public DbClientBuilder setEnhancePackages(String enhancePackages) {
        this.enhancePackages = enhancePackages;
        return this;
    }

    public String getDynamicTables() {
        return dynamicTables;
    }

    public String getNamedQueryFile() {
        return namedQueryFile;
    }

    protected JefEntityManagerFactory buildSessionFactory() {
        if (instance != null)
            return instance;

        // try enahcen entity if theres 'enhancePackages'.
        if (enhancePackages != null) {
            if (!enhancePackages.equalsIgnoreCase("none")) {
                new EntityEnhancer().enhance(StringUtils.split(enhancePackages, ","));
            }
        }
        if (enhanceScanPackages && ArrayUtils.isNotEmpty(this.packagesToScan)) {
            new EntityEnhancer().enhance(packagesToScan);
        } else if (enhanceScanPackages) {
            log.warn("EnhanceScanPackages flag was set to true. but property 'packagesToScan' was not assigned");
        }
        JefEntityManagerFactory sf;
        // check data sources.
        if (dataSource == null && dataSources == null) {
            LogUtil.info("No datasource found. Using default datasource in jef.properties.");
            sf = new JefEntityManagerFactory(null, minPoolSize, maxPoolSize, transactionMode);
        } else if (dataSource != null) {
            sf = new JefEntityManagerFactory(dataSource, minPoolSize, maxPoolSize, transactionMode);
        } else {
            RoutingDataSource rs = new RoutingDataSource(
                    new MapDataSourceLookup(dataSources).setDefaultKey(this.defaultDatasource));
            sf = new JefEntityManagerFactory(rs, minPoolSize, maxPoolSize, transactionMode);
        }
        if (namedQueryFile != null) {
            sf.getDefault().setNamedQueryFilename(namedQueryFile);
        }
        if (namedQueryTable != null) {
            sf.getDefault().setNamedQueryTablename(namedQueryTable);
        }

        if (packagesToScan != null || annotatedClasses != null) {
            QuerableEntityScanner qe = new QuerableEntityScanner();
            if (transactionMode == TransactionMode.JTA) {
                // JTADDL????JTA
                qe.setCheckSequence(false);
            }
            qe.setImplClasses(DataObject.class);
            qe.setAllowDropColumn(allowDropColumn);
            qe.setAlterTable(alterTable);
            qe.setCreateTable(createTable);

            qe.setInitData(this.initData);
            qe.setEntityManagerFactory(sf, this.useDataInitTable, this.initDataCharset, this.initDataExtension,
                    this.initDataRoot);
            if (annotatedClasses != null)
                qe.registeEntity(annotatedClasses);
            if (packagesToScan != null) {
                String joined = StringUtils.join(packagesToScan, ',');
                qe.setPackageNames(joined);
                LogUtil.info("Starting scan easyframe entity from package: {}", joined);
                qe.doScan();
            }
            qe.finish();
        }
        if (dynamicTables != null) {
            DbClient client = sf.getDefault();
            for (String s : StringUtils.split(dynamicTables, ",")) {
                String table = s.trim();
                registe(client, table);
            }
        }
        if (registeNonMappingTableAsDynamic) {
            DbClient client = sf.getDefault();
            try {
                for (String tableName : client.getMetaData(null).getTableNames()) {
                    if (MetaHolder.lookup(null, tableName) != null) {
                        registe(client, tableName);
                    }
                }
            } catch (SQLException e) {
                LogUtil.exception(e);
            }

        }
        // ??
        if (StringUtils.isNotBlank(this.dbInitHandler)) {
            for (String clzName : StringUtils.split(dbInitHandler, ',')) {
                try {
                    Object initType = Class.forName(clzName).newInstance();
                    if (initType instanceof DbInitHandler) {
                        ((DbInitHandler) initType).doDatabaseInit(sf.getDefault());
                    }
                } catch (ClassNotFoundException e) {
                    LogUtil.error("InitClass load failure: class not found - " + e.getMessage());
                } catch (InstantiationException e) {
                    LogUtil.error("InitClass load failure - ", e);
                } catch (IllegalAccessException e) {
                    LogUtil.error("InitClass load failure - ", e);
                }
            }
        }
        return sf;
    }

    private void registe(DbClient client, String table) {
        if (MetaHolder.getDynamicMeta(table) == null) {
            try {
                MetaHolder.initMetadata(client, table);
                LogUtil.show("DynamicEntity: [" + table + "] registed.");
            } catch (SQLException e) {
                LogUtil.exception(e);
            }
        }
    }

    public boolean isCacheDebug() {
        return ORMConfig.getInstance().isCacheDebug();
    }

    public DbClientBuilder setCacheDebug(boolean cacheDebug) {
        ORMConfig.getInstance().setCacheDebug(cacheDebug);
        return this;
    }

    public boolean isCacheLevel1() {
        return ORMConfig.getInstance().isCacheLevel1();
    }

    /**
     * 
     * @param cache
     * @return this
     * @see DbCfg#CACHE_LEVEL_1
     */
    public DbClientBuilder setCacheLevel1(boolean cache) {
        ORMConfig.getInstance().setCacheLevel1(cache);
        return this;
    }

    /**
     * ?? ??????
     * 
     * @return 
     * @see DbCfg#CACHE_GLOBAL_EXPIRE_TIME
     */
    public int getGlobalCacheLiveTime() {
        return ORMConfig.getInstance().getCacheLevel2();
    }

    /**
     * ?? ??????
     * 
     * @param second
     * @return this
     * @see DbCfg#CACHE_GLOBAL_EXPIRE_TIME
     */
    public DbClientBuilder setGlobalCacheLiveTime(int second) {
        ORMConfig.getInstance().setCacheLevel2(second);
        return this;
    }

    public DbClientBuilder setUseSystemOut(boolean flag) {
        LogUtil.useSlf4j = !flag;
        return this;
    }

    /**
     * ????? ?? allow_data_initialize
     * do_init0???? 1???
     * 
     * @return whether use the datainit table or not.
     */
    public boolean isUseDataInitTable() {
        return useDataInitTable;
    }

    /**
     * ????? ?? allow_data_initialize
     * do_init0???? 1???
     * 
     * @param useDataInitTable
     *            whether use the datainit table or not.
     * @return this
     */
    public DbClientBuilder setUseDataInitTable(boolean useDataInitTable) {
        this.useDataInitTable = useDataInitTable;
        return this;
    }

    public static DbClientBuilder newBuilder() {
        return new DbClientBuilder();
    }

    public String getInitDataCharset() {
        return initDataCharset;
    }

    public DbClientBuilder setInitDataCharset(String initDataCharset) {
        this.initDataCharset = initDataCharset;
        return this;
    }

    public String getDbInitHandler() {
        return dbInitHandler;
    }

    public void setDbInitHandler(String dbInitHandler) {
        this.dbInitHandler = dbInitHandler;
    }

    public boolean isEnhanceScanPackages() {
        return enhanceScanPackages;
    }

    public DbClientBuilder setEnhanceScanPackages(boolean enhanceScanPackages) {
        this.enhanceScanPackages = enhanceScanPackages;
        return this;
    }

    public String getInitDataExtension() {
        return initDataExtension;
    }

    public DbClientBuilder setInitDataExtension(String initDataExtension) {
        this.initDataExtension = initDataExtension;
        return this;
    }

    public String getInitDataRoot() {
        return initDataRoot;
    }

    public DbClientBuilder setInitDataRoot(String initDataRoot) {
        this.initDataRoot = initDataRoot;
        return this;
    }

}