注記を使用したORM
1.Nutzでの注記の適用
nutzでは、データベースに対応するpojoについて、fieldとtableのcolumn間の対応を注釈で構成したり、注釈で2つのpojo間の関係を構成したりすることができます.例えば、私はPOJOという名前の「Box」を持っています.2つのフィールドが含まれています.
(1)
フィールドidの場合、@Column("boxid")はcolumn"boxid"、@Idはデータベースに対応することを示し、これはプライマリ・キーです.
(2)
この注記は、BoxとBoxInfoの2つのPOJOの間に1対多の関係があることを宣言しています.Box------>複数のBoxInfo、つまり1つのboxidを指定すると、BoxInfoに対応するtableに複数のレコードを見つけることができ、「boxId」を通じて「Box」に関連付けることができます.この例をはっきり言わなかったらnutzプロジェクトのwikiを参考にして、もっと実用的な注釈と紹介を見つけることができます.
2.注釈の簡単な紹介
その前に注釈を使ったことがあると信じています.junit 4、hibernate 3などのフレームワークやツールを使ったことがあると思います.少なくとも@Overrideを使ったことがあります(これを使ったことがないとは信じません).
Annotationはjdk 1です.5導入され、その導入はsrc、classまたはruntimeレベルでプログラムの情報を増加させる新しい手段を与えた.プログラマーは自分でAnnotationを定義して自分のプログラムに使用することができます.もちろん、自分のAnnotationプロセッサを作成する必要があります.
3.簡単な例
(3.1)もし私が2つのAnnotation(@Table Name,@Column)を定義してPOJOに使用したい場合、@Table NameはPOJOのクラスに使用し、データベースに対応するどのtableに対応するかを宣言し、@ColumnはPOJOのfieldに使用し、対応するcolumnを示すために使用する場合、私はこのようにすることができます.
@Target(ElementType.TYPE)は、「クラス、インタフェース(注釈タイプを含む)または列挙宣言」であることを説明し、JDKAPIを開き、「java.lang.annotation.ElementType」を探しに行くと、より多くのオプションのTargetが見つかります.
@Retention(RetentionPolicy.RUNTIME)は、「コンパイラはクラスファイルにコメントを記録し、実行時にVMはコメントを保持するので、反射的に読み取ることができる」ことを示しています.
もう1つ定義します
(3.2)この2つの注釈を私のcodeに適用する
(3.3)プロセッサを書き、この2つの注釈を用いたPOJOのためにInsert文を生成したい場合は、そうすることができます.(例を複雑にしないために、ここでは最も無邪気で幼稚な状況だけを考慮し、すべてのコードを1つにして、どういう意味かを理解すればいい).
意外なことに、出力は「INSERT INTO tbl_user(id,name,userAge)VALuES(1,Tom,12)」であるはずです.この例では、多くの問題が見つかります.
(1)コード構造差(2)異常処理差(3)sql文にstringタイプに引用符が付けられていないため、結果は一致しません.(4).....
しかし、もしあなたが以前Annotationについて特に理解していなかったら、本文がレンガを投げて玉を引く役割を果たすことを望んでいます.
最後に、Nutzのdao機能を使って、Annotationが私たちに与えた便利さを体験することができます.http://code.google.com/p/nutz/
nutzでは、データベースに対応するpojoについて、fieldとtableのcolumn間の対応を注釈で構成したり、注釈で2つのpojo間の関係を構成したりすることができます.例えば、私はPOJOという名前の「Box」を持っています.2つのフィールドが含まれています.
(1)
@Column("boxid")
@Id
private int id;
フィールドidの場合、@Column("boxid")はcolumn"boxid"、@Idはデータベースに対応することを示し、これはプライマリ・キーです.
(2)
@Many(target = BoxInfo.class, field = "boxId")
private BoxInfo[] infos;
この注記は、BoxとBoxInfoの2つのPOJOの間に1対多の関係があることを宣言しています.Box------>複数のBoxInfo、つまり1つのboxidを指定すると、BoxInfoに対応するtableに複数のレコードを見つけることができ、「boxId」を通じて「Box」に関連付けることができます.この例をはっきり言わなかったらnutzプロジェクトのwikiを参考にして、もっと実用的な注釈と紹介を見つけることができます.
2.注釈の簡単な紹介
その前に注釈を使ったことがあると信じています.junit 4、hibernate 3などのフレームワークやツールを使ったことがあると思います.少なくとも@Overrideを使ったことがあります(これを使ったことがないとは信じません).
Annotationはjdk 1です.5導入され、その導入はsrc、classまたはruntimeレベルでプログラムの情報を増加させる新しい手段を与えた.プログラマーは自分でAnnotationを定義して自分のプログラムに使用することができます.もちろん、自分のAnnotationプロセッサを作成する必要があります.
3.簡単な例
(3.1)もし私が2つのAnnotation(@Table Name,@Column)を定義してPOJOに使用したい場合、@Table NameはPOJOのクラスに使用し、データベースに対応するどのtableに対応するかを宣言し、@ColumnはPOJOのfieldに使用し、対応するcolumnを示すために使用する場合、私はこのようにすることができます.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName{
String value();
}
@Target(ElementType.TYPE)は、「クラス、インタフェース(注釈タイプを含む)または列挙宣言」であることを説明し、JDKAPIを開き、「java.lang.annotation.ElementType」を探しに行くと、より多くのオプションのTargetが見つかります.
@Retention(RetentionPolicy.RUNTIME)は、「コンパイラはクラスファイルにコメントを記録し、実行時にVMはコメントを保持するので、反射的に読み取ることができる」ことを示しています.
もう1つ定義します
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value() default "";
}
(3.2)この2つの注釈を私のcodeに適用する
@TableName("tbl_user")
public class User {
@Column
private int id;
@Column
private String name;
@Column("age")
private int userAge;
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getUserAge() {return userAge;}
public void setUserAge(int userAge) {this.userAge = userAge;}
}
(3.3)プロセッサを書き、この2つの注釈を用いたPOJOのためにInsert文を生成したい場合は、そうすることができます.(例を複雑にしないために、ここでは最も無邪気で幼稚な状況だけを考慮し、すべてのコードを1つにして、どういう意味かを理解すればいい).
public class SqlGetter {
public static void main(String[] args) throws Exception {
User user = new User();
user.setId(1);
user.setName("Tom");
user.setUserAge(12);
System.out.println(new SqlGetter().getInsertSql(user));
}
public String getInsertSql(Object obj) throws Exception {
// table
String tableName=obj.getClass().getAnnotation(TableName.class).value();
// column---value
HashMap<String, Object> kvs = new HashMap<String, Object>();
Field[] fs = obj.getClass().getDeclaredFields();
for (Field f : fs) {
String cn = this.getFieldColumn(f);
if (cn != null) {
kvs.put(f.getName(), this.getFieldValue(obj,f));
}
}
// SQl
StringBuilder prefix = new StringBuilder();
StringBuilder suffix = new StringBuilder();
for(Iterator<String> it=kvs.keySet().iterator();it.hasNext();){
String key=it.next();
prefix.append(key);
suffix.append(kvs.get(key));
if (it.hasNext()) {
prefix.append(",");
suffix.append(",");
}
}
return String.format("INSERT INTO %s (%s) VALUES (%s)", tableName,prefix,suffix);
}
private String getFieldColumn(Field field) {
Column column = field.getAnnotation(Column.class);
if (column != null) {
if ("".equals(column.value()))
return field.getName();
else {
return column.value();
}
}
return null;
}
private Object getFieldValue(Object obj,Field field) throws Exception {
String name = field.getName();
String c = name.substring(0, 1);
name = name.replaceFirst(c, c.toUpperCase());
Method m = obj.getClass().getMethod("get" + name, new Class<?>[] {});
return m.invoke(obj, new Object[] {});
}
}
意外なことに、出力は「INSERT INTO tbl_user(id,name,userAge)VALuES(1,Tom,12)」であるはずです.この例では、多くの問題が見つかります.
(1)コード構造差(2)異常処理差(3)sql文にstringタイプに引用符が付けられていないため、結果は一致しません.(4).....
しかし、もしあなたが以前Annotationについて特に理解していなかったら、本文がレンガを投げて玉を引く役割を果たすことを望んでいます.
最後に、Nutzのdao機能を使って、Annotationが私たちに与えた便利さを体験することができます.http://code.google.com/p/nutz/