Java注解(三)

上一篇了解了自定义注解的使用,不过里面的例子没有多大使用价值,这一回来个有用点的 Demo。

目标:将实体 bean 保存到数据库

先来定义一个实体注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Entity {
String getTableName();
}

这个注解可用在类上,它有一个变量参数 getTableName。

其实意义很明显,就是一个实体类对应一张数据库的表,通过 Entity 注解将类和数据库表名关联起来

 

那么,通过什么将类的参数和数据库表中的列关联起来呢?再来定义一个注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String getName();
}

有了 Column 注解,类里面的属性就和表中的列关联起来了。

 

下面来看看 POJO 中怎么用这两个注解:

@Entity(getTableName = "user")
public class User {
    @Column(getName = "user_id")
    private String id;
    @Column(getName = "user_name")
    private String name;
    @Column(getName = "user_age")
    private int age;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getId() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> id;
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setId(String id) {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.id =<span style="color: rgba(0, 0, 0, 1)"> id;
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getName() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> name;
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setName(String name) {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getAge() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> age;
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setAge(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> age) {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.age =<span style="color: rgba(0, 0, 0, 1)"> age;
}

}

通过 Entity 和 Column 注解,就将一个实体 bean 和一张数据库表连接起来了。很多 ORM 映射就是采取这种方式实现的。

 

最后,来感受一下注解给我们带来的便利,来个方法见证下 ~~

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;

public class Session {
public static void main(String[] args) {
Session session
= new Session();
System.out.println(session.getInsertSql(
new User()));
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">在实际项目中,你可以save(obj)方法来保存一个bean</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> save(Object obj) {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> get a connection
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">PreparedStatement pstmt = getStatement(con, obj);
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">pstmt.execute();</span>

}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">得到PreparedStatement</span>
<span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> PreparedStatement getStatement(Connection con, Object obj)
        </span><span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> Exception {
    PreparedStatement pstmt </span>=<span style="color: rgba(0, 0, 0, 1)"> con.prepareStatement(getInsertSql(obj));
    Class</span>&lt;?&gt; c =<span style="color: rgba(0, 0, 0, 1)"> obj.getClass();
    Field[] fs </span>=<span style="color: rgba(0, 0, 0, 1)"> c.getDeclaredFields();
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i &lt; fs.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
        fs[i].setAccessible(</span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
        pstmt.setObject(i </span>+ 1<span style="color: rgba(0, 0, 0, 1)">, fs[i].get(obj));
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> pstmt;
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">insert into tableName(ziduan1,ziduan2...) values(?,?...)</span>
<span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String getInsertSql(Object obj) {
    StringBuilder s </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StringBuilder();
    s.append(</span>"insert into "<span style="color: rgba(0, 0, 0, 1)">);

    Class</span>&lt;?&gt; c =<span style="color: rgba(0, 0, 0, 1)"> obj.getClass();
    String tableName </span>= c.getSimpleName();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">类名,不包含包名 User</span>
    Entity entity = (Entity) c.getAnnotation(Entity.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (entity != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
        tableName </span>=<span style="color: rgba(0, 0, 0, 1)"> entity.getTableName();
    }
    s.append(tableName).append(</span>"("<span style="color: rgba(0, 0, 0, 1)">);
    Field[] fs </span>=<span style="color: rgba(0, 0, 0, 1)"> c.getDeclaredFields();

    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i &lt; fs.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
        String fieldName </span>=<span style="color: rgba(0, 0, 0, 1)"> fs[i].getName();
        Column column </span>= fs[i].getAnnotation(Column.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (column != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
            fieldName </span>=<span style="color: rgba(0, 0, 0, 1)"> column.getName();
        }
        s </span>= i == 0 ? s.append(fieldName) : s.append(","<span style="color: rgba(0, 0, 0, 1)">).append(fieldName);
    }
    s.append(</span>") values"<span style="color: rgba(0, 0, 0, 1)">).append(getString(fs.length));
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> s.toString();

}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">得到(?,?,?,...?,?)</span>
<span style="color: rgba(0, 0, 255, 1)">private</span> String getString(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> length) {
    StringBuilder s </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> StringBuilder();
    s.append(</span>"("<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i &lt; length; i++<span style="color: rgba(0, 0, 0, 1)">) {
        s </span>= i == 0 ? s.append("?") : s.append(",?"<span style="color: rgba(0, 0, 0, 1)">);
    }
    s.append(</span>")"<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> s.toString();
}

}

 

 OK,That's all!