zoukankan      html  css  js  c++  java
  • Java注解应用,自定义注解映射实现方案说明.

    插件结构如图:

    注册模块定义了三个:用于实体与表映射的注解,用于属性到表字段的映射,用于映射时过滤掉的注解.

    1.用于实体与表映射的注解

    package com.dobby.plugins.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * User: 苏若年
     * Date: 14-10-9
     * Time: 下午21:12
     * Description:
     */
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface GeneratorTable {
    
        //标注映射时的表名
        public String name() default "";
    
    }

    2.用于属性与字段映射的注解

    package com.dobby.plugins.annotation;
    
    import java.lang.annotation.*;
    
    /**
     * User: 苏若年
     * Date: 14-10-9
     * Time: 下午21:31
     * Description:
     */
    @Target({ElementType.METHOD,ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface GeneratorField {
    
        /**
         * 是否为主键
         * @return
         */
        boolean primaryKey() default false;
    
        /**
         * 映射的字段名
         * @return
         */
        public String name() default "";
    }

    3.用于废弃字段过滤的注解

    package com.dobby.plugins.annotation;
    
    import java.lang.annotation.*;
    
    /**
     * User: 苏若年
     * Date: 14-10-9
     * Time: 下午21:15
     * Description:
     */
    @Target({ElementType.METHOD,ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface AbolishedField {
        //标注映射时排除的字段
    }

    注解定义完成后,我们需要在扫描到的实体中根据注解映射规则进行扫描时自动封装

    自动封装的核心业务逻辑如下

        /**
         * 根据对象构造,表映射
         * @param object
         *                 实体对象
         * @return
         *                 实体对象到字段表的映射,基于注解处理
         */
        public static EntityTable constructEntityTableWithObject(Object object){
            EntityTable entityTable = null;
            try{
                if(null == object){return null;}
    
                ConcurrentMap<String,String> entityToTable = new ConcurrentHashMap<String, String>();
                boolean isGeneratorTable = object.getClass().isAnnotationPresent(GeneratorTable.class);
                System.out.println(object.getClass().getSimpleName());
                if(isGeneratorTable){
                    GeneratorTable generatorTable = object.getClass().getAnnotation(GeneratorTable.class);
                    if(StringUtils.isBlank(generatorTable.name())){
                        entityToTable.put(object.getClass().getSimpleName(),firstLower(object.getClass().getSimpleName()));
                    }else{
                        entityToTable.put(object.getClass().getSimpleName(),generatorTable.name());
                    }
                }else{
                    entityToTable.put(object.getClass().getSimpleName(),firstLower(object.getClass().getSimpleName()));
                }
                Field[] fields = object.getClass().getDeclaredFields();
                if(null != fields){
                    entityTable = new EntityTable();
                    //主键组
                    ConcurrentMap<String,String> propertyToKey = new ConcurrentHashMap<String,String>();
                    //字段组
                    ConcurrentMap<String,String> propertyToColumn = new ConcurrentHashMap<String, String>();
                    //主键到集合类型映射
                    ConcurrentMap<String,Object> propertyPKeyType = new ConcurrentHashMap<String,Object>();
    
                    for (int i = 0; i < fields.length; i++) {
                        //判断是否剔除
                        boolean isAbolishedField = fields[i].isAnnotationPresent(AbolishedField.class);
                        if(isAbolishedField){
                            //跳过该字段的提取
                            continue;
                        }
                        //判断是否是主键
                        boolean isGeneratorField = fields[i].isAnnotationPresent(GeneratorField.class);
                        if(isGeneratorField){
                            // 取注解中的文字说明
                            GeneratorField generatorField =  fields[i].getAnnotation(GeneratorField.class);
                            boolean primaryKey = generatorField.primaryKey();
                            if(primaryKey){
                                //添加到主键集合
                                propertyPKeyType.put(fields[i].getName(),fields[i].getType().getName());
                                propertyToKey.put(fields[i].getName(),generatorField.name());
                            }else{
                                if(StringUtils.isBlank(generatorField.name())){
                                    propertyToColumn.put(fields[i].getName(),fields[i].getName());
                                }else{
                                    propertyToColumn.put(fields[i].getName(),generatorField.name());
                                }
                            }
                            continue;
                        }
                        propertyToColumn.put(fields[i].getName(), fields[i].getName());
                    }
                    entityTable.setPropertyPKeyType(propertyPKeyType);
                    entityTable.setPropertyToPKey(propertyToKey);
                    entityTable.setPropertyToColumn(propertyToColumn);
                }
                entityTable.setEntityToTable(entityToTable);
            }catch (Exception e){
                e.printStackTrace();
            }
            return entityTable;
        }
    EntityTable时实体与表结构映射的一个简易对象.

    如下,我们定义的实体

    package com.dobby.code.make.model;
    
    import com.dobby.plugins.annotation.AbolishedField;
    import com.dobby.plugins.annotation.GeneratorField;
    import com.dobby.plugins.annotation.GeneratorTable;
    
    import java.io.Serializable;
    
    /**
     * Created by 苏若年 on 2014/11/26.
     */
    //映射表别名
    @GeneratorTable(name = "tb_member")
    public class Member implements Serializable {
    
    
        //映射该字段,并且为主键,自定义字段别名
        @GeneratorField(primaryKey = true, name = "m_Id")
        private Integer id;
    
        @GeneratorField(name = "member_name")
        private String memberName;
    
        //映射时不映射该字段
        @AbolishedField
        private String address;
    
        //不使用注解,默认为使用属性名进行映射
        private String zipCode;
    
        //getter and setter
    
    }

     查看实体映射过程

     EntityTable entityTable = BeanUtils.constructEntityTableWithPath("com.dobby.code.make.model.Member");
     System.out.println("主键映射" + entityTable.getPropertyToPKey());
     System.out.println("字段映射" + entityTable.getPropertyToColumn());
     System.out.println("主键集合" + entityTable.getPropertyPKeyType());
     System.out.println("表名映射" + entityTable.getEntityToTable());

    通过注解映射后的结果如下:

    主键映射{id=m_Id}
    字段映射{zipCode=zipCode, memberName=member_name}
    主键集合{id=java.lang.Integer}
    表名映射{Member=tb_member}

    因为使用了注解映射过滤,所以address字段映射时被排除.

    转载请注明出处:[http://www.cnblogs.com/dennisit/p/4125103.html]

  • 相关阅读:
    2021-6-3 日报博客
    2021-6-2 日报博客
    2021-6-1 日报博客
    2021-5-31 日报博客
    团队博客——十日冲刺结束
    团队博客——十日冲刺9
    团队博客——十日冲刺8
    团队博客——十日冲刺7
    周总结9
    团队博客——十日冲刺6
  • 原文地址:https://www.cnblogs.com/dennisit/p/4125103.html
Copyright © 2011-2022 走看看