1. 程式人生 > 實用技巧 >通過自定義註解實現自動建立表

通過自定義註解實現自動建立表

通過自定義註解實現自動建立表

需求分析

1、建立一個學生資訊實體類,包括學號,姓名,性別,聯絡方式,住址
2、建立一些適當的註解,實現根據實體類自動建立資料庫中的表
3、在建立的學生資訊實體類上應用自定義的註解
4、寫一個註解解析器,獲取解析學生資訊實體類上的註解,然後在mysql資料庫中自動建立好表

實體類

@TableName
public class StuInfo {
	@Type(type = "int", constraints = @Constraints(primarykey = true, autoincrement = true))
	private Integer sno;
	
	@Type(constraints = @Constraints(allowNull = false, unique = true))
	private String sname;
	
	@Type(type = "varchar(15)", constraints = @Constraints(unique = true))
	private String tel;
	
	@Type(type = "varchar(4)", constraints = @Constraints(allowNull = false))
	private String sex;
	
	@Type(type = "varchar(100)")
	private String addr;
    
	@Override
	public String toString() {
		return "StuInfo [sno=" + sno + ", sname=" + sname + ", tel=" + tel + ", sex=" + sex + ", addr=" + addr + "]";
	}	
	public Integer getSno() {
		return sno;
	}
	public void setSno(Integer sno) {
		this.sno = sno;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public String getTel() {
		return tel;
	}
	public void setTel(String tel) {
		this.tel = tel;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((addr == null) ? 0 : addr.hashCode());
		result = prime * result + ((sex == null) ? 0 : sex.hashCode());
		result = prime * result + ((sname == null) ? 0 : sname.hashCode());
		result = prime * result + ((sno == null) ? 0 : sno.hashCode());
		result = prime * result + ((tel == null) ? 0 : tel.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		StuInfo other = (StuInfo) obj;
		if (addr == null) {
			if (other.addr != null)
				return false;
		} else if (!addr.equals(other.addr))
			return false;
		if (sex == null) {
			if (other.sex != null)
				return false;
		} else if (!sex.equals(other.sex))
			return false;
		if (sname == null) {
			if (other.sname != null)
				return false;
		} else if (!sname.equals(other.sname))
			return false;
		if (sno == null) {
			if (other.sno != null)
				return false;
		} else if (!sno.equals(other.sno))
			return false;
		if (tel == null) {
			if (other.tel != null)
				return false;
		} else if (!tel.equals(other.tel))
			return false;
		return true;
	}
}

註解

/**
 * 定義欄位型別
 *@author:憬荃
 *@QQ:1464080002
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Type {
	public String type() default "varchar(20)";
	public Constraints constraints() default @Constraints;
}
/**
 * 用來指定表名的註解
 *@author:憬荃
 *@QQ:1464080002
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
	public String name() default "";
}
/**
 * 定義約束的
 *@author:憬荃
 *@QQ:1464080002
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
	public boolean primarykey() default false;
	public boolean allowNull() default true;
	public boolean unique() default false;
	public boolean autoincrement() default false;
}

註解解析器

public class TableCreator {
	public static void main(String[] args) {
		TableCreator tc = new TableCreator();
		String sql = tc.getSql(StuInfo.class);
		tc.createTable(sql);
	}
    
	private void createTable(String sql) {
		Connection con = null;
		Statement stmt = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/puma?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useOldAliasMetadataBehavior=true","root","a");
			
			stmt = con.createStatement();
			
			stmt.execute(sql);
			System.out.println(sql);
			System.out.println("建立完成...");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("建立失敗...");
		}finally{
			if(stmt != null){
				try {
					stmt.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if(con != null){
				try {
					con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private String getSql(Class<StuInfo> cls) {
		TableName tn = cls.getAnnotation(TableName.class);
		
		if(tn == null){//沒有TableName這個註解,說明這個類不需要建立表
			return null;
		}
		
		StringBuffer sbf = new StringBuffer();
		String tableName = tn.name(); //獲取配置在註解中的表名
		if(tableName == null || "".equals(tableName)){	//如果沒有給定表名,則預設為這個類的類名
			tableName = cls.getSimpleName(); //獲取這個類的類名,注意不是getName(),getName()會包含這個類的類路徑資訊
		}
		
		sbf.append("create table ").append(tableName).append("("); // create table stuInfo(
		
		//接下來要拼接的是列資訊,這個時候需要獲取這個類的所有屬性,判斷上面是否有Type註解
		Field[] fields = cls.getDeclaredFields();
		if(fields == null || fields.length <= 0){
			return null;
		}
		
		Type type = null;
		for(Field field : fields){
			if(!field.isAnnotationPresent(Type.class)){ //Type註解是否在該類上
				continue;
			}
			
			type = field.getAnnotation(Type.class);
			sbf.append(field.getName()).append(" ").append(type.type()); // sno int primary key auto_increment
			
			// 拼接約束
			if(type.constraints().primarykey()){
				sbf.append(" primary key");
				
				//判斷主鍵是否自增
				if(type.constraints().autoincrement()){
					sbf.append(" auto_increment");
				}
			}else{
				//是否唯一
				if(type.constraints().unique()){
					sbf.append(" unique");
				}
				if(!type.constraints().allowNull()){
					sbf.append(" not null");
				}
			}
			sbf.append(","); //說明這一個欄位拼接完成
		}
		String sql = sbf.toString();
		sql = sql.substring(0, sql.lastIndexOf(",")) + ")";
		return sql;
	}
}

測試結果

sql語句正常輸出建立完成:

create table StuInfo(sno int primary key auto_increment,sname varchar(20) unique not null,tel varchar(15) unique,sex varchar(4) not null,addr varchar(100))
建立完成...

檢查puma資料庫是否創好stuinfo表