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]
Java注解应用,自定义注解映射实现方案说明.的更多相关文章
- Java注解-元数据、注解分类、内置注解和自定义注解|乐字节
大家好,我是乐字节的小乐,上次说过了Java多态的6大特性|乐字节,接下来我们来看看Java编程里的注解. Java注解有以下几个知识点: 元数据 注解的分类 内置注解 自定义注解 注解处理器 Ser ...
- Java中的注解及自定义注解你用的怎么样,能不能像我这样应用自如?
Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容.在这个教程当中,我们将学习Java的注解,如何定制注解,注解的使用以及如何通过反射解析注解. Java1.5引入了注解,当前许 ...
- Springboot--元注解及自定义注解(表单验证)
本文简单说明一下元注解,然后对元注解中的@Retention做深入的讨论,在文章最后使用元注解写一个自定义注解来结尾. 一.结论: @Target:注解的作用目标 @Target(ElementTyp ...
- java注解和自定义注解的简单使用
前言 在使用Spring Boot的时候,大量使用注解的语法去替代XML配置文件,十分好用. 然而,在使用注解的时候只知道使用,却不知道原理.直到需要用到自定义注解的时候,才发现对注解原理一无所知,所 ...
- Java反射与自定义注解
反射,在Java常用框架中屡见不鲜.它存在于java.lang.reflact包中,就我的认识,它可以拿到类的字段和方法,及构造方法,还可以生成对象实例等.对深入的机制我暂时还不了解,本篇文章着重在使 ...
- java内置注解、元注解和自定义注解
注解的作用: 1.生成文档 2.跟踪代码依赖性 3.编译时进行格式检查 ---------------------------------------------------------------- ...
- Java:深入自定义注解(Annotation)
在网上找了很多资料也有写的比较好的,但是总有有一点半点的细节没有写出来,在这里自己总结下使用. 使用Java的自定义注解,首先个人需要了解下Java为我们提供的元注解和相关定义注解的语法.(这个我在网 ...
- Java注解(自定义注解、view注入)
注解这东西虽然在jdk1.5就加进来了,但他的存在还是因为使用Afinal框架的view注入才知道的.一直觉得注入特神奇,加了一句就可以把对应view生成了. 下面我们来认识一下注解这个东西 一.注解 ...
- Java中的自定义注解
## 元注解 要声明一个注解, 我们需要元注解, 元注解是指注解的注解,包括@Retention, @Target, @Document, @Inherited. @Retention 注解的保留位置 ...
随机推荐
- C. 【UNR #2】黎明前的巧克力
题解: 不会FWT,只能水40分了 首先,要观察出的性质就是: 选出的集合要满足所有数亦或等于0,而在其中任选子集都可以满足条件,答案就等于sigma(2^size(s)) 这样dp一波显然就可以O( ...
- LR报错Error -27780: [GENERAL_MSG_CAT_SSL_ERROR]connect to host "XXX.XXX.com" failed解决方法
- git add Untracked files
git add * 将目录里的所有文件提交到暂存区后 git status 查看状态 所有文件都是绿色的表示本地的文件和暂存区的文件是一样的 然后在本地修改一个文件 然后新建一个文件 在使用git ...
- Angular 个人深究(三)【由Input&Output引起的】
Angular 个人深究(三)[由Input&Output引起的] 注:最近项目在做别的事情,angular学习停滞了 1.Angular 中 @Input与@Output的使用 //test ...
- IdentityServer4-用EF配置Client(一)
一.背景 IdentityServer4的介绍将不再叙述,百度下可以找到,且官网的快速入门例子也有翻译的版本.这里主要从Client应用场景方面介绍对IdentityServer4的应用. 首先简要介 ...
- 简述synchronized和java.util.concurrent.locks.Lock的异同?
主要相同点:Lock能完成synchronized所实现的所有功能 . 主要不同点:Lock有比synchronized更精确的线程语义和更好的性能.synchronized会自动释放锁,而Lock一 ...
- 跳过从Win7/8升级,直接格式化全新安装 Windows 10 并自动永久激活系统的方法教程
跳过升级,直接激活全新 Win10 的方法步骤教程: 下载 Windows 10 系统的 ISO 镜像 在你当前的 Win7 / Win 8 / 8.1 系统中,使用 DaemonTools 或右键选 ...
- SQL SERVER字符串中的空格去除
1.LTRIM 删除起始空格后返回字符表达式. 语法 LTRIM ( character_expression ) 参数 character_expression 是字符或二进制数据表达式 ...
- 多个 gradle 文件夹 \.gradle\wrapper\dists\ 设置gradle不是每次都下载
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 设置gradle不是每次都下载 \.gradle\wrapper\dists\ ==== ...
- luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索
题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...