java EE开发之Servlet第十一课:反射基础三
来源:互联网 发布:ubuntu vi编辑器 编辑:程序博客网 时间:2024/05/16 15:55
1 .使用反射机制形成通用sql语句
1)构建insert语句
public static void save(Object obj) { // 获取传递过来对象的Class类对象 Class c = obj.getClass(); // 获取数据库连接 Connection conn = getConn(); // 准备执行SQL语句的对象(车、船) PreparedStatement pstmt = null; // 获取类对象的所有声明了的属性 Field[] fs = c.getDeclaredFields(); // 解锁 Field.setAccessible(fs, true); // 根据获得的类对象,拼SQL语句 StringBuffer sb = new StringBuffer(); sb.append("insert into "); // 表名 sb.append(c.getSimpleName()); sb.append(" values( "); // 拼SQL语句有多少个问号 for (int i = 1; i < fs.length; i++) { sb.append(" ? "); if (i < fs.length - 1) { sb.append(" , "); } } sb.append(" ) "); try { // 初始化执行SQL语句的对象 pstmt = conn.prepareStatement(sb.toString()); // 给问号进行赋值 for (int i = 1; i < fs.length; i++) { pstmt.setObject(i, fs[i].get(obj)); } // 执行SQL语句 pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } finally { closeAll(conn, pstmt, null); } System.out.println(sb);}
2)构建select语句
public List<T> queryFX(Class<T> clazz) { List<T> list = new ArrayList<T>(); // 获取传递过来对象的类对象 //Class c = obj.getClass(); Connection conn = getConn(); PreparedStatement pstmt = null; ResultSet rs = null; // 获取声明的属性 Field[] fs = clazz.getDeclaredFields(); // 解锁 Field.setAccessible(fs, true); // 拼SQL StringBuffer sb = new StringBuffer(); sb.append(" select * from tbl_"); sb.append(clazz.getSimpleName()); // 初始化执行SQL语句的对象 try { pstmt = conn.prepareStatement(sb.toString()); rs = pstmt.executeQuery(); // 从结果集中获取数据 while (rs.next()) { // Student stu = new Student(); T o = (T) clazz.newInstance(); // stu.setSid(rs.getInt("sid")); for (int i = 0; i < fs.length; i++) { // 获取rs中的值 Object value = rs.getObject(fs[i].getName()); // 获value值存入到对应属性中xxx.setXxx(); if (value instanceof BigDecimal) { // 将数据中类型为numeric类型的做一个和实体类型对应的转换 //value = ((BigDecimal) value).doubleValue(); value = ((BigDecimal) value).intValue(); } /* * if(value instanceof Timestamp ){ * Timestamp ts =(Timestamp)value; * value = ts.toString(); * } */ // rs.getObject()获得的数据类型为时间戳类型 // 需要转换为实体中对应的java.sql.Date类型时,需要做以下转换 if (value instanceof Timestamp) { Timestamp ts = (Timestamp) value; value = new Date(ts.getTime()); } // 把值装入到实体类中属性中 fs[i].set(o, value); } // 将对象放入到list中 list.add(o); } } catch (SQLException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } finally { closeAll(conn, pstmt, rs); } return list;}
注意: 表名和实体类名相同,表的列名和类的属性名一样。
总结:利用同样的思路,可以构建通用删除,通用更新,读者自行完成。
2 .克隆
1)普通属性不需要克隆
2) 浅度克隆:这个类中的属性没有引用另外一个类型的对象
该类必须显示的继承Object类和实现Cloneable接口,然后重写clone();就是把我们要克隆的类,实现一个Cloneable的接口,接口中无方法,只是一个标识 而已,然后写一个方法public void clone();本来是protected的,要改为public 的,这样才能在非子类中访问该方法,在main方法中,生成该类的两个对象,第一个 给他赋值,第二个就让它等于第一个对象的clone方法,这样就克隆了,第二个对象的改变不会影响第一个。
public class GrilFriend implements Cloneable { ........ @Override public Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); }}
3)深度克隆:这个类中的属性有引用另外一个类型的对象
浅克隆,只涉及到一个类的克隆;既然有浅克隆也就有深克隆,深克隆,是指:在第一个类中用到了另外的类作为属性,那样的话,当第一个类要克隆,则它所涉及的类则都要标识为克隆的,并实现从clone方法。
@Override//procted-->public public Object clone() throws CloneNotSupportedException { //调用父类的克隆方法 //称为浅度克隆 //return super.clone(); //做深度克隆 //把用户克出来 Users u = (Users)super.clone(); //把用户女友克出来 GrilFriend gf= (GrilFriend)u.getGf().clone(); //绑定用户的克隆的对象和女友有克隆对象 u.setGf(gf); return u;}
3.序列化
1)序列化作用:
当我们在电脑上玩游戏等一些事情时,然而有时我们要去有事,而此时我们退出游戏,
会有一个是否保存当前游戏的按钮,保存的是我们当前游戏的状态,例如:当前自己的位置,怪物的位置等等。
而这时我们就可以用到序列化来解决这个问题
2)序列化是什么:
就是指把java生成的一个对象(包括属性和方法),以一种对象输出流(ObjectOutputStream)的方式,写入到硬盘的文件中(writeObject(Object obj)),以后要使用到这个对象,也可以用对象输入流(ObjectInputStream)的方式读到程序中,使用(readObject())把文件中的内容恢复为一个对象,恢复的对象的数据与当初写入对象的数据一至,这样对像就可以在网络中传输,以及像游戏那样得到自己的位置,怪物的位置等等
3)怎么实现序列化
(1)需要序列化的类必须实现Serializable,但没有方法需要实现,它只是一种标示,标示该类可以序列化
(2)建立FileOutputStream,写到哪个文件里,再套用ObjectOutputStream,调用writeObject(Object o)序列化对象
(3)建立FileInputStream,读硬盘的文件,再套用ObjectInputStream,调用readObject()恢复对象
(4)可以同时写多个对象进去,那么每个对象都会给它一个标志位,用来区别,读的时候先进去先出来,后进去后出来(队列结构)
(5)static和transient是不能默认序列化,就是指凡是它们修饰的属性的值不会序列化到文件里面去,那么读出来也是为空的
(6)可以通过重写Serializable接口已经注释的方法
writeObject(ObjectOutputStream out)来序列化static和 transient修饰的属性的值,通过readObject(ObjectInputStream in),来读static和 transient修饰的属性的值这两个方法必须是private void 的,在序列化对象和读对象的时候jdk会自动去调用这两个方法,有一些注意事项看代码。
完整代码
public class Users implements Serializable{ ......... //序列化时,static和transient(瞬时态)修饰的变量,不可序列化 private static String email; private transient String phone;
序列化
Users users = new Users();users.setUid(1);users.setUname("tom");users.setAge(24);users.setPhone("13888888");users.setEmail("aa@qq.com");try { //创建对象输出流 ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("users.txt")); os.writeObject(users);} catch (FileNotFoundException e) { e.printStackTrace();} catch (IOException e) { e.printStackTrace();}
反序列化
try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("users.txt")); Users users = (Users)ois.readObject(); System.out.println(users.getUid()+"\t"+users.getUname()); System.out.println(users.getPhone()+"\t"+users.getEmail());} catch (FileNotFoundException e) { e.printStackTrace();} catch (IOException e) { e.printStackTrace();} catch (ClassNotFoundException e) { e.printStackTrace();}
- java EE开发之Servlet第十一课:反射基础三
- java EE开发之Servlet第一课
- Java EE开发第十一章:1.servlet的准备知识
- Java EE开发第十一章:2.初始servlet
- Java EE开发第十一章:4.servlet的综合小项目之实现账户密码的登陆
- java EE开发之Servlet第三课:过滤器(Filter)
- java EE开发之Servlet第四课:监听器(Listener)
- java EE开发之Servlet第五课:xml解析
- java EE开发之Servlet第六课:神奇的Ajax
- java EE开发之Servlet第七课:JNDI
- java EE开发之Servlet第十四课:自定义注解Annotation
- java ee 之 servlet
- Java EE开发第十一章:3.servlet的体系结构以及常用方法
- java EE开发之Servlet第二课:Servlet的三个hashMap
- Java EE之Servlet技术
- Java EE之Servlet技术
- java EE开发之Servlet第十二课:简单自定标签
- java EE开发之Servlet第十三课:复杂自定标签
- LeetCode-72-Edit Distance 记忆化搜索DP
- CAD转PDF怎么设置输出质量
- TCP 滑动窗口协议
- 监督学习之多变量线性回归
- Android 常用的ADB命令
- java EE开发之Servlet第十一课:反射基础三
- Spring中使用AOP
- 修改UIWebView中字体的大小,颜色
- VS2013 cryptopp 库编译LIB问题
- 2017完美世界研发部笔试题_取经
- Java中的图片压缩
- 第三周项目三
- 利用C语言的内存机制破解密码
- onclick方法和$("").click()有不一样的地方