通过自定义注解实现自动创建表
需求分析
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 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表