实现orm框架,类似hibernate功能
之前使用Hibernate时,觉得很不错,但是自己平时做一些练习时都是一些小项目,所以自己想能不能自尝试写一个类似Hibernate的简单功能呢?当然,本人水平不足,所以现在只能求形似。如果说的有错希望给位前辈批评并指教。
以下是我的测试结果:
数据插入:
User user = new User(); user.setName("HHZoog"); user.setPwd("HHZoog"); user.setMusic_box("12"); HibernateDao.save(user);
测试结果:
数据修改:
User user = new User(); user.setId(22); user.setName("HHZoog"); user.setPwd("OOOOOO"); user.setMusic_box("12");
HibernateDao.update(user);
测试结果:
数据删除:
User user = new User(); user.setId(22); user.setName("HHZoog"); user.setPwd("OOOOOO"); user.setMusic_box("12"); HibernateDao.delete(user);
测试结果:删除成功
数据查找:get方法
User user = (User)HibernateDao.get(User.class, 23); System.out.println(user.getId() + " | " +user.getName() + " | " +user.getPwd());
测试结果:
数据查找: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()); }
测试结果:
下面介绍一下各个类的功能:
ResultSetToObject类事件数据库操作返回的ResultSet结果集转为List<Object>对象;
BaseOperatorDao类是基本的数据操作类,执行传递过来的Sql语句;
HibernateDao提供类似Hibernate简单操作的功能;
User对应的实体类;
FunctionUtils类提供一些常用的方法;
ConnectDB类是连接数据库的操作类:
***********************************************************************
一下是各个类的源代码:
HibernateDao.java
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(); } }
FunctionUtils.java
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; } }
ConnectionDB.java
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(); } } } } }
User.java
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; } }
ResultSetToObject.java
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(); } } } //关闭结果集 ConnectDB.releaseDB(resultSet, null, ConnectDB.conn); } catch (SQLException e) { e.printStackTrace(); } return listObjs; } }
BaseOperatorDao.java
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); } catch (SQLException e) { e.printStackTrace(); } return resultSet; } /** * 使用Statement对象操作数据 * 主要针对数据的增删改 * @param sql * @return */ public static int delOrSaveOrUpdateData(String sql) { int resultRow = 0; try { statement = ConnectDB.connToDB().createStatement(); resultRow = statement.executeUpdate(sql); ConnectDB.releaseDB(null, statement, ConnectDB.conn); } catch (SQLException e) { e.printStackTrace(); } return resultRow; } }
********************************************************
以下是此用法的使用一些限制:
1,此方法不适合复合主键
2,实体类的属性名称必须要与数据的字段名一致
3,此方法的对应实体类必须有public static tableName =”XXX” //代表的对应的数据库名
public static primaryKey = “XXX” //代表对应的主键名称
4,由于我进行测试的时候使用的主键是“id”且自增长,所以如果不是则需要做一下修改。
本人联系方式qq:982925115 , 邮箱:zhong678@yeah.net
User user = new User(); user.setId(22); user.setName("HHZoog"); user.setPwd("OOOOOO"); user.setMusic_box("12"); HibernateDao.delete(user);