用反射模拟Hibernate保存JavaBean
1 用反射模拟Hibernate保存JavaBean 2 首先要说一下思想。就是要接收一个JavaBean实例对象,然后根据字段信息、类名信息,自己组组织成sql语句最后保存到数据库中。 3 组件说明: 4 需要一个@Table注解,自己声明,以便于用户声明的表名与数据库的表名不致的情况。 5 此注解应该包含一个属性,以便于指定表名。 6 需要声明一个@Column注解,自己声明以便于用户声明的字段名与JavaBean的列名不一致的情况。 7 此注解也应该包含一个属性,以便于指定字段名。如果需要还可以指定数据类型。 8 上代码: 9 1:@Table注解 10 package cn.project.anno; 11 import java.lang.annotation.ElementType; 12 import java.lang.annotation.Retention; 13 import java.lang.annotation.RetentionPolicy; 14 import java.lang.annotation.Target; 15 @Retention(RetentionPolicy.RUNTIME) 16 @Target(value=ElementType.TYPE) 17 public @interface Table { 18 public String value();//声明一个属性 19 } 20 2:@Column注解 21 package cn..project.anno; 22 import java.lang.annotation.ElementType; 23 import java.lang.annotation.Retention; 24 import java.lang.annotation.RetentionPolicy; 25 import java.lang.annotation.Target; 26 @Retention(RetentionPolicy.RUNTIME) 27 @Target(value=ElementType.FIELD) 28 public @interface Column { 29 public String value() default "";//默认值 30 } 31 3:工具类代码:接收对象,直接保存: 32 package cn.project.anno; 33 import java.lang.reflect.Field; 34 import java.sql.ParameterMetaData; 35 import java.sql.PreparedStatement; 36 import java.util.ArrayList; 37 import java.util.List; 38 /** 39 * 这只是保存的示例 40 * 应该同时提供删除,修改 41 * 查询的可以直接使用DbUtils 42 * @author <a href="mailto:wj@itcast.cn">王健</a> 43 */ 44 public class SaveUtils { 45 public static void save(Object o) throws Exception{ 46 String sql = "insert into";//声明insert的头 47 String values = " values (";//声明values的头 48 Class c = o.getClass(); 49 boolean boo = c.isAnnotationPresent(Table.class); 50 if(boo){ //分析是否带有Table注解,此外分析的还少一句不存在时的处理 51 Table t = (Table) c.getAnnotation(Table.class); 52 String vv = t.value(); 53 System.err.println(vv); 54 sql+=" "+vv; 55 } 56 sql+="("; 57 Field[] f = c.getDeclaredFields();//获取所有字段,来判断是否存在@Column注解 58 List<Object> oo = new ArrayList<Object>();//声明参数对象 59 for(Field ff:f){ 60 if(ff.isAnnotationPresent(Column.class)){ 61 Column col = ff.getAnnotation(Column.class); 62 String vv = col.value(); 63 if(vv.equals("")){ 64 if(sql.endsWith("(")){ 65 sql+=ff.getName(); 66 values+="?"; 67 }else{ 68 sql+=","+ff.getName(); 69 values+=",?"; 70 } 71 }else{ 72 if(sql.endsWith("(")){ 73 sql+=vv; 74 values+="?"; 75 }else{ 76 sql+=","+vv; 77 values+=",?"; 78 } 79 } 80 ff.setAccessible(true); 81 oo.add(ff.get(o)); 82 } 83 } 84 sql+=")"; 85 values+=")"; 86 System.err.println(sql+" "+values);//组成有效的sql语句 87 System.err.println("处理数据...."); 88 PreparedStatement pst = //在正式的应用场合下,所有的Connection应该由用户传递过来,以保证事务 89 Conn.getConn().prepareStatement(sql+values); 90 ParameterMetaData param = pst.getParameterMetaData(); 91 int count = param.getParameterCount();//判断有多少参数 92 System.err.println("count:"+count); 93 for(int i=0;i<count;i++){ 94 pst.setObject(i+1,oo.get(i));//设置参数 95 } 96 pst.execute();//执行代码 97 Conn.getConn().close(); 98 } 99 } 100 1、测试代码: 101 @Test 102 public void testSave() throws Exception{ 103 Stud stud = new Stud(); 104 stud.setName("Marray"); 105 stud.setAge(89); 106 stud.setAddr("中国上海"); 107 SaveUtils.save(stud); 108 } 109 2、测试结果: 110 student 111 insert into student(name,ages,addr) values (?,?,?) 112 处理数据.... 113 count:3 114 保存成功