自己动手写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 ...
随机推荐
- You And Me 不见不散!
泰戈尔说: 有一个夜晚,我烧毁了所有的记忆, 从此我的梦就透明了: 有个早晨我扔掉了所有的昨天, 从此我的脚步就轻盈了! 越过山丘,才发现无人等候! 有段话最近很流行:20多岁的你,迷茫又着急,你想要 ...
- Tomcat,eclipse热部署的三种方式
热部署是指在你修改项目BUG的时候对JSP或JAVA类进行了修改在不重启WEB服务器前提下能让修改生效.但是对配置文件的修改除外! 怎么说呢?热部署其实用的算少了,热部署怎么说都是个人部署的,大点的公 ...
- 用background-image做成条纹背景
效果: 实现: //html <div class="container"> <span class="tip span-1">1111 ...
- npm下载包很慢和node-sass编译错误的解决办法
最近研究一个ionic cordova angular2的前端项目 发现npm install下载包非常慢的问题 最近整理了一些解决这些问题的方法. 1.通过config命令修改https为http ...
- JDBC:从原理到应用
一.是为何物 1.概念 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用J ...
- SpringMVC格式转化错误之HTTP Status [400] – [Bad Request]
SpringMVC中,如果直接为Date类型的属性赋值,服务器有可能会报HTTP Status [400] – [Bad Request] Type Status Report Description ...
- MongoDB 自动增长
MongoDB 没有像 SQL 一样有自动增长的功能, MongoDB 的 _id 是系统自动生成的12字节唯一标识. 但在某些情况下,我们可能需要实现 ObjectId 自动增长功能. 由于 Mon ...
- 分布式一致性协议Raft原理与实例
分布式一致性协议Raft原理与实例 1.Raft协议 1.1 Raft简介 Raft是由Stanford提出的一种更易理解的一致性算法,意在取代目前广为使用的Paxos算法.目前,在各种主流语言中都有 ...
- 安卓高级1 -----Xutil3 和Picasso使用
Xutils3 Xutils由于内部使用httpclient然而在安卓5.0谷歌发现httpclient出现不稳定的情况.于6.0完全弃用,所以作者升级到Xutils3替换原本网络模块 配置环境(St ...
- proc文件系统探索 之 以数字命名的目录
在proc根目录下,以数字命名的目录表示当前一个运行的进程,目录名即为进程的pid.其内的目录和文件给出了一些关于该进程的信息. niutao@niutao-desktop:/proc/6584$ l ...