这篇文章 可作为北京尚学堂 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_Java


其实这里面问题最多的在于反射知识的应用