1.

  1 package com.glodon.gspm.adapter.plugin.common;
  2 
  3 import com.glodon.cloudt.tenancy.context.TenantContext;
  4 import org.bson.Document;
  5 import org.springframework.beans.BeanUtils;
  6 import org.springframework.beans.BeanWrapper;
  7 import org.springframework.beans.PropertyAccessorFactory;
  8 import org.springframework.util.StringUtils;
  9 
 10 import java.beans.PropertyDescriptor;
 11 import java.util.HashMap;
 12 import java.util.Map;
 13 import java.util.concurrent.ConcurrentHashMap;
 14 
 15 /**
 16  * 实体对象转Document类
 17  * Created by hezg on 2017/4/4.
 18  */
 19 public class Bean2Document<T> {
 20 
 21     //字段前缀
 22     private static final char COLUMN_PREFIX = 'F';
 23     //单词分隔符
 24     private static final char UNDER_LINE = '_';
 25     //字段属性映射
 26     private transient Map<String, PropertyDescriptor> mappedFields;
 27 
 28     private static Map<Class<?>, Bean2Document> mapperMap = new ConcurrentHashMap<>();
 29 
 30     public Bean2Document(Class<T> mappedClass) {
 31         initialize(mappedClass);
 32     }
 33 
 34     /**
 35      * 创建一个新的Bean2Document类
 36      *
 37      * @param mappedClass 需要映射的实体类
 38      */
 39     @SuppressWarnings("unchecked")
 40     public static <T> Bean2Document<T> newInstance(Class<T> mappedClass) {
 41         Bean2Document mapper = mapperMap.get(mappedClass);
 42         if (mapper == null) {
 43             mapper = new Bean2Document<>(mappedClass);
 44             mapperMap.put(mappedClass, mapper);
 45         }
 46         return (Bean2Document<T>) mapper;
 47     }
 48 
 49     /**
 50      * 将实体属性初始化到mappedFields中
 51      *
 52      * @param mappedClass 需要初始化的实体类
 53      */
 54     @SuppressWarnings("Duplicates")
 55     protected void initialize(Class<T> mappedClass) {
 56         this.mappedFields = new HashMap<>();
 57         PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(mappedClass);
 58         for (PropertyDescriptor pd : pds) {
 59             if (pd.getWriteMethod() != null) {
 60                 this.mappedFields.put(pd.getName().toUpperCase(), pd);
 61             }
 62         }
 63     }
 64 
 65     /**
 66      * 将实体字段名转换为表字段名
 67      *
 68      * @param name 实体字段
 69      * @return 返回对应表字段名
 70      */
 71     @SuppressWarnings("Duplicates")
 72     private String underscoreName(String name) {
 73         if (!StringUtils.hasLength(name)) {
 74             return "";
 75         }
 76         // 添加字段前缀
 77         StringBuilder result = new StringBuilder();
 78         if (!StringUtils.isEmpty(COLUMN_PREFIX)) {
 79             result.append(COLUMN_PREFIX).append(UNDER_LINE);
 80         }
 81         result.append(name.substring(0, 1).toUpperCase());
 82         for (int i = 1; i < name.length(); i++) {
 83             String ss = name.substring(i, i + 1);
 84             String slc = ss.toUpperCase();
 85             if (ss.equals(slc)) {
 86                 result.append(UNDER_LINE).append(slc);
 87             } else {
 88                 result.append(slc);
 89             }
 90         }
 91         return result.toString();
 92     }
 93 
 94     /**
 95      * 将实体数据格式转换为Document格式
 96      *
 97      * @param data 实体数据
 98      * @return Document格式数据
 99      */
100     public Document toDocument(T data) {
101         if (data == null) {
102             return null;
103         }
104 
105         Document document = new Document();
106         BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(data);
107         for (PropertyDescriptor pd : this.mappedFields.values()) {
108             Object value = bw.getPropertyValue(pd.getName());
109             String underscoredName = underscoreName(pd.getName());
110             document.put(underscoredName, value);
111         }
112         //Mongo同一接口,所有类转Document时都带上租户Id
113         long tenantId = TenantContext.getCurrent()
114                 .getTenantId();
115 
116         document.put("F_TENANT_ID", tenantId);
117         return document;
118     }
119 }

 

posted on 2017-11-20 23:46  Sharpest  阅读(320)  评论(0编辑  收藏  举报