自定义注解与MYSQL
无聊之作,可以提意见,但别嘲笑啊
package bean; import java.sql.Date; import annotationK.annotation.Column; import annotationK.annotation.Comment; import annotationK.annotation.Entity; import annotationK.annotation.GeneratedValue; import annotationK.annotation.GenerationType; import annotationK.annotation.Id; import annotationK.annotation.Table; import annotationK.annotation.Temporal; import annotationK.annotation.TemporalType; @Entity @Table(name="base_user") public class User { @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="uid") @Comment(value="编码") private Long id; @Comment(value="姓名") @Column(name="core_name",length=50) private String name; @Comment(value="密码") @Column(unique=true,length=50) private String password; @Column(length=100) @Comment(value="邮箱") private String email; @Temporal(TemporalType.DATE) @Comment(value="生日") private Date birthday; @Temporal(TemporalType.TIME) private Date birthday2; @Temporal(TemporalType.TIMESTAMP) private Date birthday3; private Date birthday4; private Integer nums; private int num2; private Long num3; private long num4; private Double num5; private double num6; private Float num15; private float num16; private Byte num8; private byte num7; private Short num9; private short num10; private char num11; private Character num12; private Boolean num13; private boolean num14; @Temporal(TemporalType.DATE) private java.sql.Date num17; @Temporal(TemporalType.TIME) private java.sql.Date num18; @Temporal(TemporalType.TIMESTAMP) private java.sql.Date num19; private java.sql.Date num20; }
AnnotationEnum
package annotationK.annotation; import java.util.HashMap; import java.util.Map; /** * 注解枚举 * */ public enum AnnotationEnum { TABLE("Table"), ID("Id"), COLUMN("Column"), UNIQUECONSTRAINT("UniqueConstraint"), GENERATEDVALUE("GeneratedValue"), GENERICGENERATOR("GenericGenerator"), PARAMETER("Parameter"), TEMPORAL("Temporal"), COMMENT("Comment"), TRANSIENT("Transient"), ENTITY("Entity"); public final String annotationName; private static Map<String, String> annotations = new HashMap<String, String>(); static{ for (AnnotationEnum annotation : AnnotationEnum.values()) { annotations.put(annotation.toString(), annotation.annotationName); } } private AnnotationEnum(String annotationName) { this.annotationName = annotationName; } public static String forType(String annotation) { String annotationName = annotations.get(annotation); return annotationName; } }
Column
package annotationK.annotation; import java.lang.annotation.Target; import java.lang.annotation.Retention; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * 复制 javax.Persistence 下面的colums 注解 * @since Java Persistence 1.0 */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Column { String name() default "";//映射列名 boolean unique() default false; //映射列上的值不能相同 FetchType type() default FetchType.EAGER;//加载策略 boolean nullable() default true; //是否允许为空 boolean insertable() default true; boolean updatable() default true; String columnType() default "";//对应列类型 String defaultVaule() default "";//默认值 String table() default ""; int length() default 255;//长度 int precision() default 0; int scale() default 0; }
Comment
package annotationK.annotation; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * 注释注解 * */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Comment { /** * 注释类容 * */ String value(); }
Entity
package annotationK.annotation; import java.lang.annotation.Target; import java.lang.annotation.Retention; import java.lang.annotation.Documented; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Specifies that the class is an entity. This annotation is applied to the * entity class. * * @since Java Persistence 1.0 * 复制 javax.Persistence 下面的Entity 注解 */ @Documented @Target(TYPE) @Retention(RUNTIME) public @interface Entity { String name() default ""; }
FetchType package annotationK.annotation; /** * 加载策略 * */ public enum FetchType { /** Defines that data can be lazily fetched. * 延迟 * */ LAZY, /** Defines that data must be eagerly fetched. * 即刻 * */ EAGER }
GeneratedValue
package annotationK.annotation; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static annotationK.annotation.GenerationType.AUTO; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface GeneratedValue { GenerationType strategy() default AUTO; String generator() default ""; }
GenerationType
package annotationK.annotation; /** * Defines the types of primary key generation strategies. * * @see GeneratedValue * * @since Java Persistence 1.0 * * JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO. TABLE:使用一个特定的数据库表格来保存主键。 SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。 IDENTITY:主键由数据库自动生成(主要是自动增长型) AUTO:主键由程序控 */ public enum GenerationType { TABLE, SEQUENCE, IDENTITY, AUTO }
GenericGenerator
package annotationK.annotation; import static java.lang.annotation.ElementType.*; import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; /** * @author Emmanuel Bernard */ @Target({PACKAGE, TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface GenericGenerator { String name(); String strategy(); Parameter[] parameters() default {}; }
Id
package annotationK.annotation; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * 自定义主键注解 * */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Id { }
MysqlToJavaTypeEnum
package annotationK.annotation; import java.util.HashMap; import java.util.Map; /** * 数据类型枚举 java类型,mysql数据类型,数据列默认长度,参考Hibernae jap规范 * */ public enum MysqlToJavaTypeEnum { LANG_LONG("bigint","java.lang.Long",20), LANG_INTEGER("int","java.lang.Integer",11), LANG_SHORT("smallint","java.lang.Short",6), LANG_BYTE("tinyint","java.lang.Byte",4), LANG_DOUBLE("double","java.lang.Double",0), LANG_FLOAT("float","java.lang.Float",0), LANG_BOOLEAN("enum","java.lang.Boolean",1), LANG_STRING("varchar","java.lang.String",255), LANG_CHAR("char","java.lang.Character",1), OBJECT_LONG("bigint","long",20), OBJECT_INT("int","int",11), OBJECT_SHORT("smallint","short",6), OBJECT_byte("tinyint","byte",4), OBJECT_DOUBLE("double","double",0), OBJECT_FLOAT("float","float",0), OBJECT_CHAR("char","char",1), OBJECT_BOOLEAN("enum","boolean",1), UTIL_DATE("datetime","java.util.Date",0), SQL_DATE("date","java.sql.Date",0); public final String jdbcType; public final String javaType; public final Integer defaultlength; private static Map<String, String> annotations = new HashMap<String, String>(); static{ for (MysqlToJavaTypeEnum type : MysqlToJavaTypeEnum.values()) { annotations.put(type.toString(), type.javaType); } } private MysqlToJavaTypeEnum(String jdbcType, String javaType, Integer defaultlength) { this.jdbcType = jdbcType; this.javaType = javaType; this.defaultlength = defaultlength; } public static String forType(String annotation) { String annotationName = annotations.get(annotation); return annotationName; } }
Parameter
package annotationK.annotation; import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; @Target({}) @Retention(RUNTIME) public @interface Parameter { String name(); String value(); }
Table
package annotationK.annotation; import java.lang.annotation.Target; import java.lang.annotation.Retention; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * <pre> * Example: * * @Entity * @Table(name="CUST", schema="RECORDS") * public class Customer { ... } * </pre> * 拷贝 javax.persistence 的table注解 * @since Java Persistence 1.0 */ @Target(TYPE) @Retention(RUNTIME) public @interface Table { String name() default ""; String catalog() default ""; String schema() default ""; UniqueConstraint[] uniqueConstraints() default { }; }
Transient
package annotationK.annotation; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * 非映射注解 * */ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Transient { }
UniqueConstraint
package annotationK.annotation; import java.lang.annotation.Target; import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({ }) @Retention(RUNTIME) public @interface UniqueConstraint { String name() default ""; String[] columnNames(); }
package annotationK.util; import java.lang.annotation.Annotation; import java.lang.reflect.Field; /** * 实体bean 字段注解封装 * */ public class ColumnBean { private Field field;//反射字段 private String fieldName;//映射字段名称 private String fieldTypeName; //映射字段数据类型名称 private Class<?> fileType;//映射字段数据类型 private String columnName;//对应数据库表列名称 private Integer columnLength;//对应字段数据列长度 private Integer leve=1;//字段级别 默认为1 (1)普通列 (2)主键列 (3)带自增主键列 private String columnType;//对应列类型 private boolean unique=false;//对应列数据库表中的值能否相同 private boolean nullableBoo=true; //是否允许Null值 private Annotation [] annotations;//该字段上所有的注解 private String comment="";//注释 private boolean fetchType=false;//是否延迟加载 默认false是不延迟 ,true是延迟 private String defaultValue="";//默认值 //---------------------少用---------------------- private boolean insertable; private boolean updatableBoo; private String tableName; private int precision; private int scale; public ColumnBean() { super(); } public ColumnBean(Field field) { super(); this.field = field; } } package annotationK.util; import java.util.List; import annotationK.annotation.UniqueConstraint; /** * 封装实体bean头部注解信息 * */ public class EntityBean<T> { private Class<T> clazz;//解析的类 private boolean entityBO=false; //是否为实体 private boolean tableBO=false; //是否对应table private String entityName;//jpa 映射 对象名称 private String tableName; //对应表名 默认为类名 private String catalog=""; //? private String schema="";//? private UniqueConstraint [] uniqueConstraints;//? private List<ColumnBean> columnBean;//所有字段结果集 }
AnnotationReflectionUtil
package annotationK.util; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import org.junit.Test; import annotationK.annotation.AnnotationEnum; import annotationK.annotation.Column; import annotationK.annotation.Comment; import annotationK.annotation.Entity; import annotationK.annotation.GeneratedValue; import annotationK.annotation.GenerationType; import annotationK.annotation.Id; import annotationK.annotation.Table; /** *注解反射帮助类 * */ public final class AnnotationReflectionUtil { @Test public void test()throws Exception{ /* EntityBean<User> entity=parserClass(User.class); entity=TypeUtils.reflecJdbcTypeAll(entity); for(ColumnBean columnBean:entity.getColumnBean()){ System.out.println(column.getFieldName()); System.out.println("level="+column.getLeve()+",name="+column.getColumnName()+",type="+column.getColumnType()+",length="+column.getColumnLength()+",defalutvalue="+column.getDefaultValue()+",comment="+column.getComment()); System.out.println("--------------------------------------------------------------------"); }*/ } /** * 抛出异常 目前暂定将不属于自定义的注解,全部抛出,返回值布尔值 * */ private boolean putExceptionAnnotationToField(Field field){ boolean tag=true; Annotation annotations []=field.getAnnotations(); if(annotations.length>0){ for(Annotation annotation:annotations){ String annotationName=annotation.annotationType().getName(); if(annotationName.contains("javax")||annotationName.contains("hibernate")||annotationName.contains("ejb3")){ tag=false; throw new RuntimeException(field.getName()+"该字段请注入规定注解"); } } } return tag; } /** * 解析实体bean并将数据封装至TableBean * */ public <T> EntityBean<T> parserClass(Class<T> clazz) throws ClassNotFoundException{ //解析头部 EntityBean<T> entityBean=parserAnnotationClassTop(clazz); if(entityBean.isEntityBO()){ Field fields []=clazz.getDeclaredFields(); List<ColumnBean> columnList=new ArrayList<ColumnBean>(); ColumnBean column=null; for(Field field:fields){ putExceptionAnnotationToField(field); column=new ColumnBean(field); Annotation annotations []=field.getAnnotations(); column.setAnnotations(annotations); column.setFieldName(field.getName()); column.setFileType(field.getType()); column.setFieldTypeName(field.getType().getSimpleName()); boolean tag=true; if(annotations.length>0){ //该字段根据头部注解区分对待 for(Annotation annotation:annotations){ String annotationName=annotation.annotationType().getSimpleName(); if(AnnotationEnum.forType("ID").equals(annotationName)){ column=parserAnnotationId(column); } if(AnnotationEnum.forType("GENERATEDVALUE").equals(annotationName)){ column=parserAnnotationGeneratedValue(column); } if(AnnotationEnum.forType("COLUMN").equals(annotationName)){ column=parserAnnotationColumn(column); } if(AnnotationEnum.forType("TEMPORAL").equals(annotationName)){ column=parserAnnotationDate(column); } if(AnnotationEnum.forType("COMMENT").equals(annotationName)){ column=parserAnnotationComment(column); } if(AnnotationEnum.forType("TRANSIENT").equals(annotationName)){ tag=false; } } }else{ //该字段为缺省为cloumn注解类型,属于映射字段 column=parserAnnotationColumnNot(column); } if(tag) columnList.add(column); } entityBean.setColumnBean(columnList); } return entityBean; } /** * 解决注释注解 * */ private ColumnBean parserAnnotationComment(ColumnBean column){ Field field=column.getField(); Comment comment=field.getAnnotation(Comment.class); String msg=comment.value(); if(msg!=null){ column.setComment(msg); } return column; } /** * 解决无注解字段处理,但是其头部有entity注解 * */ private ColumnBean parserAnnotationColumnNot(ColumnBean column){ Field field=column.getField(); column.setColumnName(field.getName()); return column; } /** * 解析日期类注解 * */ private ColumnBean parserAnnotationDate(ColumnBean column){ Field field=column.getField(); column.setColumnName(field.getName()); return column; } /** * 解析字段Column 注解 * */ private ColumnBean parserAnnotationColumn(ColumnBean columns){ Field field=columns.getField(); Column column=field.getAnnotation(Column.class); if(!column.columnType().equals("")){ columns.setColumnType(column.columnType()); } columns.setDefaultValue(column.defaultVaule()); columns.setColumnName(column.name().equals("")?field.getName():column.name()); columns.setColumnLength(column.length()); columns.setUnique(column.unique()); columns.setInsertable(column.insertable()); columns.setNullableBoo(column.nullable()); columns.setUpdatableBoo(column.updatable()); columns.setTableName(column.table()); columns.setPrecision(column.precision()); columns.setScale(column.scale()); return columns; } /** * 解析主键 * */ private ColumnBean parserAnnotationId(ColumnBean column){ Field field=column.getField(); Id id=field.getAnnotation(Id.class); String className=id.annotationType().getName(); if(!className.contains("javax")||!className.contains("hibernate")){ column.setLeve(2); if(column.getColumnName()==null){ column.setColumnName(field.getName()); } } return column; } /** * 解析主键自增类型 strategy 主键生成规则,配合主键生成策略 * */ private ColumnBean parserAnnotationGeneratedValue(ColumnBean column){ Field field=column.getField(); GeneratedValue generated=field.getAnnotation(GeneratedValue.class); //自增辅助策略 //String generator=generated.generator().toString(); //自增主策略 String generatedValue=generated.strategy().toString(); if(generatedValue==GenerationType.AUTO.toString()){ column.setLeve(3); } return column; } /** * 解析头部注解 * */ private <T> EntityBean<T> parserAnnotationClassTop(Class<T> clazz){ EntityBean<T> entityBean=new EntityBean<T>(); Annotation annotations [] = clazz.getAnnotations(); for(Annotation annotation:annotations){ String annotationName = annotation.annotationType().getSimpleName(); if(AnnotationEnum.forType("ENTITY").equals(annotationName)){ String entityName=parserAnnotationEntity(clazz,annotation); entityBean.setEntityBO(true); entityBean.setEntityName(entityName); } if(AnnotationEnum.forType("TABLE").equals(annotationName)){ String tableName=parserAnnotationTable(clazz,annotation); entityBean.setTableBO(true); entityBean.setTableName(tableName); } } if(entityBean.isEntityBO()&&!entityBean.isTableBO()){ entityBean.setTableName(clazz.getSimpleName()); } return entityBean; } /** * 解析Entity注解 * */ private <T> String parserAnnotationEntity(Class<T> clazz,Annotation annotation){ String entityName=""; Entity entity = clazz.getAnnotation(Entity.class); entityName = entity.name(); if(entityName==null||entityName.equals("")){ entityName=clazz.getSimpleName(); } return entityName; } /** * 解析Table注解 * */ private <T> String parserAnnotationTable(Class<T> clazz,Annotation annotation){ String tableName=""; Table table = clazz.getAnnotation(Table.class); tableName = table.name(); if(tableName==null||tableName.equals("")){ tableName=clazz.getSimpleName(); } return tableName; } }
TypeUtils
package annotationK.util; import java.lang.reflect.Field; import java.util.List; import org.junit.Test; import annotationK.annotation.MysqlToJavaTypeEnum; import annotationK.annotation.Temporal; import annotationK.annotation.TemporalType; import bean.User; /** * 数据类型映射帮助类 * */ public class TypeUtils { @Test public void test() throws ClassNotFoundException{ EntityBean<User> entity=new AnnotationReflectionUtil().parserClass(User.class); entity=TypeUtils.reflecJdbcTypeAll(entity); } public static <T> EntityBean<T> reflecJdbcTypeAll(EntityBean<T> entity){ if(entity.isEntityBO()&&entity.isTableBO()){ List<ColumnBean> columns=entity.getColumnBean(); for(ColumnBean column:columns){ column=reflecJdbcTypeSingle(column); } } return entity; } /** * 解析某个单独 Column对象 * */ public static ColumnBean reflecJdbcTypeSingle(ColumnBean column){ Class<?> clazz=column.getFileType(); MysqlToJavaTypeEnum typeEnum []=MysqlToJavaTypeEnum.values(); for(MysqlToJavaTypeEnum e:typeEnum){ if(e.javaType.equals(clazz.getName())){ if(column.getColumnType()==null){ column.setColumnType(e.jdbcType); } //假如没有使用任何注解,根据枚举对象中定义的长度赋值 if(column.getAnnotations()!=null){ if(column.getColumnLength()==null||column.getColumnLength()==255){ column.setColumnLength(e.defaultlength); } //某些数据库类型的映射长度必须为0 String ctype=column.getColumnType(); if(ctype.equals("longtext")||ctype.equals("enum")){ column.setColumnLength(0); } }else { column.setColumnLength(e.defaultlength); } break; } } if(column.getFieldTypeName().equals("Date")){ reflectDateType(column); } return column; } /** * 映射日期类注解数据类型 * */ public static ColumnBean reflectDateType(ColumnBean column){ //不判断判断属于哪种Date 数据类型 目前只要是 java.util.Date java.sql.Date 都相应的数据类型都 一样 Field field=column.getField(); Temporal tem=field.getAnnotation(Temporal.class); if(tem!=null){ TemporalType temporalType=tem.value(); if(temporalType.compareTo(TemporalType.DATE)==0){ column.setColumnType("date"); }else if(temporalType.compareTo(TemporalType.TIME)==0){ column.setColumnType("time"); }else{ column.setColumnType("datetime"); } } return column; } }
GeneralSQLUtil
package annotationK.util; import org.junit.Test; import bean.User; /** * 生成slq帮助类 * */ public class GeneralSQLUtil { @Test public void test() throws ClassNotFoundException{ //destory(); AnnotationReflectionUtil reflectUtil=new AnnotationReflectionUtil(); EntityBean<User> entity=reflectUtil.parserClass(User.class); entity=TypeUtils.reflecJdbcTypeAll(entity); String result=generalSqlByEntity(entity); System.out.println(result); } public void destory(){ String end="drop table so_order"; } public <T> String generalSqlByEntity(EntityBean<T> entity){ StringBuilder sb=new StringBuilder(); sb.append("create table ").append(entity.getTableName()).append(" (").append("\n"); for(ColumnBean column:entity.getColumnBean()){ if(column==null){ break; } sb.append(column.getFieldName()).append(" ").append(column.getColumnType()); if(column.getFieldTypeName().equals("boolean")||column.getFieldTypeName().equals("Boolean")){ sb.append(" (\'0\',\'1\',\'2\') "); } if(column.getColumnLength()!=0){ sb.append("(").append(column.getColumnLength()).append(")"); } sb.append(" "); if(!column.getDefaultValue().equals("")){ sb.append("DEFAULT ").append(column.getDefaultValue()); } if(column.getLeve()==2){ sb.append(" PRIMARY KEY"); }else if(column.getLeve()==3){ sb.append(" PRIMARY KEY AUTO_INCREMENT"); } if(!column.getComment().equals("")){ sb.append(" comment ").append("\'").append(column.getComment()).append("\'"); } sb.append(",").append("\n"); } return sb.substring(0, sb.length()-2).concat(")"); } }