/**
* Copyright (c) 2011-2014, hubin (jobob@qq.com).
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 com.baomidou.mybatisplus.entity;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
import javax.sql.DataSource;
import com.baomidou.mybatisplus.mapper.IKeyGenerator;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.baomidou.mybatisplus.MybatisSqlSessionTemplate;
import com.baomidou.mybatisplus.enums.DBType;
import com.baomidou.mybatisplus.enums.FieldStrategy;
import com.baomidou.mybatisplus.enums.IdType;
import com.baomidou.mybatisplus.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.mapper.AutoSqlInjector;
import com.baomidou.mybatisplus.mapper.ISqlInjector;
import com.baomidou.mybatisplus.mapper.MetaObjectHandler;
import com.baomidou.mybatisplus.toolkit.IOUtils;
import com.baomidou.mybatisplus.toolkit.JdbcUtils;
import com.baomidou.mybatisplus.toolkit.SqlReservedWords;
import com.baomidou.mybatisplus.toolkit.StringUtils;
import com.baomidou.mybatisplus.toolkit.TableInfoHelper;
/**
* <p>
* Mybatis全局缓存
* </p>
*
* @author Caratacus
* @since 2016-12-06
*/
public class GlobalConfiguration implements Cloneable {
/**
* 默认参数
*/
public static final GlobalConfiguration DEFAULT = new GlobalConfiguration();
// 日志
private static final Log logger = LogFactory.getLog(GlobalConfiguration.class);
/**
* 缓存全局信息
*/
private static final Map<String, GlobalConfiguration> GLOBAL_CONFIG = new ConcurrentHashMap<>();
// 逻辑删除全局值
private String logicDeleteValue = null;
// 逻辑未删除全局值
private String logicNotDeleteValue = null;
// 数据库类型(默认 MySql)
private DBType dbType = DBType.MYSQL;
// 主键类型(默认 ID_WORKER)
private IdType idType = IdType.ID_WORKER;
// 表名、字段名、是否使用下划线命名(默认 false)
private boolean dbColumnUnderline = false;
// SQL注入器
private ISqlInjector sqlInjector;
// 表关键词 key 生成器
private IKeyGenerator keyGenerator;
// 元对象字段填充控制器
private MetaObjectHandler metaObjectHandler = new DefaultMetaObjectHandler();
// 字段验证策略
private FieldStrategy fieldStrategy = FieldStrategy.NOT_NULL;
// 是否刷新mapper
private boolean isRefresh = false;
// 是否自动获取DBType
private boolean isAutoSetDbType = true;
// 是否大写命名
private boolean isCapitalMode = false;
// 标识符
private String identifierQuote;
// 缓存当前Configuration的SqlSessionFactory
private SqlSessionFactory sqlSessionFactory;
// 缓存已注入CRUD的Mapper信息
private Set<String> mapperRegistryCache = new ConcurrentSkipListSet<>();
// 单例重用SqlSession
private SqlSession sqlSession;
public GlobalConfiguration() {
// 构造方法
}
public GlobalConfiguration(ISqlInjector sqlInjector) {
this.sqlInjector = sqlInjector;
}
/**
* 获取当前的SqlSessionFactory
*
* @param clazz
* @return
*/
public static SqlSessionFactory currentSessionFactory(Class<?> clazz) {
String configMark = TableInfoHelper.getTableInfo(clazz).getConfigMark();
GlobalConfiguration mybatisGlobalConfig = GlobalConfiguration.getGlobalConfig(configMark);
return mybatisGlobalConfig.getSqlSessionFactory();
}
/**
* 获取默认MybatisGlobalConfig
*
* @return
*/
public static GlobalConfiguration defaults() {
try {
GlobalConfiguration clone = DEFAULT.clone();
clone.setSqlInjector(new AutoSqlInjector());
return clone;
} catch (CloneNotSupportedException e) {
throw new MybatisPlusException("ERROR: CLONE MybatisGlobalConfig DEFAULT FAIL ! Cause:" + e);
}
}
/**
* <p>
* 设置全局设置(以configuration地址值作为Key)
* <p/>
*
* @param configuration
* @param mybatisGlobalConfig
* @return
*/
public static void setGlobalConfig(Configuration configuration, GlobalConfiguration mybatisGlobalConfig) {
if (configuration == null || mybatisGlobalConfig == null) {
throw new MybatisPlusException("Error: Could not setGlobalConfig");
}
// 设置全局设置
GLOBAL_CONFIG.put(configuration.toString(), mybatisGlobalConfig);
}
/**
* 获取MybatisGlobalConfig (统一所有入口)
*
* @param configuration
* @return
*/
public static GlobalConfiguration getGlobalConfig(Configuration configuration) {
if (configuration == null) {
throw new MybatisPlusException("Error: You need Initialize MybatisConfiguration !");
}
return getGlobalConfig(configuration.toString());
}
/**
* 获取MybatisGlobalConfig (统一所有入口)
*
* @param configMark
* @return
*/
public static GlobalConfiguration getGlobalConfig(String configMark) {
GlobalConfiguration cache = GLOBAL_CONFIG.get(configMark);
if (cache == null) {
// 没有获取全局配置初始全局配置
logger.debug("DeBug: MyBatis Plus Global configuration Initializing !");
GLOBAL_CONFIG.put(configMark, DEFAULT);
return DEFAULT;
}
return cache;
}
public static DBType getDbType(Configuration configuration) {
return getGlobalConfig(configuration).getDbType();
}
public static IKeyGenerator getKeyGenerator(Configuration configuration) {
return getGlobalConfig(configuration).getKeyGenerator();
}
public static IdType getIdType(Configuration configuration) {
return getGlobalConfig(configuration).getIdType();
}
public static boolean isDbColumnUnderline(Configuration configuration) {
return getGlobalConfig(configuration).isDbColumnUnderline();
}
public static ISqlInjector getSqlInjector(Configuration configuration) {
// fix #140
GlobalConfiguration globalConfiguration = getGlobalConfig(configuration);
ISqlInjector sqlInjector = globalConfiguration.getSqlInjector();
if (sqlInjector == null) {
sqlInjector = new AutoSqlInjector();
globalConfiguration.setSqlInjector(sqlInjector);
}
return sqlInjector;
}
public IKeyGenerator getKeyGenerator() {
return keyGenerator;
}
public void setKeyGenerator(IKeyGenerator keyGenerator) {
this.keyGenerator = keyGenerator;
}
public static MetaObjectHandler getMetaObjectHandler(Configuration configuration) {
return getGlobalConfig(configuration).getMetaObjectHandler();
}
public static FieldStrategy getFieldStrategy(Configuration configuration) {
return getGlobalConfig(configuration).getFieldStrategy();
}
public static boolean isRefresh(Configuration configuration) {
return getGlobalConfig(configuration).isRefresh();
}
public static boolean isAutoSetDbType(Configuration configuration) {
return getGlobalConfig(configuration).isAutoSetDbType();
}
public static Set<String> getMapperRegistryCache(Configuration configuration) {
return getGlobalConfig(configuration).getMapperRegistryCache();
}
public static String getIdentifierQuote(Configuration configuration) {
return getGlobalConfig(configuration).getIdentifierQuote();
}
public static SqlSession getSqlSession(Configuration configuration) {
return getGlobalConfig(configuration).getSqlSession();
}
/**
* 设置元数据相关属性
*
* @param dataSource
* @param globalConfig
*/
public static void setMetaData(DataSource dataSource, GlobalConfiguration globalConfig) {
Connection connection = null;
try {
connection = dataSource.getConnection();
String jdbcUrl = connection.getMetaData().getURL();
// 设置全局关键字
globalConfig.setSqlKeywords(connection.getMetaData().getSQLKeywords());
// 自动设置数据库类型
if (globalConfig.isAutoSetDbType()) {
globalConfig.setDbTypeByJdbcUrl(jdbcUrl);
}
} catch (SQLException e) {
logger.warn("Warn: GlobalConfiguration setMetaData Fail ! Cause:" + e);
} finally {
IOUtils.closeQuietly(connection);
}
}
public String getLogicDeleteValue() {
return logicDeleteValue;
}
public void setLogicDeleteValue(String logicDeleteValue) {
this.logicDeleteValue = logicDeleteValue;
}
public String getLogicNotDeleteValue() {
return logicNotDeleteValue;
}
public void setLogicNotDeleteValue(String logicNotDeleteValue) {
this.logicNotDeleteValue = logicNotDeleteValue;
}
public DBType getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = DBType.getDBType(dbType);
this.isAutoSetDbType = false;
}
public void setDbTypeByJdbcUrl(String jdbcUrl) {
this.dbType = JdbcUtils.getDbType(jdbcUrl);
}
public IdType getIdType() {
return idType;
}
public void setIdType(int idType) {
this.idType = IdType.getIdType(idType);
}
public boolean isDbColumnUnderline() {
return dbColumnUnderline;
}
public void setDbColumnUnderline(boolean dbColumnUnderline) {
this.dbColumnUnderline = dbColumnUnderline;
}
public ISqlInjector getSqlInjector() {
return sqlInjector;
}
public void setSqlInjector(ISqlInjector sqlInjector) {
this.sqlInjector = sqlInjector;
}
public MetaObjectHandler getMetaObjectHandler() {
return metaObjectHandler;
}
public void setMetaObjectHandler(MetaObjectHandler metaObjectHandler) {
this.metaObjectHandler = metaObjectHandler;
}
public FieldStrategy getFieldStrategy() {
return fieldStrategy;
}
public void setFieldStrategy(int fieldStrategy) {
this.fieldStrategy = FieldStrategy.getFieldStrategy(fieldStrategy);
}
public boolean isRefresh() {
return isRefresh;
}
public void setRefresh(boolean refresh) {
this.isRefresh = refresh;
}
public boolean isAutoSetDbType() {
return isAutoSetDbType;
}
public void setAutoSetDbType(boolean autoSetDbType) {
this.isAutoSetDbType = autoSetDbType;
}
public Set<String> getMapperRegistryCache() {
return mapperRegistryCache;
}
public void setMapperRegistryCache(Set<String> mapperRegistryCache) {
this.mapperRegistryCache = mapperRegistryCache;
}
public SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
this.sqlSession = new MybatisSqlSessionTemplate(sqlSessionFactory);
}
public boolean isCapitalMode() {
return isCapitalMode;
}
public void setCapitalMode(boolean isCapitalMode) {
this.isCapitalMode = isCapitalMode;
}
public String getIdentifierQuote() {
if (null == identifierQuote) {
return dbType.getQuote();
}
return identifierQuote;
}
public void setIdentifierQuote(String identifierQuote) {
this.identifierQuote = identifierQuote;
}
public void setSqlKeywords(String sqlKeywords) {
if (StringUtils.isNotEmpty(sqlKeywords)) {
SqlReservedWords.RESERVED_WORDS.addAll(StringUtils.splitWorker(sqlKeywords.toUpperCase(), ",", -1, false));
}
}
public SqlSession getSqlSession() {
return sqlSession;
}
@Override
protected GlobalConfiguration clone() throws CloneNotSupportedException {
return (GlobalConfiguration) super.clone();
}
/**
* <p>
* 标记全局设置 (统一所有入口)
* </p>
*
* @param sqlSessionFactory
* @return
*/
public SqlSessionFactory signGlobalConfig(SqlSessionFactory sqlSessionFactory) {
if (null != sqlSessionFactory) {
setGlobalConfig(sqlSessionFactory.getConfiguration(), this);
}
return sqlSessionFactory;
}
}