自己动手写hibernate
这篇文章 可作为北京尚学堂 hibernate的学习笔记
再学习hibernate之前 得有一点反射的基础知识
package com.bjsxt.hibernate; public class Stu { public int id; private String name; private int age; //省略get.set方法 }
package com.bjsxt.hibernate; import java.lang.reflect.Field; import java.lang.reflect.Method; public class MyHibernate { public static void main2(String[] args) { Stu stu=new Stu(); stu.setAge(15); stu.setId(111); stu.setName("DDD"); MySession session=new MySession(); session.save(stu); } }
如上所示 其实最复杂的就是MySession里面的save方法(其实会写save 别的delete update也是一样的)
ok 咱们一步一步来 既然要和数据库打交道 最少得两个部分吧 1和数据连接 2写sql
/* 获取数据库连接的函数*/ public Connection getConnection() { Connection con = null; //创建用于连接数据库的Connection对象 try { Class.forName("com.mysql.jdbc.Driver");// 加载Mysql数据驱动 con = DriverManager.getConnection( "jdbc:mysql://localhost:3306/webexample?" + "useUnicode=true&characterEncoding=UTF-8", "root","");// 创建数据连接 } catch (Exception e) { System.out.println("数据库连接失败" + e.getMessage()); } return con; //返回所建立的数据库连接 }
第二部分组成sql就有点复杂了
insert into table (id,name,age) values(?,?,?)
最后的结果应该是这样对吧
我们已经知道实体类里面的各个属性 假定他与数据库中的各个字段名 对应(当然我们并不强调 两者必须相等 但最好相等)
既然一个是实体属性 一个是字段名 那么最好的结果就是hashmap喽
public class MySession { private Map<String, String> map; private String tableName="stu"; public MySession() { map = new HashMap<String, String>(); map.put("id", "id"); // key为实体类里面的属性名 map.put("name", "name"); // value为对应表里面的字段名字 map.put("age", "age"); } }
至于map的填充 在真正的hibernate中可以同xml也可以基于annotation 在这里不是重点 我们就直接给他默认
下面就是生成sql部分
注释掉的部分先不要看!!
public String creatSQL() { String sql; String str1 = new String(); int index = 0; for (String key : map.keySet()) { str1 += key + ","; // String v = map.get(key); // 下面是得到对应的bean中的get方法。也就是得到User类中的getId()、getUsername()、getPwd()方法。 // 注意每个属性的get后面的第一个字母是大写,需要转换。 // v = "get" + Character.toUpperCase(v.charAt(0)) + v.substring(1); // methodNames[index] = v; // 将方法保存在数组中。 // index++; } str1=str1.substring(0,str1.length()-1);//如果不加这一行会有什么后果 大家试试 String str2=new String(); for (int i = 0; i < map.size(); i++) str2+="?,"; str2=str2.substring(0, str2.length()-1); sql="insert into "+tableName +" ("+str1+ ") "+"values ("+str2+")"; return sql; }
生成的sql是带?的 也就是我们要用preparedstatement
那么我们如何填充问号
答案是 借助反射调用类里面的get方法
ok 再看看creatsql里面的注释掉的内容 应该没有疑问了吧
再下面请大家回家jdbc连数据库的基本内容
public void save(Object obj) { String sql = creatSQL(); System.out.println(sql); Connection con = getConnection(); //创建用于连接数据库的Connection对象 try { PreparedStatement st=(PreparedStatement) con.prepareStatement(sql); Method method=null; for (int j = 0; j < map.size(); j++) { method= obj.getClass().getMethod(methodNames[j]); Class<?> type=method.getReturnType(); if (type.getName().equals("java.lang.String")) { String param=(String) method.invoke(obj); st.setString(j+1, param); //为什么要加一 大家自己看看 } if (type.getName().equals("int")) { int param=(int) method.invoke(obj); st.setInt(j+1, param); } System.out.println(method.getName() + "--" + method.getReturnType()); } st.execute(); st.close(); con.close(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } }
再看看一个完整的MySession
package com.bjsxt.hibernate; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import com.mysql.jdbc.PreparedStatement; public class MySession { private Map<String, String> map; private String tableName="stu"; private String[] methodNames; public MySession() { map = new HashMap<String, String>(); map.put("id", "id"); // key为实体类里面的属性名 map.put("name", "name"); // value为对应表里面的字段名字 map.put("age", "age"); methodNames=new String[map.size()]; } public void save(Object obj) { String sql = creatSQL(); System.out.println(sql); Connection con = getConnection(); //创建用于连接数据库的Connection对象 try { PreparedStatement st=(PreparedStatement) con.prepareStatement(sql); Method method=null; for (int j = 0; j < map.size(); j++) { method= obj.getClass().getMethod(methodNames[j]); Class<?> type=method.getReturnType(); if (type.getName().equals("java.lang.String")) { String param=(String) method.invoke(obj); st.setString(j+1, param); } if (type.getName().equals("int")) { int param=(int) method.invoke(obj); st.setInt(j+1, param); } System.out.println(method.getName() + "--" + method.getReturnType()); } st.execute(); st.close(); con.close(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } /* 获取数据库连接的函数*/ public Connection getConnection() { Connection con = null; //创建用于连接数据库的Connection对象 try { Class.forName("com.mysql.jdbc.Driver");// 加载Mysql数据驱动 con = DriverManager.getConnection( "jdbc:mysql://localhost:3306/webexample?" + "useUnicode=true&characterEncoding=UTF-8", "root","");// 创建数据连接 } catch (Exception e) { System.out.println("数据库连接失败" + e.getMessage()); } return con; //返回所建立的数据库连接 } public String creatSQL() { String sql; String str1 = new String(); int index = 0; for (String key : map.keySet()) { str1 += key + ","; String v = map.get(key); // 下面是得到对应的bean中的get方法。也就是得到User类中的getId()、getUsername()、getPwd()方法。 // 注意每个属性的get后面的第一个字母是大写,需要转换。 v = "get" + Character.toUpperCase(v.charAt(0)) + v.substring(1); methodNames[index] = v; // 将方法保存在数组中。 index++; } str1=str1.substring(0,str1.length()-1); String str2=new String(); for (int i = 0; i < map.size(); i++) str2+="?,"; str2=str2.substring(0, str2.length()-1); sql="insert into "+tableName +" ("+str1+ ") "+"values ("+str2+")"; return sql; } }
在MyHibernate里面测试
结果如下
其实这里面问题最多的在于反射知识的应用
自己动手写hibernate的更多相关文章
- 【原创】自己动手写工具----XSmartNote [Beta 3.0]
一.前面的话 在动笔之前,一直很纠结到底要不要继续完成这个工具,因为上次给它码代码还是一年多之前的事情,参考自己动手写工具----XSmartNote [Beta 2.0],这篇博文里,很多园友提出了 ...
- 【原创】自己动手写控件----XSmartNote控件
一.前面的话 在上一篇博文自己动手写工具----XSmartNote [Beta 3.0]中,用到了若干个自定义控件,其中包含用于显示Note内容的简单的Label扩展控件,用于展示标签内容的labe ...
- 【原创】自己动手写工具----XSmartNote [Beta 2.0]
一.前面的话 在上一篇自己动手写工具----XSmartNote中,我简单介绍了这个小玩意儿的大致界面和要实现的功能,看了一下园子里的评论,评价褒贬不一,有人说“现在那么多云笔记的工具”,“极简版ev ...
- 【原创】自己动手写工具----签到器[Beta 2.0]
一.前面的话 上一篇中基本实现了简单的签到任务,但是不够灵活.在上一篇自己动手写工具----签到器的结尾中,我设想了几个新增功能来提高工具的灵活程度,下面把新增功能点列出来看看: (1)新增其他的进程 ...
- 自己动手写ORM的感受
之前看到奋斗前辈和时不我待前辈的自己动手写ORM系列博客,感觉讲解的通俗易懂,清晰透彻.作为一个菜鸟,闲来也想着自己写一个ORM,一来加深自己对 ORM的理解,以求对EF,NHibernate等ROM ...
- 自己动手写插件底层篇—基于jquery移动插件实现
序言 本章作为自己动手写插件的第一篇文章,会尽可能的详细描述一些实现的方式和预备知识的讲解,随着知识点积累的一点点深入,可能到了后期讲解也会有所跳跃.所以,希望知识点不是很扎实的读者或者是初学者,不要 ...
- Python - 动手写个ORM
Python - 动手写个ORM 任务: 模拟简单的ORM - Object Relational Mapping 为model添加create方法 代码很简单,直接上 字段类型类 class Fie ...
- 【转】自己动手写SC语言编译器
自序 编译原理与技术的一整套理论在整个计算机科学领域占有相当重要的地位,学习它对程序设计人员有很大的帮助.我们考究历史会发现那些人人称颂的程序设 计大师都是编译领域的高手,像写出BASIC语言的BIL ...
- 自己动手写CPU之第九阶段(8)——MIPS32中的LL、SC指令说明
将陆续上传新书<自己动手写CPU>,今天是第47篇. 9.7 ll.sc指令实现思路 9.7.1 实现思路 这2条指令都涉及到訪问链接状态位LLbit,能够将LLbit当做寄存器处理,ll ...
随机推荐
- width:100vh有感而发
在看一个网页的代码是看到 width:100vh 纳尼...这这我怎么没有见过,这是个什么属性,随之有看到 min-height:calc(100vh + 51px);这尼玛又是怎么用的.... 感 ...
- 移动端web开发中对点透的处理,以及理解fastclick如何做到去除300ms延迟
一.点透问题以及处理办法 开发中遇到一个问题,就是点击layer弹出框的取消按钮之后,按钮下方的click事件就直接触发了.直接看代码: $('.swiper-slide').on('click', ...
- Java 的异常处理机制
异常是日常开发中大家都「敬而远之」的一个东西,但实际上几乎每种高级程序设计语言都有自己的异常处理机制,因为无论你是多么厉害的程序员,都不可避免的出错,换句话说:你再牛逼,你也有写出 Bug 的时候. ...
- javascript实现图片的预览
简单javascript代码 实现上传图片预览 <body> <!-- 设置当有图片准备上传时触发javascript代码--> <input type="fi ...
- spark升级后 集成hbase-1.0.0-cdh5.4.5异常
.具体场景如下: spark1.6 升级 spark2.2 后 分析查询hbase 数据报异常: 具体错误如下: ERROR TableInputFormat: java.io ...
- Django网站制作
创建mysite目录 django-admin.py startproject mysite这个命令作用是:这将创建在当前目录创建一个mysite目录 前提是从命令行上cd到你想储存你代码的目录,然后 ...
- 使用Docker搭建GitLab
使用docker-compose快速启动GitLab.(当然前提是你先安装docker-compose,安装方式见博客:http://blog.csdn.net/yulei_qq/article/de ...
- React Native 4 for Android源码分析 一《JNI智能指针之介绍篇》
文/ Tamic: http://blog.csdn.net/sk719887916/article/details/53455441 原文:http://blog.csdn.net/eewolf/a ...
- “ML学分计划”说明书
计划的由来 我们是一群对机器学习感兴趣的小伙伴,对于神奇的机器学习经常有"一探究竟"的冲动,却因为孤身一人学习的寂寞.亦或繁忙考试工作之余的小小拖延症,而没有持续这份对知识的渴求和 ...
- Zookeeper的功能以及工作原理 (转自:http://www.cnblogs.com/felixzh/p/5869212.html)
1.ZooKeeper是什么?ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的 ...