根据object封装实体对象

工作中用到了原生hibernate,得自己封装List<String,Map<Object,Objec>>,贴上代码。


 

/**
 * 
 * @Author:         Leon.Liu
 * @Version:        2018-8-13
 * @Explain:        
 *                     重新改写了一下代码...原来需要用包名..现在不用了...
 */
public class LeonBatis<T> {
    
    private T t;
    
    public List<T> mapper(List<Map<Object,Object>> listMap,Map<String,Object> resultMap){
        if(listMap==null||listMap.size()==0)return null;
        return AssignBean(null,listMap,resultMap);
    }
    
    public LeonBatis() {
        super();
    }
    public LeonBatis(T t) {
        super();
        this.t = t;
    }
    
    /**
     * 
     * MyBatis的作用是自定义sql字段,查询数据库,以及自动封装对象,
     * 
     * 那我的LeonBatis,先做的就是自动封装对象,其他的功能实现,等待以后需要自己添加
     * 
     * @see     根据查询出来的自定义字段,进行对象封装,因为会有多个自定义对象,在一个查询结果里,然后这些查询结果都是有连接关系的,比如是当前查询结果的子之类的...
     * @param    Package                类的全路径,会有多个自定义路径                例:cn.softcore.com.bean.TopoBean
     * @param    listMap                数据库中查询出来的所有数据
     * @param    resultMap            
     *                                 第一种情况,key是对象的属性
     *                                         value是sql查询的别名
     *                                         通过key 就是field 获得sql 别名,然后获取map中别名下的查询到的数据,赋值给field
     *                                 
     *                                 例子 select t1.id kkid , t1.name kkname from t t1
     *                                 查询出来的数据如下
     *                                 kkid    kkname                            
     *                                  1             小明
     *                                 假如现在的现在的对象是student,对象的属性是id和name
     *                                 那我们需要将kkid和kkname的值赋给id和name
     *                                 这个时候直接通过属性是获取不到的值的,因为两个名称不一样
     *                                 通过resultMap,id对应查询出来kkid,name对应查询出来kkname
     *                                 将值赋给对应的属性,这样对象里就有查询出来的值了...
     * 
     *                                 通过类的pid属性,获得PPID别名,然后通过PPID获得sql查询到的值,在赋值给PID
     *     
     *                                 第二种情况,key是bean的field,不过是别的类,比如Area什么的,或者是List<Bean>之类的...
     *                                         value就是属性类的全路径包名,通过全路径包名获取到一个全新的resultMap,在通过第一种情况进行赋值.
     *                                         然后将属性类赋值到类的属性中
     * 
     *                                 第三种情况,如果resultMap为null,则执行反射属性执行
     *             Tips:
     *                 相对于MyBatis的resultMap
     *                 因为一个对象,对应多个自定义字段,所以每个自定义字段,都属于同一个类的全路径下
     * @TODO:
     *             MyBatis中,会有多个对象自定义封装,比如一个对象,下面list<Son> ,这个时候需要查询出来对象,还要进行对象封装,以及赋值给子
     * 
     * [əˈsaɪn] assign
     */
    private List AssignBean(String packageName,List<Map<Object,Object>> listMap,Map<String,Object> resultMap){
        List list = null;
        if(packageName==null)list = new ArrayList<T>();
        else list = new ArrayList<Object>();
        //1.获取无参构造和方法
        Map<String,Object> map = forNameClassGetNonParameterConstructor(packageName);
        //1.1    获取无参构造
        Constructor Constructor = (Constructor)map.get("Constructor");
        //1.2    获取所有属性
        Field[] fields = (Field[])map.get("fields");
        //1.3    根据无参构造方法实例化对象
        Object object = NonParameterConstructorToObject(Constructor);
        //2.0    循环遍历查询出的完整数据listMap
        for (Map<Object, Object> objectMap : listMap) {
            //这个时候想要取数据,需要将    objectMap    对应的    key    找出来
            if(resultMap!=null){
                objectMapToObjectByResultMap(object,objectMap,fields,resultMap);
            }
            else{
                objectMapToObjectByField(object,fields,objectMap);
            }
            // 8.循环遍历完所有属性,将数据完整Object添加到list中
            //2.1    添加到list中
            if(packageName==null)list.add((T)object);
            else list.add(object);
            //2.2    实例化新的obj,参加下一次循环
            object = NonParameterConstructorToObject(Constructor);
        }
        return list;
    }
    
    /**
     * 
     * @param objectMap        单条查询数据
     * @param fields        类的属性
     * @param resultMap        查询结果属性对应的字段
     * @param obj            传递过来的对象,封装完数据,需要返回
     * @For:
     *                         根据resultMap来封装对象
     */
    private  void objectMapToObjectByResultMap(Object obj,Map<Object, Object> objectMap,Field[] fields,Map<String,Object> resultMap){
        String BEANPACKAGEFLAG = ".";//如果在一个属性里出现里. 那就是下一个类的象征了...
        String ListType = "interface java.util.List";
        String fieldName = null;    //     类的属性名称
        Object fieldValue = null;    // 类的属性值
        String fieldType = null;    //     属性类型
        String sqlFieldName = null;    //属性对应的sql别名
        //1.先遍历类的属性
        for (Field field : fields) {
            fieldName = field.getName();                    //类的属性名
            fieldType = field.getType().toString();            //类的属性类型Type
            //resultMap从,放入属性名的key,取出对应sql语句中的别名字段,拿到别名字段,开始做下一步操作
            
            //做一个验证,
            //第一,不是所有属性都会赋值,so遇到不需要赋值的,直接跳过
            if(resultMap.get(fieldName)==null)continue;
            
            sqlFieldName = resultMap.get(fieldName).toString();    
            //2.      别名字段下数据不为空.则要进行验证是否为其他包...            例:cn.softcore.com.bean.TopoBean
            //2.1     首先看下别名字段是不是下一个对象的包名,如果是,进行下一步操作
            if(sqlFieldName.indexOf(BEANPACKAGEFLAG)!=-1){
                //如果别名里包含.    说明是一个包..需要进行下一步的操作了...
                List<Map<Object, Object>> arrayList = new ArrayList<>();
                arrayList.add(objectMap);
                //2.2    通过递归将当前数据,这个时候需要知道当前属性的类型,如果是单个类型,将类型list.get(0)赋值,若不是,则将list赋值进去
                List<Object> list = AssignBean(sqlFieldName,arrayList,(Map<String,Object>)resultMap.get(sqlFieldName));
                //将resultMap中数据删除
                resultMap.remove(sqlFieldName);
                //2.3    当前是一个类型是一个类名,如果是list
                if(fieldType.equals(ListType)){
                    //赋值
                    invokeSet(obj, fieldName, list, fieldType);
                }else{
                    //不是list,是一个实体类,直接传一个单独的类过去赋值
                    invokeSet(obj, fieldName, list.get(0), fieldType);
                }
                continue;
            }
            fieldValue = objectMap.get(sqlFieldName.toUpperCase());//从map中取出别名字段下的数据
            if (fieldValue == null)continue;            // 如果值为空,直接开始下一个循环
            //    普通属性,直接赋值
            invokeSet(obj, fieldName, fieldValue, fieldType);
        }
    }
    
    /**
     * 根据无参构造方法实例化对象
     */
    private  Object NonParameterConstructorToObject(Constructor constructor){
        Object object = null;
        try {
            object = constructor.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return object;
    }
    
    /**
     * @param Package    类的全路径包名
     * @return
     *                     根据全路径包名
     *                     获取无参构造方法
     *                     以及所有属性
     */
    private  Map<String,Object> forNameClassGetNonParameterConstructor(String packageName){
        Map<String,Object> map = new HashMap<>();
        Class c = null;
        try {
            if(packageName==null)c = t.getClass();
            else c = Class.forName(packageName);
            Constructor Constructor = getNonParameterConstructor(c.getConstructors());
            Field[] fields = c.getDeclaredFields();
            map.put("Constructor",Constructor);
            map.put("fields",fields);
        }catch(Exception e){
            e.printStackTrace();
        }
        return map;
    }
    
    /**
     * 根据类的属性进行封装数据
     */
    private  void objectMapToObjectByField(Object obj,Field[] fields,Map<Object, Object> m){
        String fieldName = null;// 类的属性名称
        Object fieldValue = null;// 类的属性值
        String fieldType = null;// 属性类型
        for (Field field : fields) {
            fieldName = field.getName(); // 类的属性名
            fieldValue = m.get(fieldName.toUpperCase());// 从map中取出数据
            fieldType = field.getType().toString(); // 类的属性类型Type
            if (fieldValue == null)
                continue; // 如果值为空,直接开始下一个循环
            // 7.值不为空,反射执行方法
            invokeSet(obj, fieldName, fieldValue, fieldType);
        }
    }
    
    /**
     * 获取无参构造方法
     */
    private  Constructor getNonParameterConstructor(Constructor[] c) {
        for (Constructor constructor : c) {
            if (constructor.getParameterTypes().length == 0) {
                return constructor;
            }
        }
        return null;
    }
    
    
     /**
     * 
     * @param o            当前对象
     * @param fieldName    属性名
     * @param value        属性值
     * 
     *          根据传递过来的对象和值,进行赋值,执行反射方法
     */
    private  void invokeSet(Object o, String fieldName, Object value,String fieldType) {  
        Method method = getSetMethod(o.getClass(), fieldName);  
        try {
            method.invoke(o, new Object[] { caseFieldType(fieldType,value)});
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }
    
    /**
     * 
     * @param fieldType        属性类型
     * @param value            属性值
     * @return                返回一个已经实例化的对象
     * @For:
     *                         根据属性类型,
     *                         将属性转换成相应的对象
     * Tips:    
     *         对于byte和short,
     *         因为使用频率实在太低,
     *         而且暂时还不知道怎么转换,
     *         所以不进行转换...
     */
    private  Object caseFieldType(String fieldType,Object value){
        if(fieldType.indexOf("String")!=-1){
            return value.toString();
        }else if(fieldType.equals("byte") || fieldType.indexOf("Byte")!=-1){
            return value;
        }else if(fieldType.equals("short") || fieldType.indexOf("Short")!=-1){
            return value;
        }else if(fieldType.equals("long")|| fieldType.indexOf("Long")!=-1){
            return Long.valueOf(value.toString());
        }else if((fieldType.equals("int") || fieldType.indexOf("Integer")!=-1) && fieldType.indexOf("interface")==-1){
            return Integer.parseInt(value.toString());
        }else if(fieldType.equals("double") || fieldType.indexOf("Double")!=-1){
            return Double.parseDouble(value.toString());
        }else if(fieldType.equals("char") || fieldType.indexOf("Character")!=-1){
            return Character.valueOf((Character) value);
        }else if(fieldType.equals("boolean") || fieldType.indexOf("Boolean")!=-1){
            return Boolean.parseBoolean(value.toString());
        }else if(fieldType.equals("float")    || fieldType.indexOf("Float")!=-1){
            return    Float.parseFloat(value.toString());
        }else if(fieldType.indexOf("Date")!= -1 ){
             String date = value.toString();
             SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
             ParsePosition pos = new ParsePosition(0);
             return    formatter.parse(date, pos);
        }else if(fieldType.equals("interface java.util.List")){
            return value;
        }
        //会有list吗?不会有噢~,因为查询的语句里不会冒出来一个list的
        return value;
    }
    
    /**
     * 反射set方法
     */
    private  Method getSetMethod(Class objectClass, String fieldName) {  
        try {  
            Class[] parameterTypes = new Class[1];  
            Field field = objectClass.getDeclaredField(fieldName);  
            parameterTypes[0] = field.getType();  
            StringBuffer sb = new StringBuffer();  
            sb.append("set");  
            sb.append(fieldName.substring(0, 1).toUpperCase());  
            sb.append(fieldName.substring(1));  
            Method method = objectClass.getMethod(sb.toString(), parameterTypes);
            return method;  
        } catch (Exception e) {  
            e.printStackTrace();  
        }
        return null;
    }
    
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值