All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.featherfly.component.sorm.mapping.ClassMapping Maven / Gradle / Ivy

There is a newer version: 1.3.9
Show newest version
package cn.featherfly.component.sorm.mapping;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Id;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.featherfly.common.bean.BeanDescriptor;
import cn.featherfly.common.bean.BeanProperty;
import cn.featherfly.common.bean.matcher.BeanPropertyAnnotationMatcher;
import cn.featherfly.common.bean.matcher.BeanPropertyNameRegexMatcher;
import cn.featherfly.common.constant.Chars;
import cn.featherfly.common.db.metadata.ColumnMetadata;
import cn.featherfly.common.db.metadata.DatabaseMetadata;
import cn.featherfly.common.db.metadata.TableMetadata;
import cn.featherfly.common.enums.Logic;
import cn.featherfly.common.lang.LangUtils;
import cn.featherfly.common.lang.ServiceLoaderUtils;
import cn.featherfly.common.lang.StringUtils;
import cn.featherfly.common.lang.SystemPropertyUtils;
import cn.featherfly.common.lang.WordUtils;
import cn.featherfly.component.sorm.SimpleORMException;
import cn.featherfly.component.sorm.annotation.Column;
import cn.featherfly.component.sorm.annotation.Identity;

/**
 * 

* 类映射 *

* @param 类型 * @author 钟冀 * @since 1.0 * @version 1.0 */ public class ClassMapping { private static final Logger LOGGER = LoggerFactory.getLogger(ClassMapping.class); private static final char UNDER_LINE = '_'; private static final Map, ClassMapping> MAPPED_CLASS = new HashMap, ClassMapping>(); private static final List TABLE_NAME_FACTORIES; // private static final List COLUMN_NAME_FACTORIES; static { TABLE_NAME_FACTORIES = ServiceLoaderUtils.loadAll(ClassTableNameFactory.class); TABLE_NAME_FACTORIES.add(new ClassTableNameJpaFactory()); TABLE_NAME_FACTORIES.add(new ClassTableNameSormAnnotationFactory()); TABLE_NAME_FACTORIES.add(new ClassTableNameSormNameMapFactory()); // COLUMN_NAME_FACTORIES = ServiceLoaderUtils.loadAll(PropertyColumnNameFactory.class); } /** * * @param type 类型 * @param tableName 表名 */ public ClassMapping(Class type, String tableName) { this.type = type; this.tableName = tableName; } /** *

* 返回指定属性名称的属性映射. * 没有找到返回null. *

* @param propertyName 属性名称 * @return 属性映射对象 */ public PropertyMapping getPropertyMapping(String propertyName) { return propertyMappings.get(propertyName); } /** *

* 返回所有属性映射 *

* @return 所有属性映射 */ public Collection getPropertyMappings() { return propertyMappings.values(); } // ******************************************************************** // // ******************************************************************** /** * 返回指定类型的描述 * @param 类型 * @param type 类型 * @param meta 数据库元数据 * @return 指定类型的描述 */ public static ClassMapping getMappedClass(Class type, DatabaseMetadata meta) { @SuppressWarnings("unchecked") ClassMapping cm = (ClassMapping) MAPPED_CLASS.get(type); if (cm == null) { Map tableMapping = new HashMap(); StringBuilder logInfo = new StringBuilder(); // // 从对象中读取有Column的列,找到显示映射,使用scan扫描 BeanDescriptor bd = BeanDescriptor.getBeanDescriptor(type); String tableName = getTableName(type); tableName = tableName.toUpperCase(); logInfo.append(String.format("###%s类%s映射到表%s", SystemPropertyUtils.getLineSeparator(), type.getName(), tableName)); Collection> bps = bd.findBeanPropertys( new BeanPropertyAnnotationMatcher(Logic.OR, Column.class, Identity.class, Id.class)); boolean findPk = false; for (BeanProperty beanProperty : bps) { if (mapping(beanProperty, tableMapping, logInfo)) { findPk = true; } } if (!findPk) { throw new SimpleORMException("#id.map.not.exists", new Object[] {type.getName()}); } // 从对象对应的table读取列,找到隐式映射(下划线分割后的自动大写) TableMetadata tm = meta.getTable(tableName); if (tm == null) { throw new SimpleORMException("#talbe.not.exists", new Object[] {tableName}); } for (ColumnMetadata cmd : tm.getColumns()) { mappingHidden(bd, tableMapping, cmd, logInfo); } if (LOGGER.isDebugEnabled()) { LOGGER.debug(logInfo.toString()); } // 形成映射对象 cm = new ClassMapping(type, tableName); cm.addPropertyMappings(tableMapping.values()); MAPPED_CLASS.put(type, cm); } return cm; } // ******************************************************************** // private method // ******************************************************************** private static String getTableName(Class type) { String tableName = null; for (ClassTableNameFactory classTableNameFactory : TABLE_NAME_FACTORIES) { tableName = classTableNameFactory.getMappingTableName(type); if (LangUtils.isNotEmpty(tableName)) return tableName; } if (LangUtils.isEmpty(tableName)) { throw new SimpleORMException("#notalbe.map.type", new Object[] {type.getName()}); } return tableName; } // private static String getColumnName(BeanProperty bp) { // String columnName = null; // for (PropertyColumnNameFactory columnNameFactory : COLUMN_NAME_FACTORIES) { // columnName = columnNameFactory.getMappingColumnName(bp); // if (columnName != null) return columnName; // } // if (LangUtils.isEmpty(columnName)) { // throw new SimpleORMException(String.format("没有找到类型%s的属性%s对应的列名" // , bp.getOwnerType().getName(), bp.getName())); // } // return columnName; // } private static boolean mapping(BeanProperty beanProperty, Map tableMapping , StringBuilder logInfo) { PropertyMapping mapping = new PropertyMapping(); Column columnAnnotation = beanProperty.getAnnotation(Column.class); String columnName = null; String innerProperty = null; if (columnAnnotation == null) { columnName = WordUtils.addSignBeforeUpper( beanProperty.getName(), UNDER_LINE , true); } else { columnName = columnAnnotation.value(); innerProperty = columnAnnotation.innerProperty(); } mapping.setColumnName(columnName.toUpperCase()); mapping.setPropertyName(beanProperty.getName()); mapping.setPropertyType(beanProperty.getType()); if (StringUtils.isNotEmpty(innerProperty)) { BeanDescriptor innerBd = BeanDescriptor .getBeanDescriptor(beanProperty.getType()); BeanProperty innerBeanProperty = innerBd.getBeanProperty( innerProperty); mapping.setInnerPropertyName(innerBeanProperty.getName()); mapping.setInnerPropertyType(innerBeanProperty.getType()); } boolean hasPk = beanProperty.hasAnnotation(Identity.class);; if (!hasPk) { hasPk = beanProperty.hasAnnotation(Id.class); } mapping.setPrimaryKey(hasPk); tableMapping.put(mapping.getColumnName(), mapping); if (LOGGER.isDebugEnabled()) { logInfo.append(String.format("%s###\t%s -> %s", SystemPropertyUtils.getLineSeparator(), mapping.getFinalPropertyName(), mapping.getColumnName())); } return hasPk; } private static void mappingHidden(BeanDescriptor bd, Map tableMapping , ColumnMetadata cmd, StringBuilder logInfo) { if (!tableMapping.containsKey(cmd.getName())) { // 转换下划线,并使用驼峰 String columnName = cmd.getName().toLowerCase(); String propertyName = WordUtils.parseToUpperFirst( columnName, Chars.UNDER_LINE.charAt(0)); BeanProperty beanProperty = bd.findBeanProperty( new BeanPropertyNameRegexMatcher(propertyName)); if (beanProperty != null) { PropertyMapping mapping = new PropertyMapping(); mapping.setPropertyType(beanProperty.getType()); mapping.setPropertyName(propertyName); mapping.setColumnName(columnName.toUpperCase()); mapping.setPrimaryKey(cmd.isPrimaryKey()); tableMapping.put(mapping.getColumnName(), mapping); if (LOGGER.isDebugEnabled()) { logInfo.append(String.format("%s###\t%s -> %s", SystemPropertyUtils.getLineSeparator(), mapping.getPropertyName(), mapping.getColumnName())); } } else { if (LOGGER.isDebugEnabled()) { logInfo.append(String.format("%s\t没有属性 -> %s [列%s的隐式映射]", SystemPropertyUtils.getLineSeparator(), propertyName, cmd.getName())); } } } } private void addPropertyMapping(PropertyMapping propertyMapping) { propertyMappings.put(propertyMapping.getPropertyName(), propertyMapping); } // private void addPropertyMappings(PropertyMapping...propertyMappings) { // for (PropertyMapping propertyMapping : propertyMappings) { // addPropertyMapping(propertyMapping); // } // } private void addPropertyMappings(Collection propertyMappings) { for (PropertyMapping propertyMapping : propertyMappings) { addPropertyMapping(propertyMapping); } } // ******************************************************************** // // ******************************************************************** private Map propertyMappings = new HashMap(0); private String tableName; private Class type; /** * @return 返回tableName */ public String getTableName() { return tableName; } /** * @return 返回type */ public Class getType() { return type; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy