- 浏览: 73501 次
- 性别:
- 来自: 长沙
-
最新评论
-
kuchaguangjie:
好哎!!!!
Eclipse添加DTD文件实现xml的自动提示功能 -
jay263677313:
不错,刚好用上了!
Eclipse添加DTD文件实现xml的自动提示功能 -
ocaicai:
很有爱,很有爱
Eclipse添加DTD文件实现xml的自动提示功能 -
爪哇岛岛主:
哎,楼主,绝对的新手啊,鼓励一下!
iBATIS 初探 -
蛋呢823:
king130520 写道苍山洱海 写道这个应该省去了hibe ...
iBATIS 初探
之前, 在做web 个人blog项目的时候,
数据库那里设置了三个表 ---- userinfo, article, comment
然后,在项目里写了个pojo包, dao包.
里面 分别都有三个表的 对应的 实现类 和 操作类 ,
这样, 即使是只写 基本的 CRUD操作. 也都要写3遍.
代码量,复杂程度 可想而知 ...
现在, 利用 java 灵活的反射功能.
可以 很灵活的 通过反射 判断一个对象的类
从而 实现 智能分析的功能.
举个例子, 通过一个例子 比较一下:
任务: 往数据库里 分别添加一个 user对象, 一个article对象, 一个comment对象
之前:
- 调用 user 的dao类 的save方法. eg: userDao.save(user);
- 调用 article 的dao类 的save方法. eg: articleDao.save(article);
- 调用comment 的dao类 的save方法. eg: commentDao.save(comment);
现在:
- save(user);
- save(article);
- save(comment);
是不是很省事???
来看看具体的代码 是怎么实现的吧...
先大致的介绍一下这个东东的基本功能....
1. 增加对象. .
/** * 保存一个对象的 方法. * @param obj: 要保存的对象 */ public static boolean save (Object obj){}
sql = insert into obj.类名 (属性1,属性2,...) values (值1,值2, ...) ;
2. 删除对象..
/** * 删除一个对象的方法 * @param id: 要删除的数据的ID, * @param c : 要删除的数据的类型. */ public static boolean delete (int id , Class c){}
sql = delete from 类名 where id= id;
3. 修改对象的属性值
/** * 修改一个对象的信息的方法 * @param obj: 传入修改后的对象 */ public static boolean modify (Object obj){}
sql = update obj.类名 set 属性1=值1,属性2=值2,... where id = obj.getId;
4. 查找---某一类型的全部对象
/** * 查找某一个类型的所有对象. select * from 表名; * * @return : 对象的队列 */ public static List selectAll(Class c) {}
sql = select * from 类名;
5. 查找--- 根据某些属性 模糊查找
/** * 根据一个模板来查找对象 可以理解成为多条件查找. eg: 查找 age=20, name="Lilei" 的用户 * * @param obj */ public static List selectBySample(Object obj) {}
sql = select * from 类名 where 属性1 = 值1 and 属性2 like 值2 ...;
(int型 就用等号连接, string型 则模糊查找 用like 连接)
6. 查找--- 根据id 来查找
/** * 通过唯一的 主键 id 查找对象的方法 * * @param id: id * @param c : 要查找的类型 * @return : 返回对象 */ public static Object selectById(int id, Class c) {}
sql = select * from 类名 where id = id;
目前只写了这么多功能...
相信多花点心思下去, 可以写得更好的...
大家可能注意到, 上面的每一个功能下面 我都添加了个 sql 的注释..
因为, 在现在看来.
下面的代码, 所干的事情, 就是 :
- 拼凑一条 符合操作要求的 sql ;
- 执行sql 语句;
- 返回结果;
- 对结果 进行处理 --- (对于selec 语句: 把得到的属性值 赋值给一个对象, 返回这个对象, 或者这个对象队列..)
其中 写出 一句 正确的 sql 语句是 很关键的一步...
具体实现. 就看看下面的代码吧...
package orm; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.Date; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; /** * 山寨hibernate的实现. 实现ORM 功能 * * @author 小奇 * */ public class HibernateORM { /** * 保存一个对象的 方法. * * @param obj * : 要保存的对象 */ public static boolean save(Object obj) { // 1.拼凑一条 保存的sql语句 insert into 类名 (属性1,属性2,...) values (值1,值2, ...) ; String sql = "insert into "; // 得到对象的类 Class c = obj.getClass(); // 得到类名 也就是表名 String cName = c.getName(); sql += cName.substring(cName.lastIndexOf(".") + 1, cName.length()); // 得到类中的所有方法的队列 java.lang.reflect.Method[] methods = c.getMethods(); List<Method> gets = new ArrayList<Method>(); for (Method m : methods) { String s = m.getName(); // 判断是否为 get 方法 而且 不是getClass 方法 if (s.startsWith("get") && !s.equals("getClass")) { try { // int类型的默认值是 0; 所以必须去除这种 默认值的.. if ((m.invoke(obj, null) != null) && !m.invoke(obj, null).equals(0)) { gets.add(m); System.out.println("------>方法名:" + s); } } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (InvocationTargetException e1) { e1.printStackTrace(); } } } String properties = "("; String values = "("; for (int i = 0; i < gets.size(); i++) { Method m = gets.get(i); // 先判断属性值 是否为null 如果为null 则没必要继续写入语句 try { String s = m.getName(); // 得到属性名 即get后面的字符串 String fName = s.substring(3, s.length()); if (i != gets.size() - 1) { properties += fName + " , "; } else properties += fName + ") "; // 执行get方法 // 判断get方法的返回类型 Class re = m.getReturnType(); String value; if (re.getName().equals("int")) { // 如果是int 类型, 则直接添加就行. value = ((Integer) m.invoke(obj, null)).toString(); if (i != gets.size() - 1) { values += value + ","; } else values += value + ")"; } else if (re.getName().equals("String")) { // 如果是String类型 // 则要记得加单引号 ' ' value = (String) m.invoke(obj, null); if (i != gets.size() - 1) { values += "'" + value + "' ,"; } else values += "'" + value + "' )"; } else { System.out.println("未知的数据类型... 暂时不支持"); } } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (InvocationTargetException e1) { e1.printStackTrace(); } } sql += properties + "values" + values; System.out.println("得到的sql语句是: " + sql); // 2. 连接数据库 Connection conn = dbConn.DBUtil.getConn(); // 3. 执行sql 语句 try { java.sql.Statement stmt = conn.createStatement(); int t = stmt.executeUpdate(sql); if (t == 1) { System.out.println("保存成功!"); return true; } else { System.out.println("删除失败!"); } } catch (SQLException e) { e.printStackTrace(); } // 4. 返回结果 return false; } /** * 删除一个对象的方法 */ public static boolean delete(int id, Class c) { // 1.拼凑一条 保存的sql语句 delete from 类名 where id = id ; String sql = "delete from "; // 得到类名 也就是表名 String cName = c.getName(); sql += cName.substring(cName.lastIndexOf(".") + 1, cName.length()); sql += " where id = " + id; System.out.println("得到的sql语句是: " + sql); // 2. 连接数据库 Connection conn = dbConn.DBUtil.getConn(); // 3. 执行sql 语句 try { java.sql.Statement stmt = conn.createStatement(); int i = stmt.executeUpdate(sql); if (i == 1) { System.out.println("删除成功!"); return true; } else { System.out.println("删除失败!"); } } catch (SQLException e) { e.printStackTrace(); } // 4. 返回结果 return false; } /** * 修改一个对象的信息的方法 */ public static boolean modify(Object obj) { // 1.拼凑一条 保存的sql语句 String sql = "update "; int id = 0; // 得到对象的类 Class c = obj.getClass(); // 得到类名 也就是表名 String cName = c.getName(); sql += cName.substring(cName.lastIndexOf(".") + 1, cName.length()); sql += " set "; // 得到类中的所有方法的队列 java.lang.reflect.Method[] methods = c.getMethods(); List<Method> gets = new ArrayList<Method>(); for (Method m : methods) { String s = m.getName(); System.out.println("--->方法名:" + s); // 判断是否为 get 方法 而且 不是getClass 方法 if (s.startsWith("get") && !s.equals("getClass")) { try { // 先判断属性值 是否为null或者初始值"0" , 如果是 , 则没必要继续写入语句 if (m.invoke(obj, null) != null && !m.invoke(obj, null).equals(0)) { gets.add(m); System.out.println("------>方法名:" + s); } } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (InvocationTargetException e1) { e1.printStackTrace(); } } } for (int i = 0; i < gets.size(); i++) { Method m = gets.get(i); try { // 如果是 getId 方法. 则得到id. if (m.getName().equalsIgnoreCase("getId")) { id = (Integer) m.invoke(obj, null); } else { String s = m.getName(); // 得到属性名 即get后面的字符串 String fName = s.substring(3, s.length()); sql += fName + "="; // 执行get方法 // 判断get方法的返回类型 Class re = m.getReturnType(); String value; if (re.getName().equals("int")) { // 如果是int 类型, 则直接添加就行. value = ((Integer) m.invoke(obj, null)).toString(); if (i != gets.size() - 1) { sql += value + ","; } else sql += value; } else { // 如果是String类型 则要记得加单引号 ' ' value = (String) m.invoke(obj, null).toString(); if (i != gets.size() - 1) { sql += "'" + value + "' ,"; } else sql += "'" + value + "'"; } } } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (InvocationTargetException e1) { e1.printStackTrace(); } } sql += " where id = " + id; System.out.println("得到的sql语句是: " + sql); // 2. 连接数据库 Connection conn = dbConn.DBUtil.getConn(); // 3. 执行sql 语句 try { java.sql.Statement stmt = conn.createStatement(); int i = stmt.executeUpdate(sql); if (i == 1) { System.out.println("更改信息成功!"); return true; } else { System.out.println("更改信息失败!"); } } catch (SQLException e) { e.printStackTrace(); } // 4. 返回结果 return false; } /** * 根据一个模板来查找对象 可以理解成为多条件查找. eg: 查找 age=20, name="Lilei" 的用户 * * @param obj */ public static List selectBySample(Object obj) { // 即将返回的 队列.... List list = new ArrayList(); String sql = "select * from "; Class c = obj.getClass(); String cName = c.getName(); sql += cName.substring(cName.lastIndexOf(".") + 1, cName.length()) + " where "; // 得到类中的所有方法的队列 java.lang.reflect.Method[] methods = c.getMethods(); List<Method> gets = new ArrayList<Method>(); List<Method> sets = new ArrayList<Method>(); for (Method m : methods) { String s = m.getName(); if (s.startsWith("set")) { // 添加 set 方法进入队列 sets.add(m); System.out.println("--- >set方法名:" + s); String field = s.substring(3); for (Method sm : methods) { if (sm.getName().equals("get" + field)) { // 添加 get 方法 进入队列 gets.add(sm); System.out.println("------>get方法名:" + sm.getName()); } } } } for (int i = 0; i < gets.size(); i++) { Method get = gets.get(i); try { // 先判断 sample里面的非初始化的值 if (get.invoke(obj, null) != null && !get.invoke(obj, null).equals(0)) { String name = get.getName(); // 得到属性名 即get后面的字符串 String fName = name.substring(3, name.length()); // 执行get方法 // 判断get方法的返回类型 Class re = get.getReturnType(); String value; if (re.getName().equals("int")) { // 如果是int 类型, 则直接添加就行. value = ((Integer) get.invoke(obj, null)).toString(); sql += fName + "="; // 如果是 int 型, 则用"=" 连接 sql += value + " and "; } else { // 如果是String类型 则要记得加单引号 ' ' value = (String) get.invoke(obj, null).toString(); sql += fName + " like "; // 如果是 string 型, 则用"=" 连接 sql += "'%" + value + "%' and "; } } } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (InvocationTargetException e1) { e1.printStackTrace(); } } // 输出sql语句 测试 记得去掉最后的 "and" 三个字符 sql = sql.substring(0, sql.length() - 4); System.out.println("得到的sql 语句是: " + sql); // 执行sql 语句 Connection conn = dbConn.DBUtil.getConn(); try { java.sql.Statement stmt = conn.createStatement(); java.sql.ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { // 创建这个类型的新对象 Object o = c.newInstance(); // 给这个对象 设置属性. 赋值 for (int i = 0; i < sets.size(); i++) { Method set = sets.get(i); Method getM = gets.get(i); // 得到set 方法名字 eg: setAge String mName = set.getName(); System.out.println("得到的set 方法是: " + mName); // 得到属性名字 eg: Age --> age String fName = mName.substring(3, 4).toLowerCase() + mName.substring(4); Class re = getM.getReturnType(); System.out.println("set方法返回类型是: " + re.getName()); if (re.getName().equals("int")) { // 如果是int 类型 int param = rs.getInt(fName); System.out.println(" rs 得到的是: " + param); set.invoke(o, param); } else if (re.getName().equals("java.lang.String")) { // 如果是String类型 String param = rs.getString(fName); if (param != null) { // 如果rs得到的不是null set.invoke(o, param); } } else if (re.getName().equals("java.sql.Date")) { Date param = rs.getDate(fName); if (param != null) { // 如果rs得到的不是null set.invoke(o, param); } } } // 把对象加入 队列中... list.add(o); } } catch (Exception e) { e.printStackTrace(); } return list; } /** * 查找某一个类型的所有对象. select * from 表名; * * @return : 对象的队列 */ public static List selectAll(Class c) { // 即将返回的 队列.... List list = new ArrayList(); String sql = "select * from "; String cName = c.getName(); sql += cName.substring(cName.lastIndexOf(".") + 1); // 得到类中的所有方法的队列 java.lang.reflect.Method[] methods = c.getMethods(); List<Method> gets = new ArrayList<Method>(); List<Method> sets = new ArrayList<Method>(); for (Method m : methods) { String s = m.getName(); if (s.startsWith("set")) { // 添加 set 方法进入队列 sets.add(m); System.out.println("--- >set方法名:" + s); String field = s.substring(3); for (Method sm : methods) { if (sm.getName().equals("get" + field)) { // 添加 get 方法 进入队列 gets.add(sm); System.out.println("------>get方法名:" + sm.getName()); } } } } // 输出sql语句 测试 System.out.println("得到的sql 语句是: " + sql); // 执行sql 语句 Connection conn = dbConn.DBUtil.getConn(); try { java.sql.Statement stmt = conn.createStatement(); java.sql.ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { // 创建这个类型的新对象 Object o = c.newInstance(); // 给这个对象 设置属性. 赋值 for (int i = 0; i < sets.size(); i++) { Method set = sets.get(i); Method getM = gets.get(i); // 得到set 方法名字 eg: setAge String mName = set.getName(); System.out.println("得到的set 方法是: " + mName); // 得到属性名字 eg: Age --> age String fName = mName.substring(3, 4).toLowerCase() + mName.substring(4); Class re = getM.getReturnType(); System.out.println("set方法返回类型是: " + re.getName()); if (re.getName().equals("int")) { // 如果是int 类型 int param = rs.getInt(fName); System.out.println(" rs 得到的是: " + param); set.invoke(o, param); } else if (re.getName().equals("java.lang.String")) { // 如果是String类型 String param = rs.getString(fName); if (param != null) { // 如果rs得到的不是null set.invoke(o, param); } } else if (re.getName().equals("java.sql.Date")) { Date param = rs.getDate(fName); if (param != null) { // 如果rs得到的不是null set.invoke(o, param); } } } // 把对象加入 队列中... list.add(o); } } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (InvocationTargetException e1) { e1.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } return list; } /** * 通过唯一的 主键 id 查找对象的方法 * * @param id * : id * @param c * : 要查找的类型 * @return : 返回对象 */ public static Object selectById(int id, Class c) { String sql = "select * from "; String cName = c.getName(); sql += cName.substring(cName.lastIndexOf(".") + 1) + " where id = " + id; // 得到类中的所有方法的队列 java.lang.reflect.Method[] methods = c.getMethods(); List<Method> gets = new ArrayList<Method>(); List<Method> sets = new ArrayList<Method>(); for (Method m : methods) { String s = m.getName(); if (s.startsWith("set")) { // 添加 set 方法进入队列 sets.add(m); System.out.println("--- >set方法名:" + s); String field = s.substring(3); for (Method sm : methods) { if (sm.getName().equals("get" + field)) { // 添加 get 方法 进入队列 gets.add(sm); System.out.println("------>get方法名:" + sm.getName()); } } } } // 输出sql语句 测试 System.out.println("得到的sql 语句是: " + sql); // 执行sql 语句 Connection conn = dbConn.DBUtil.getConn(); try { java.sql.Statement stmt = conn.createStatement(); java.sql.ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { // 创建这个类型的新对象 Object o = c.newInstance(); // 给这个对象 设置属性. 赋值 for (int i = 0; i < sets.size(); i++) { Method set = sets.get(i); Method getM = gets.get(i); // 得到set 方法名字 eg: setAge String mName = set.getName(); System.out.println("得到的set 方法是: " + mName); // 得到属性名字 eg: Age --> age String fName = mName.substring(3, 4).toLowerCase() + mName.substring(4); Class re = getM.getReturnType(); System.out.println("set方法返回类型是: " + re.getName()); if (re.getName().equals("int")) { // 如果是int 类型 int param = rs.getInt(fName); System.out.println(" rs 得到的是: " + param); set.invoke(o, param); } else if (re.getName().equals("java.lang.String")) { // 如果是String类型 String param = rs.getString(fName); if (param != null) { // 如果rs得到的不是null set.invoke(o, param); } } else if (re.getName().equals("java.sql.Date")) { Date param = rs.getDate(fName); if (param != null) { // 如果rs得到的不是null set.invoke(o, param); } } } return o; } } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (InvocationTargetException e1) { e1.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } return null; } }
相关推荐
【标题】"看我山寨版 hibernate 简单实现 一" 这篇文章的主题是作者尝试模仿 Hibernate 框架的功能,创建一个简单的实现。Hibernate 是一个流行的关系对象映射(ORM)框架,它允许 Java 开发人员将数据库操作与对象...
"山寨版当当网 struts+hibernate"是一个基于Struts和Hibernate框架构建的简易电子商务平台,模拟了知名电商网站当当网的部分功能。在这个项目中,开发者使用了Struts作为前端MVC(Model-View-Controller)框架,以及...
使用java和hibernate做到山寨qq
【Java Struts+Hibernate 实现的山寨版当当网系统】是一个基于MVC设计模式的电子商务平台,旨在模拟和学习当当网的核心功能。在这个系统中,开发者利用Java的Struts框架来处理用户请求和控制应用程序流程,同时借助...
【电信计费系统(山寨版)】是一款基于Java技术栈实现的计费系统,它集成了Struts2、Spring和Hibernate三个主流的开源框架,即所谓的SSH(Struts2 + Spring + Hibernate)架构。SSH框架在企业级开发中广泛应用,因其...
6. **实战项目**:如“山寨QQ项目”、“满汉楼餐饮系统”和“网上商城”等,这些视频教程提供了实际项目开发的经验,有助于提升开发者将理论知识应用于实际问题的能力。 7. **面试准备**:包括了“JAVA就业面试题...
这个项目采用了经典的Java技术栈,包括JavaServer Pages (JSP)、Struts框架以及Hibernate持久层框架,这些都是Java Web开发中的核心组件。 【JSP(JavaServer Pages)】是一种动态网页技术,允许开发者在HTML页面中...
作品吹牛: ...通用Hibernate Dao 最后真心话! 力行 一个星期完成! 第一次 心血之作 所以望大家体谅给点支持! 好请给予支持,坏请给予批评并且指正! 在次感谢大家的支持。。。 留言QQ:308117229
本文将详细探讨一个自编的Hibernate实现——myHibernate,旨在帮助读者理解Hibernate的基本工作原理,并从中获得对ORM框架更深层次的理解。 首先,myHibernate项目实现了Hibernate的核心功能,包括对象的持久化、...
SSH框架,全称为Struts2、Spring和Hibernate的组合,是Java Web开发中常用的一种开源框架。这个框架的集成使得开发者能够更有效地处理MVC(Model-View-Controller)架构,事务管理,以及对象持久化等问题。在描述中...
在这个场景下,我们将讨论如何在SSH(Spring、Struts2和Hibernate)框架中配置第三方支付的银联支付接口。 首先,SSH框架是Java Web开发中常用的MVC架构,Spring负责依赖注入和事务管理,Struts2负责控制层逻辑,...
Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket...
Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket...
Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket...
Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证用户登录,创建一个该qq号和服务器端保持通讯连接得线程,启动该通讯线程,通讯完毕,关闭Scoket...
Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证...
Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和客户端,典型C/S结构, 当用户发送第一次请求的时候,验证...