用反射模擬Hibernate保存JavaBean
用反射模擬Hibernate保存JavaBean
首先要說一下思想。就是要接收一個JavaBean實例對象,然后根據字段信息、類名信息,自己組組織成sql語句最后保存到數據庫中。
組件說明:
需要一個@Table注解,自己聲明,以便于用戶聲明的表名與數據庫的表名不致的情況。
此注解應該包含一個屬性,以便于指定表名。
需要聲明一個@Column注解,自己聲明以便于用戶聲明的字段名與JavaBean的列名不一致的情況。
此注解也應該包含一個屬性,以便于指定字段名。如果需要還可以指定數據類型。
上代碼:
1:@Table注解
package cn.itcast.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(value=ElementType.TYPE)
public @interface Table {
public String value();//聲明一個屬性
}
2:@Column注解
package cn.itcast.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(value=ElementType.FIELD)
public @interface Column {
public String value() default "";//默認值
}
3:工具類代碼:接收對象,直接保存:
package cn.itcast.anno;
import java.lang.reflect.Field;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
/**
* 這只是保存的示例
* 應該同時提供刪除,修改
* 查詢的可以直接使用DbUtils
* @author <a href="mailto:wj@itcast.cn">王健</a>
*/
public class SaveUtils {
public static void save(Object o) throws Exception{
String sql = "insert into";//聲明insert的頭
String values = " values (";//聲明values的頭
Class c = o.getClass();
boolean boo = c.isAnnotationPresent(Table.class);
if(boo){ //分析是否帶有Table注解,此外分析的還少一句不存在時的處理
Table t = (Table) c.getAnnotation(Table.class);
String vv = t.value();
System.err.println(vv);
sql+=" "+vv;
}
sql+="(";
Field[] f = c.getDeclaredFields();//獲取所有字段,來判斷是否存在@Column注解
List<Object> oo = new ArrayList<Object>();//聲明參數對象
for(Field ff:f){
if(ff.isAnnotationPresent(Column.class)){
Column col = ff.getAnnotation(Column.class);
String vv = col.value();
if(vv.equals("")){
if(sql.endsWith("(")){
sql+=ff.getName();
values+="?";
}else{
sql+=","+ff.getName();
values+=",?";
}
}else{
if(sql.endsWith("(")){
sql+=vv;
values+="?";
}else{
sql+=","+vv;
values+=",?";
}
}
ff.setAccessible(true);
oo.add(ff.get(o));
}
}
sql+=")";
values+=")";
System.err.println(sql+" "+values);//組成有效的sql語句
System.err.println("處理數據....");
PreparedStatement pst = //在正式的應用場合下,所有的Connection應該由用戶傳遞過來,以保證事務
Conn.getConn().prepareStatement(sql+values);
ParameterMetaData param = pst.getParameterMetaData();
int count = param.getParameterCount();//判斷有多少參數
System.err.println("count:"+count);
for(int i=0;i<count;i++){
pst.setObject(i+1,oo.get(i));//設置參數
}
pst.execute();//執行代碼
Conn.getConn().close();
}
}
<!--[if !supportLists]-->1、 <!--[endif]-->測試代碼:
@Test
public void testSave() throws Exception{
Stud stud = new Stud();
stud.setName("Marray");
stud.setAge(89);
stud.setAddr("中國上海");
SaveUtils.save(stud);
}
<!--[if !supportLists]-->2、 <!--[endif]-->測試結果:
student
insert into student(name,ages,addr) values (?,?,?)
處理數據....
count:3
保存成功