实现简单的ORM功能,类似Hibernate功能

[b]
本人水平不足,菜鸟一个,说的有错希望各位前辈给予指导。
之前学习Hibernate时,发现Hibernate很好用,省了很多编写SQL的时间。
但是自己平常做一些练习时基本都是小东西,使用Hibernate便觉得大材小用了,所以自己试着实现类似Hibernate的一些简单功能,当然我写的只是形似而神不似。[/b]
以下是我的测试结果:

User user = new User();
user.setName("HHZoog");
user.setPwd("HHZoog");
user.setMusic_box("12");

HibernateDao.save(user);

插入结果:[img]http://dl.iteye.com/upload/picture/pic/112011/cc3e4e22-3b49-37fb-a782-7f1fce2bc8dd.png[/img]

		User user = new User();
user.setId(22);
user.setName("HHZoog");
user.setPwd("OOOOOO");
user.setMusic_box("12");

HibernateDao.update(user);

修改结果:[img]http://dl.iteye.com/upload/picture/pic/112013/30301e91-b364-3bab-b1a1-a562c1263e02.png[/img]

		User user = new User();
user.setId(22);
user.setName("HHZoog");
user.setPwd("OOOOOO");
user.setMusic_box("12");

HibernateDao.delete(user);

删除结果:删除成功

User user = (User)HibernateDao.get(User.class, 23);
System.out.println(user.getId() + " | " +user.getName() + " | " +user.getPwd());

查找结果:[img]http://dl.iteye.com/upload/picture/pic/112015/32926788-97c8-3b45-a9ca-323ebf72e392.png[/img]

find查找测试:
		String sql = "select * from user where id = 23";
List<Object> lists = HibernateDao.find(sql, User.class);
for(int i = 0 ; i < lists.size(); i++)
{
User user = (User)lists.get(i);
System.out.println(user.getId() + " | " +user.getName() + " | " +user.getPwd());
}

测试结果图片:[img]http://dl.iteye.com/upload/picture/pic/112017/7d2d5d3e-b0ee-392d-9562-14caf2481f7e.png[/img]

以下是各个类的使用方法:
ResultSetToObject类事件数据库操作返回的ResultSet结果集转为List<Object>对象

public class ResultSetToObject
{
public static List<Object> turnToObject(ResultSet resultSet,
Class<?> objClass)
{
/** 存储转化后的实体类 */
List<Object> listObjs = new ArrayList<Object>();

/** resultSet数据表中的字段名称 */
String[] columnNames = null;

/** resultSet数据表中对应字段的数据类型 */
String[] columnTypes = null;

try
{
if (resultSet == null)
{
return listObjs;
} else
{
ResultSetMetaData metaResult = resultSet.getMetaData();
int length = metaResult.getColumnCount();
columnNames = new String[length];
columnTypes = new String[length];
for (int i = 0; i < columnNames.length; i++)
{
columnNames[i] = metaResult.getColumnName(i + 1);
columnTypes[i] = metaResult.getColumnClassName(i + 1);
}

while (resultSet.next())
{
try
{
/* 实例化实体类 */
Object obj = objClass.newInstance();

/* 根据字段名调用实体类中的set方法 */
for (int j = 0; j < columnNames.length; j++)
{
Method method = objClass.getDeclaredMethod("set"
+ FunctionUtils.upInitial(columnNames[j]),
FunctionUtils.paraTypeClass(columnTypes[j]));
method.invoke(obj, resultSet
.getObject(columnNames[j]));
}

listObjs.add(obj);
} catch (InstantiationException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
} catch (SecurityException e)
{
e.printStackTrace();
} catch (NoSuchMethodException e)
{
e.printStackTrace();
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (InvocationTargetException e)
{
e.printStackTrace();
}
}
}

/* 关闭结果集 */
resultSet.close();

} catch (SQLException e)
{
e.printStackTrace();
}
return listObjs;
}

}


FunctionUtils类提供一些常用的方法

public class FunctionUtils
{
/**
* 将首字母变为大写
*
* @param str
* @return
*/
public static String upInitial(String str)
{
char[] chars = str.toCharArray();
chars[0] = Character.toUpperCase(chars[0]);
return new String(chars);
}

/**
* 字段的数据类型
*
* @param str
* @return
*/
public static Class<?> paraTypeClass(String str)
{
if (str.equals("java.lang.String"))
{
return java.lang.String.class;
} else if (str.equals("java.lang.Integer"))
{
return java.lang.Integer.class;
} else if (str.equals("java.lang.Character"))
{
return java.lang.Character.class;
} else if (str.equals("java.lang.Double"))
{
return java.lang.Double.class;
} else if (str.equals("java.lang.Short"))
{
return java.lang.Short.class;
} else if (str.equals("java.lang.Byte"))
{
return java.lang.Byte.class;
} else if (str.equals("java.lang.Float"))
{
return java.lang.Float.class;
} else if (str.equals("java.lang.Boolean"))
{
return java.lang.Boolean.class;
} else if (str.equals("java.util.Date"))
{
return java.util.Date.class;
}
return null;
}

}


BaseOperatorDao类是基本的数据操作类,执行传递过来的Sql语句;

/**
* 数据基本操作类
* @author HHZ
*
*/
public class BaseOperatorDao
{
private static Statement statement = null;

/**
* 使用Statement对象对数据操作
* 主要是查询
* @param sql
* @return
*/
public static ResultSet selectData(String sql)
{
ResultSet resultSet = null;
try
{
Connection conn = ConnectDB.connToDB();
statement = conn.createStatement();
resultSet = statement.executeQuery(sql);
return resultSet;
} catch (SQLException e)
{
e.printStackTrace();
}

ConnectDB.releaseDB(resultSet, statement, ConnectDB.conn);

return resultSet;
}

/**
* 使用Statement对象操作数据
* 主要针对数据的增删改
* @param sql
* @return
*/
public static int delOrSaveOrUpdateData(String sql)
{
try
{
statement = ConnectDB.connToDB().createStatement();
return statement.executeUpdate(sql);

} catch (SQLException e)
{
e.printStackTrace();
}

ConnectDB.releaseDB(null, statement, ConnectDB.conn);

return 0;
}
}


ConnectDB类是连接数据库的操作类:


/**
* 连接数据库
* @author HHZ
*
*/
public class ConnectDB
{
/** 数据库用户名 */
private static String DB_uName = "root";

/** 数据库用户密码 */
private static String DB_uPwd = "mysqladmin";

/** 数据库驱动 */
private static String DB_Driver = "com.mysql.jdbc.Driver";

/** 数据库连接路径 */
private static String DB_Url = "jdbc:mysql://localhost:3306/Pluto";

/**数据库连接对象*/
public static Connection conn = null;

private ConnectDB()
{

}

/**
* 加载数据库驱动
*/
static
{
try
{
Class.forName(DB_Driver);
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}

/**
* 连接数据库,并返回数据库连接对象
* @return
*/
public static Connection connToDB()
{
try
{
conn = DriverManager.getConnection(DB_Url, DB_uName, DB_uPwd);

} catch (SQLException e)
{
e.printStackTrace();
}

return conn;
}

/**
* 关闭数据库,释放资源
* @param resultSet
* @param statement
* @param conn
*/
public static void releaseDB(ResultSet resultSet, Statement statement,
Connection conn)
{

try
{
if (resultSet != null)
{
resultSet.close();
}
} catch (SQLException e)
{
e.printStackTrace();
} finally
{
try
{
if(statement != null)
{
statement.close();
}
} catch (SQLException e)
{
e.printStackTrace();
} finally
{
try
{
conn.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
}


HibernateDao提供类似Hibernate简单操作的功能:

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.util.List;
import com.music.utils.FunctionUtils;
import com.music.utils.ResultSetToObject;

/**
* 数据库持久层封装操作类
* @author HHZ
*
*/
public class HibernateDao
{

/**
* 保存对象
* @param object
*/
public static void save(Object object)
{
Class<?> objClass = object.getClass();
Field[] fields = objClass.getDeclaredFields();

/*构建SQL语句*/
StringBuffer sql = new StringBuffer("insert into ");
StringBuffer values = new StringBuffer("values(");

/*数据库名称*/
Field tableName = null;

try
{
/*根据实体类中的tableName属性获得数据库名称*/
tableName = objClass.getDeclaredField("tableName");

/*拼接SQL语句*/
sql.append(tableName.get(object));
sql.append("(");

/*根据传入的object对象获取到属性的值,并拼接到SQL语句中*/
for(int i = 0 ; i < fields.length ; i++)
{
/*但object的属性名为tableName,id,primaryKey时,则不将其拼接到SQL语句中*/
if(fields[i].getName().equals("tableName") || fields[i].getName().equals("id") || fields[i].getName().equals("primaryKey"))
{

}else
{
sql.append(fields[i].getName());
sql.append(",");

/*获得object对应属性的字段名的getXxxx()方法*/
Method method = objClass.getDeclaredMethod
("get"+FunctionUtils.upInitial(fields[i].getName()));

/*获得此objec字段的值*/
Object value = method.invoke(object);

/*如果值为空,则SQL语句中的值则为空*/
if(value == null)
{
values.append("null");
values.append(",");
}

/*获得此字段对应的数据类型*/
else if(fields[i].getType() == java.lang.String.class)
{
values.append("'");
values.append(value);
values.append("'");
values.append(",");
}else
{
values.append(value);
values.append(",");
}
}
}

} catch (SecurityException e)
{
e.printStackTrace();
} catch (NoSuchFieldException e)
{
e.printStackTrace();
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
} catch (NoSuchMethodException e)
{
e.printStackTrace();
} catch (InvocationTargetException e)
{
e.printStackTrace();
}

/*删除末尾一个逗号*/
sql.delete(sql.length()-1, sql.length());
sql.append(")");
sql.append(" ");
values.delete(values.length()-1, values.length());
values.append(")");

/*拼接成一条完整的SQL语句*/
String resultSql = sql.toString() + values.toString();

/*执行SQL语句操作*/
BaseOperatorDao.delOrSaveOrUpdateData(resultSql);

System.out.println(resultSql);
}

/**
* 根据提供的SQL和实体类查找数据并返回List<Object>
* @param sql
* @param objClass
* @return
*/
public static List<Object> find(String sql,Class<?> objClass)
{
return ResultSetToObject.turnToObject(BaseOperatorDao.selectData(sql),objClass);
}

/*根据主键查找数据*/
public static Object get(Class<?> objClass,Object key)
{

StringBuffer sql = new StringBuffer("select * from ");
Object object = null;

try
{
Field tableName = objClass.getDeclaredField("tableName");
Field primaryKey = objClass.getDeclaredField("primaryKey");

/*拼接数据库名到SQL语句中*/
sql.append(tableName.get(objClass));

/*获得主键数据类型,如果是string类型则加单引号*/
if(primaryKey.getType().equals("java.lang.String.class"))
{
sql.append(" where "+primaryKey.get(objClass)+" ='"+key.toString()+"'");
}else
{
sql.append(" where "+primaryKey.get(objClass)+" ="+key.toString());
}

System.out.println(sql.toString());

/*执行SQL语句后返回List对象*/
List<Object> listObjects = ResultSetToObject.turnToObject(BaseOperatorDao.selectData(sql.toString()),objClass);

/*取得第一条记录,即查找到数据*/
object = listObjects.get(0);

} catch (SecurityException e)
{
e.printStackTrace();
} catch (NoSuchFieldException e)
{
e.printStackTrace();
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
}

return object;
}

/**
* 删除记录
* @param object
*/
public static void delete(Object object)
{

StringBuffer sql = new StringBuffer("delete from ");

/*获得对象的Class类型*/
Class<?> objClass = object.getClass();

/*对象申明的属性*/
Field filed;

/*对象申明的方法*/
Method method = null;

try
{
/*获得主键名称*/
Field primaryKey = objClass.getDeclaredField("primaryKey");
String keyName = (String) primaryKey.get(objClass);

/*将keyName首字母转为大写,并获得主键的get方法*/
method = objClass.getDeclaredMethod("get"+FunctionUtils.upInitial(keyName));

/*获得数据名称,并拼接到SQL语句中*/
filed = objClass.getDeclaredField("tableName");
sql.append(filed.get(objClass));

if(primaryKey.getType().equals("java.lang.String.class"))
{
sql.append(" where "+keyName+" = '"+method.invoke(object)+"'");
}else
{
sql.append(" where "+keyName+" = "+method.invoke(object));
}

BaseOperatorDao.delOrSaveOrUpdateData(sql.toString());
} catch (SecurityException e)
{
e.printStackTrace();
} catch (NoSuchFieldException e)
{
e.printStackTrace();
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
} catch (NoSuchMethodException e)
{
e.printStackTrace();
} catch (InvocationTargetException e)
{
e.printStackTrace();
}

System.out.println(sql.toString());
}

/**
* 根据SQL删除记录
* @param sql
* @return
*/
public static int delete(String sql)
{
return BaseOperatorDao.delOrSaveOrUpdateData(sql);
}

/**
* 更新记录
* @param object
*/
public static void update(Object object)
{
/*获得对象的类型*/
Class<?> objClass = object.getClass();

/*待拼接SQL语句*/
StringBuffer sql = new StringBuffer("update ");
StringBuffer whereSql = new StringBuffer(" where ");

/*获得申明的属性*/
Field[] fields = objClass.getDeclaredFields();


try
{
Field tableName = objClass.getDeclaredField("tableName");
Field primaryKey = objClass.getDeclaredField("primaryKey");

/*获得主键的名称*/
String keyName = (String)primaryKey.get(objClass);

/*将主键拼接到SQL语句中*/
whereSql.append(keyName);
whereSql.append("= ");
sql.append(tableName.get(objClass));
sql.append(" set ");

for(int i = 0 ; i < fields.length; i++)
{
/*如果属性名称为tableName,primaryKey时则不拼接到SQL中*/
if(fields[i].getName().equals("tableName") || fields[i].getName().equals("primaryKey"))
{

}else
{
/*获得对应属性的get方法*/
Method method = objClass.getDeclaredMethod("get"+FunctionUtils.upInitial(fields[i].getName()));
sql.append(fields[i].getName());
sql.append("=");

/*获得对应属性的数据类型,如果是String类型则加单引号*/
if(fields[i].getType() == java.lang.String.class)
{
sql.append("'");
sql.append(method.invoke(object));
sql.append("'");
sql.append(",");
}else
{
sql.append(method.invoke(object));
sql.append(",");
}

/*如果此属性为主键*/
if(fields[i].getName().equals(keyName))
{
if(primaryKey.getType().equals("java.lang.String.class"))
{
whereSql.append("'");
whereSql.append(method.invoke(object));
whereSql.append("'");
}else
{
whereSql.append(method.invoke(object));
}
}
}
}

/*删除多余的逗号*/
sql.delete(sql.length()-1, sql.length());

/*执行操作,并返回作用的行数*/
int count = BaseOperatorDao.delOrSaveOrUpdateData(sql.toString()+whereSql.toString());

if(count == 0)
{
System.out.println("请确定数据库中是否由此记录");
}

System.out.println(sql.toString()+whereSql.toString());

} catch (SecurityException e)
{
e.printStackTrace();
} catch (NoSuchFieldException e)
{
e.printStackTrace();
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
} catch (NoSuchMethodException e)
{
e.printStackTrace();
} catch (InvocationTargetException e)
{
e.printStackTrace();
}
}


以下是用法规则:
1,此方法不适合复合主键
2,实体类的属性名称必须要与数据的字段名一致
3,此方法的对应实体类必须有public static tableName ="XXX" //代表的对应的数据库名
public static primaryKey = "XXX" //代表对应的主键名称
例如:

public class User
{
/**用户编号*/
private Integer id;

/** 用户名 */
private String name;

/** 用户密码 */
private String pwd;

/** 用户音乐盒子 */
private String music_box;

/**对应数据库名称*/
public static String tableName = "user";

/**数据对应的主键*/
public static String primaryKey = "id";

/**
* get,set方法
* @return
*/
public String getName()
{
return name;
}

public Integer getId()
{
return id;
}

public void setId(Integer id)
{
this.id = id;
}

public void setName(String name)
{
this.name = name;
}

public String getPwd()
{
return pwd;
}

public void setPwd(String pwd)
{
this.pwd = pwd;
}

public String getMusic_box()
{
return music_box;
}

public void setMusic_box(String musicBox)
{
music_box = musicBox;
}
}

[size=medium][b]哈哈,最后打条广告:本人现在(二流)本科大三,想在暑假出去实习,所投简历石沉大海,希望那位前辈能推荐一下。本人真心热爱编程,QQ:982925115[/b][/size]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值