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 保存成功