Hibernate的出现和Hinbernate的简单模拟实现
2013年4月14日,继续学习Hibernate框架
1 概念
Hibernate是一种免费的开源的Java语言下的对象关系映射解决方案
Hibernate 有个在.NET Framework 上的实现版本,称为 NHibernate
1.1 为什么出现Hibernate
l 阻抗不匹配
l 如果有对象数据库,hibernate就没用了
1.2 Hibernate在做什么
l 存储
l 查询、加载
l 缓存
体系结构图
1.3 优点
l sql语句不用写了,只需要操纵对象,使开发更对象化
l 移植性好
l 提高开发效率
l 透明持久化,不需要实现任何类,任何接口。Pojo类没有实现任何第三方的接口。即没有侵入性
l 轻量级的框架,不依赖于容器
1.4 缺点
l 额外的学习成本
l 配置麻烦
l 复杂的查询效率不高,
l 批量修改、删除效率不高
l 大量数据的查询效率不高
1.5 使用场合
l 不想写sql
l 需要跨平台。
1.6 不宜使用的场合
l 实体关系太复杂
l 需要数据库的特定优化机制
l 需要使用存储过程
l 批量更新,批量删除不适合
Hibernate的模拟实现
1. 创建Java项目:Hibernate_OR_Mapping_Simulation
2. 创建包:com.wwj.hibernate.model
3. 创建Student类
/Student.java
package com.wwj.hibernate.model;
/**
*
* @author wwj
* Student模型类
*
*/
public class Student {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
4. 创建包Test
5. 创建Test类
package test;
import com.wwj.hibernate.model.Student;
/**
*
* @author wwj
*
*/
public class Test {
public static void main(String[] args) throws Exception{
Student stu = new Student(); //定义一个Student类对象
//设置属性值
stu.setId(3);
stu.setName("lishi");
stu.setAge(22);
//生成自定义的Session对象
Session session = new Session();
//执行Session类中的save方法
session.save(stu);
}
}
6. 创建Session类
package test;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.HashMap;
import java.util.Map;
import com.wwj.hibernate.model.Student;
/**
* 模拟Hibernate中的Session实现的功能
* @author wwj
* @date 2013/4/14
*/
public class Session {
String tableName = "student"; //表名
Map<String,String> cfs = new HashMap<String, String>(); //字段名与属性一一对应的关系
String[] methodNames; //声明一个字符串数组,用来存储方法名
/**
* Session的构造方法
*/
public Session(){
cfs.put("id", "id");
cfs.put("name", "name");
cfs.put("age", "age");
methodNames = new String[cfs.size()];
}
/**
* 实现数据插入功能
* @param stu
* @throws Exception
*/
public void save(Student stu) throws Exception{
String sql = createSql(); //获取拼接完成的sql语句
Class.forName("com.mysql.jdbc.Driver"); //加载MySQL数据库驱动
//获取数据库连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/hibernate","root", "wwj");
//创建PreparedStement对象
PreparedStatement ps = conn.prepareStatement(sql);
for(int i = 0; i < methodNames.length; i++) {
//利用Java的反射机制,获取对象的方法
Method m = stu.getClass().getMethod(methodNames[i]);
Class r = m.getReturnType(); //获取方法返回值类型
if(r.getName() == "java.lang.String"){ //如果返回值类型等于”java.lang.String"的话
String v = (String)m.invoke(stu); //对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。
ps.setString(i + 1, v); //将指定参数设置为给定 Java String 值。
}
if(r.getName() == "int"){
Integer v = (Integer)m.invoke(stu);
ps.setInt(i + 1, v);
}
System.out.println(m.getName() + "|" + r.getName());
}
ps.executeUpdate(); //执行sql语句更新数据库
ps.close(); //释放此PrepareStatement对象的数据库和JDBC资源
conn.close(); //关闭数据连接
}
/**
* 创建SQL语句
* @return
*/
private String createSql() {
//拼接字段
String str1 = "";
int index = 0;
for(String s : cfs.keySet()) {
String v = cfs.get(s);
v = Character.toUpperCase(v.charAt(0)) + v.substring(1);
methodNames[index] = "get" + v;
index++;
str1 += s + ",";
}
str1 = str1.substring(0, str1.length() - 1); //去掉最后面的逗号","
System.out.println(str1);
//拼接(?,?,?,?),问号的个数取决于map的长度
String str2 = "";
for(int i = 0; i < cfs.size(); i++){
str2 += "?,";
}
str2 = str2.substring(0, str2.length() - 1);
System.out.println(str2);
//拼接sql字符串
String sql = "Insert into " + tableName + "(" + str1 + ")" + "values" + "(" + str2 + ")";
System.out.println(sql);
return sql;
}
}
测试结果:
id,age,name
?,?,?
Insert into student(id,age,name)values(?,?,?)
getId|int
getAge|int
getName|java.lang.String
?,?,?
Insert into student(id,age,name)values(?,?,?)
getId|int
getAge|int
getName|java.lang.String
查看数据库
Hibernate总结:
Hibernate是一个很优秀的框架,确实能减轻程序员的开发数据库的繁杂,其实最重要的是一种解决方案的思想,而我学习框架的初衷也就是学习框架思想,有了思想,就不会被技术禁锢在一个尴尬的境地。