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><?> 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 < 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><?> 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 < 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 < 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!