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 注解的保留位置 ...
随机推荐
- git合并冲突解决方法
1.git merge冲突了,根据提示找到冲突的文件,解决冲突 如果文件有冲突,那么会有类似的标记 2.修改完之后,执行git add 冲突文件名 3.git commit 注意:没有-m选项 进去类 ...
- Redis持久化(persistence)
Redis 持久化 Redis 提供了多种不同级别的持久化方式: RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). AOF 持久化记录服务器 ...
- QMessageBox的用法
QMessageBox的用法 先来看一下最熟悉的QMessageBox::information.我们在以前的代码中这样使用过: QMessageBox::information(NULL, ...
- Failed to load resource: the server responded with a status of 404 (Not Found) favicon.ico文件找不到
今天使用sublime以localhost方式打开html文件时(使用wamp环境提供一个Apache服务器,html文件存在于wamp环境的www文件夹下),出现favicon.ico文件找不到 ...
- python爬虫学习(一):BeautifulSoup库基础及一般元素提取方法
最近在看爬虫相关的东西,一方面是兴趣,另一方面也是借学习爬虫练习python的使用,推荐一个很好的入门教程:中国大学MOOC的<python网络爬虫与信息提取>,是由北京理工的副教授嵩天老 ...
- dp的最优性
dp看似像递推,但是有一点不一样,虽然都是先处理完子过程并由此退出最终的,但是dp满足任何过程的最优性,dp用子过程最优来保证最终结果的最优性.
- bzoj 4767: 两双手 组合 容斥
题目链接 bzoj4767: 两双手 题解 不共线向量构成一组基底 对于每个点\((X,Y)\)构成的向量拆分 也就是对于方程组 $Ax * x + Bx * y = X $ \(Ay * x + B ...
- Bzoj4598: [Sdoi2016]模式字符串 点分治 哈希
国际惯例的题面:这种关于树上路径的题,我也没什么好办法,只好点分治.考虑当前分治重心为root,如何统计经过分治重心的路径的答案.我们令prf[i]表示某个点到root的路径(不含root)已经循环匹 ...
- Codechef October Challenge 2018 游记
Codechef October Challenge 2018 游记 CHSERVE - Chef and Serves 题目大意: 乒乓球比赛中,双方每累计得两分就会交换一次发球权. 不过,大厨和小 ...
- Python 爬取bangumi网页信息
1.数据库连接池 #######db.py########## import time import pymysql import threading from DBUtils.PooledDB im ...