使用纯JDBC实现hibernate/mybatis的基本功能

现在主流的在JAVA开发中实现数据库管理的框架hibnate,mybatis 但是纯针对一些特别小的项目来说,其实jdbc也足够了,而纯jdbc的好处就是无依赖包,几行代码搞定简单业务.但是让大多数人头疼的就是jdbc如何直接处理java对象,让他看起来像我们经常使用hibernate或mybatis,这样才能保证开发的速度。

近期简单写了一个纯jdbc的数据库连接类,里面简单的用到一些反射的机制,完成java对象和数据库数据之间的操作衔接,而由于利用了反射机制,整体代码执行起来效率也比较高。

1、hibnate的load方法--通过一个sql将数据库的某些数据直接对应到映射对象里面。好处不用多说,坏处就是比较局限,尤其针对复杂sql联合查询出的对象没有映射类很难直接获取到一个完整的对象。这点到不如mybatis,针对这个方法我的要求就是。传入一个sql,指定返回的class,java自动根据class的数据进行赋值。

// 获取唯一对象
	public static Object getUniqueResult(String sql, Class<?> t) throws InstantiationException, IllegalAccessException {
		Object obj = t.newInstance();
		Connection con = null;// 创建一个数据库连接
		PreparedStatement pre = null;// 创建预编译语句对象,一般都是用这个而不用Statement
		ResultSet result = null;
		String getName = "";
		Method[] mts = obj.getClass().getMethods();
		Method metset = null;

		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
			System.out.println("开始尝试连接数据库!");
			con = DriverManager.getConnection(url, user, password);// 获取连接
			System.out.println("连接成功!");
			pre = con.prepareStatement(sql);// 实例化预编译语句
			result = pre.executeQuery();// 执行查询,注意括号中不需要再加参数
			while (result.next()) {
				// 当结果集不为空时
				for (Method md : mts) {
					if (md.getName().startsWith("get")) {
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(String.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, String.class);
							try {
								metset.invoke(obj, result.getString(getName));
							} catch (Exception e) {
							}
							continue;
						}
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(Date.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, Date.class);
							// 这里注意正常result返回的是sqlDate这里要转成utildate
							try {
								metset.invoke(obj, JDBCUtil.uitlDate_to_sqlDate(result.getDate(getName)));
							} catch (Exception e) {
							}
							continue;
						}
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(Double.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, Double.class);
							try {
								metset.invoke(obj, result.getDouble(getName));
							} catch (Exception e) {
							}
							continue;
						}
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(int.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, int.class);
							try {
								metset.invoke(obj, result.getInt(getName));
							} catch (Exception e) {
							}
							continue;
						}
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(Long.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, Long.class);
							try {
								metset.invoke(obj, result.getLong(getName));
							} catch (Exception e) {
							}
							continue;
						}
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(BigDecimal.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, BigDecimal.class);
							try {
								metset.invoke(obj, BigDecimal.valueOf(result.getLong(getName)));
							} catch (Exception e) {
							}
							continue;
						}

					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 逐一将上面的几个对象关闭,因为不关闭的话会影响性能、并且占用资源
				// 注意关闭的顺序,最后使用的最先关闭
				if (result != null) {
					result.close();
				}
				if (pre != null) {
					pre.close();
				}
				if (con != null) {
					con.close();
				}
				System.out.println("数据库连接已关闭!");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return obj;
	}

这段代码直接通过传入的sql获取了一个唯一对象。我们调用这个方法的时候就和hibernate非常相似了。

Ac01 ac01 = (Ac01) JDBCUtil.getUniqueResult(sql, Ac01.class);

是不是和我们常见hibernate的query方法长的差不多,其实他还有更强大的功能就是传入任意sql,这个sql可以无限复杂,返回的对象可以是你做的任意一个关联好几个表数据的对象。只要你的sql执行效率比较高,这个方法带来的结果就非常实用。

当然我们实际需求不可能只有一个普通的查询,我们想返回一个list应该如何处理呢?针对hibernate本身提供的sqlquery来说。他返回一个list<objetc[]>这个对象数组的集合操作起来就让人非常尴尬了。那么如何返回一个任意对象的list<object>呢?只要将上面代码稍作改动。


// 返回list对象
	public static List<?> getListResult(String sql, Class<?> t) throws InstantiationException, IllegalAccessException {

		Connection con = null;// 创建一个数据库连接
		PreparedStatement pre = null;// 创建预编译语句对象,一般都是用这个而不用Statement
		ResultSet result = null;
		String getName = "";
		Method metset = null;
		List<Object> list = new ArrayList<Object>();
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
			System.out.println("开始尝试连接数据库!");
			con = DriverManager.getConnection(url, user, password);// 获取连接
			System.out.println("连接成功!");
			pre = con.prepareStatement(sql);// 实例化预编译语句
			result = pre.executeQuery();// 执行查询,注意括号中不需要再加参数
			while (result.next()) {
				Object obj = t.newInstance();
				Method[] mts = obj.getClass().getMethods();
				for (Method md : mts) {
					if (md.getName().startsWith("get")) {
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(String.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, String.class);
							try {
								metset.invoke(obj, result.getString(getName));
							} catch (Exception e) {
							}
							continue;
						}
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(Date.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, Date.class);
							// 这里注意正常result返回的是sqlDate这里要转成utildate
							try {
								metset.invoke(obj, JDBCUtil.uitlDate_to_sqlDate(result.getDate(getName)));
							} catch (Exception e) {
							}
							continue;
						}
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(Double.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, Double.class);
							try {
								metset.invoke(obj, result.getDouble(getName));
							} catch (Exception e) {
							}
							continue;
						}
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(int.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, int.class);
							try {
								metset.invoke(obj, result.getInt(getName));
							} catch (Exception e) {
							}
							continue;
						}
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(Long.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, Long.class);
							try {
								metset.invoke(obj, result.getLong(getName));
							} catch (Exception e) {
							}
							continue;
						}
						// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
						if (md.getReturnType().equals(BigDecimal.class)) {// 源为字符串
							getName = md.getName().replaceAll("get", "").toString();
							metset = obj.getClass().getMethod("set" + getName, BigDecimal.class);
							try {
								metset.invoke(obj, BigDecimal.valueOf(result.getLong(getName)));
							} catch (Exception e) {
							}
							continue;
						}
					}
				}
				list.add(obj);
			}
			// 当结果集不为空时
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 逐一将上面的几个对象关闭,因为不关闭的话会影响性能、并且占用资源
				// 注意关闭的顺序,最后使用的最先关闭
				if (result != null) {
					result.close();
				}
				if (pre != null) {
					pre.close();
				}
				if (con != null) {
					con.close();
				}
				System.out.println("数据库连接已关闭!");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return list;
	}

调用方法依然采用hibernate的写法

List<Ac01> ac01list = (List<Ac01>) JDBCUtil.getListResult(sql, Ac01.class);

这样我们很简单的就拿到一个list<object>的任意对象的集合。

2、save和update方法-有了上面的方法铺垫。save或update这里不再多解释。代码上注释已经给的非常明确-直接贴代码-要注意的一点就是update参考mybatis提供的两个update方法,一种应该是全部更新一种是仅更新非空,我们这里也提供了两个方法。

/**
	 * 
	 * @param obj
	 *            --要更新的对象object
	 * @param where条件字段
	 *            如果有多个用","分开
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws SQLException
	 */
	public static int updateWithoutNull(Object obj, String where) throws InstantiationException,
			IllegalAccessException, SQLException {
		// 先判断如果obj==null 直接不操作
		if (obj == null) {
			throw new SQLException("数据库更新异常--传入对象为空!");
		}
		Connection con = null;// 创建一个数据库连接
		PreparedStatement pre = null;// 创建预编译语句对象,一般都是用这个而不用Statement
		int result = 0;
		String sql = "";
		Method[] mts = obj.getClass().getMethods();
		String getName = "";
		String value = "";
		String wherekey = "";
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
			System.out.println("开始尝试连接数据库!");
			con = DriverManager.getConnection(url, user, password);// 获取连接
			System.out.println("连接成功!");

			// 这里根据object构造update语句

			String[] objname = obj.getClass().getName().split("\\.");
			String tablename = objname[objname.length - 1].toUpperCase();
			sql += "update " + tablename + " set ";

			// 反射 找字段
			for (Method md : mts) {
				if (md.getName().startsWith("get")) {
					if (md.getReturnType().equals(String.class)) {// 源为字符串
						value = (String) md.invoke(obj, (Object[]) null);
						if (value == null || value.equals("")) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toString().toUpperCase();
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = '" + value + "'";
						}
						sql += getName + " = '" + value + "',";
						continue;
					}
					if (md.getReturnType().equals(Date.class)) {// 源为字符串
						Date date = (Date) md.invoke(obj, (Object[]) null);
						if (date == null) {
							continue;
						}
						value = DateUtil.smartFormat(date);// 全部返回19位,日期返回10位,分返回16位(系统可能用到的时间
															// 天 分 秒)
						getName = md.getName().replaceAll("get", "").toUpperCase();
						if (value.length() == 19) {// yyyy-mm-dd hh24:mm:ss
							sql += getName + " = to_date('" + value + "','yyyy-mm-dd hh24:mm:ss'),";
							if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
								wherekey += " and " + getName + " = to_date('" + value + "','yyyy-mm-dd hh24:mm:ss')";
							}
						}
						if (value.length() == 16) {// yyyy-mm-dd hh24:mm
							sql += getName + " = to_date('" + value + "','yyyy-mm-dd hh24:mm'),";
							if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
								wherekey += " and " + getName + " = to_date('" + value + "','yyyy-mm-dd hh24:mm')";
							}
						}
						if (value.length() == 10) {// "yyyy-mm-dd"
							sql += getName + " = to_date('" + value + "','yyyy-mm-dd'),";
							if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
								wherekey += " and " + getName + " = to_date('" + value + "','yyyy-mm-dd')";
							}
						}
						continue;
					}
					if (md.getReturnType().equals(Double.class)) {// 源为Double
						Double db = (Double) md.invoke(obj, (Object[]) null);
						if (db == null) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toUpperCase();
						sql += getName + " = " + db + ",";
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = " + db + "";
						}
						continue;
					}
					if (md.getReturnType().equals(Integer.class)) {// 源为Integer
						Integer it = (Integer) md.invoke(obj, (Object[]) null);
						if (it == null) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toUpperCase();
						sql += getName + " = " + it + ",";
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = " + it + "";
						}
						continue;
					}
					if (md.getReturnType().equals(int.class)) {// 源为int
						// int这里比较特殊-因为理论上object是转不成int的
						Object its = md.invoke(obj, (Object[]) null);
						if (its == null) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toUpperCase();
						sql += getName + " = " + its.toString() + ",";
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = " + its.toString() + "";
						}
						continue;
					}
					// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
					if (md.getReturnType().equals(Long.class)) {// 源为字符串
						Long lg = (Long) md.invoke(obj, (Object[]) null);
						if (lg == null) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toString().toUpperCase();
						sql += getName + " = " + lg + ",";
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = " + lg + "";
						}
						continue;
					}
					// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
					if (md.getReturnType().equals(BigDecimal.class)) {// 源为字符串
						BigDecimal bg = (BigDecimal) md.invoke(obj, (Object[]) null);
						if (bg == null) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toString();
						sql += getName + " = " + bg.doubleValue() + ",";
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = " + bg.doubleValue() + "";
						}
						continue;
					}

				}
			}
			// 最后把拼接完了的最后一个逗号去掉
			sql = sql.substring(0, sql.length() - 1);
			// 接下来这里涉及一个id问题--因为这里我们没有hibnate.xml文件的映射-所以这里没办法根据xml的配置来找到哪个字段是id-而且上述办法便利中没有考虑联合id的关系
			// 所以当我们在创建对象的时候-是不允许创建联合id的-但是这个也体现这个方法的一个灵活的地方-就是我指定where 条件的字段
			// 拼接where条件
			sql += " where 1=1 " + wherekey;
			System.out.println("执行sql:" + sql);
			pre = con.prepareStatement(sql);// 实例化预编译语句
			result = pre.executeUpdate();
			// 当结果集不为空时
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 逐一将上面的几个对象关闭,因为不关闭的话会影响性能、并且占用资源
				// 注意关闭的顺序,最后使用的最先关闭
				if (pre != null) {
					pre.close();
				}
				if (con != null) {
					con.close();
				}
				System.out.println("数据库连接已关闭!");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}
	
	/**
	 * 
	 * @param obj
	 *            --要更新的对象object
	 * @param where条件字段
	 *            如果有多个用","分开
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws SQLException
	 */
	public static int update(Object obj, String where) throws InstantiationException,
			IllegalAccessException, SQLException {
		// 先判断如果obj==null 直接不操作
		if (obj == null) {
			throw new SQLException("数据库更新异常--传入对象为空!");
		}
		Connection con = null;// 创建一个数据库连接
		PreparedStatement pre = null;// 创建预编译语句对象,一般都是用这个而不用Statement
		int result = 0;
		String sql = "";
		Method[] mts = obj.getClass().getMethods();
		String getName = "";
		String value = "";
		String wherekey = "";
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
			System.out.println("开始尝试连接数据库!");
			con = DriverManager.getConnection(url, user, password);// 获取连接
			System.out.println("连接成功!");

			// 这里根据object构造update语句

			String[] objname = obj.getClass().getName().split("\\.");
			String tablename = objname[objname.length - 1].toUpperCase();
			sql += "update " + tablename + " set ";

			// 反射 找字段
			for (Method md : mts) {
				if (md.getName().startsWith("get")) {
					if (md.getReturnType().equals(String.class)) {// 源为字符串
						value = (String) md.invoke(obj, (Object[]) null);
						if (value == null || value.equals("")) {
							sql += getName + " = '',";
							continue;
						}
						getName = md.getName().replaceAll("get", "").toString().toUpperCase();
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = '" + value + "'";
						}
						sql += getName + " = '" + value + "',";
						continue;
					}
					if (md.getReturnType().equals(Date.class)) {// 源为字符串
						Date date = (Date) md.invoke(obj, (Object[]) null);
						if (date == null) {
							sql += getName + " = '',";
							continue;
						}
						value = DateUtil.smartFormat(date);// 全部返回19位,日期返回10位,分返回16位(系统可能用到的时间
															// 天 分 秒)
						getName = md.getName().replaceAll("get", "").toUpperCase();
						if (value.length() == 19) {// yyyy-mm-dd hh24:mm:ss
							sql += getName + " = to_date('" + value + "','yyyy-mm-dd hh24:mm:ss'),";
							if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
								wherekey += " and " + getName + " = to_date('" + value + "','yyyy-mm-dd hh24:mm:ss')";
							}
						}
						if (value.length() == 16) {// yyyy-mm-dd hh24:mm
							sql += getName + " = to_date('" + value + "','yyyy-mm-dd hh24:mm'),";
							if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
								wherekey += " and " + getName + " = to_date('" + value + "','yyyy-mm-dd hh24:mm')";
							}
						}
						if (value.length() == 10) {// "yyyy-mm-dd"
							sql += getName + " = to_date('" + value + "','yyyy-mm-dd'),";
							if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
								wherekey += " and " + getName + " = to_date('" + value + "','yyyy-mm-dd')";
							}
						}
						continue;
					}
					if (md.getReturnType().equals(Double.class)) {// 源为Double
						Double db = (Double) md.invoke(obj, (Object[]) null);
						if (db == null) {
							sql += getName + " = '',";
							continue;
						}
						getName = md.getName().replaceAll("get", "").toUpperCase();
						sql += getName + " = " + db + ",";
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = " + db + "";
						}
						continue;
					}
					if (md.getReturnType().equals(Integer.class)) {// 源为Integer
						Integer it = (Integer) md.invoke(obj, (Object[]) null);
						if (it == null) {
							sql += getName + " = '',";
							continue;
						}
						getName = md.getName().replaceAll("get", "").toUpperCase();
						sql += getName + " = " + it + ",";
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = " + it + "";
						}
						continue;
					}
					if (md.getReturnType().equals(int.class)) {// 源为int
						// int这里比较特殊-因为理论上object是转不成int的
						Object its = md.invoke(obj, (Object[]) null);
						if (its == null) {
							sql += getName + " = '',";
							continue;
						}
						getName = md.getName().replaceAll("get", "").toUpperCase();
						sql += getName + " = " + its.toString() + ",";
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = " + its.toString() + "";
						}
						continue;
					}
					// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
					if (md.getReturnType().equals(Long.class)) {// 源为字符串
						Long lg = (Long) md.invoke(obj, (Object[]) null);
						if (lg == null) {
							sql += getName + " = '',";
							continue;
						}
						getName = md.getName().replaceAll("get", "").toString().toUpperCase();
						sql += getName + " = " + lg + ",";
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = " + lg + "";
						}
						continue;
					}
					// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
					if (md.getReturnType().equals(BigDecimal.class)) {// 源为字符串
						BigDecimal bg = (BigDecimal) md.invoke(obj, (Object[]) null);
						if (bg == null) {
							sql += getName + " = '',";
							continue;
						}
						getName = md.getName().replaceAll("get", "").toString();
						sql += getName + " = " + bg.doubleValue() + ",";
						if (where.toUpperCase().indexOf(getName) != -1) {// 说明这个字段是where条件
							wherekey += " and " + getName + " = " + bg.doubleValue() + "";
						}
						continue;
					}

				}
			}
			// 最后把拼接完了的最后一个逗号去掉
			sql = sql.substring(0, sql.length() - 1);
			// 接下来这里涉及一个id问题--因为这里我们没有hibnate.xml文件的映射-所以这里没办法根据xml的配置来找到哪个字段是id-而且上述办法便利中没有考虑联合id的关系
			// 所以当我们在创建对象的时候-是不允许创建联合id的-但是这个也体现这个方法的一个灵活的地方-就是我指定where 条件的字段
			// 拼接where条件
			sql += " where 1=1 " + wherekey;
			System.out.println("执行sql:" + sql);
			pre = con.prepareStatement(sql);// 实例化预编译语句
			result = pre.executeUpdate();
			// 当结果集不为空时
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 逐一将上面的几个对象关闭,因为不关闭的话会影响性能、并且占用资源
				// 注意关闭的顺序,最后使用的最先关闭
				if (pre != null) {
					pre.close();
				}
				if (con != null) {
					con.close();
				}
				System.out.println("数据库连接已关闭!");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}
	
	/**
	 * 
	 * @param obj
	 *            --要更新的对象object
	 * @param where条件字段
	 *            如果有多个用","分开
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws SQLException
	 */
	public static int save(Object obj) throws InstantiationException,
			IllegalAccessException, SQLException {
		// 先判断如果obj==null 直接不操作
		if (obj == null) {
			throw new SQLException("数据库更新异常--传入对象为空!");
		}
		Connection con = null;// 创建一个数据库连接
		PreparedStatement pre = null;// 创建预编译语句对象,一般都是用这个而不用Statement
		int result = 0;
		String sql = "";
		Method[] mts = obj.getClass().getMethods();
		String getName = "";
		String value = "";
		String values = " values (";
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
			System.out.println("开始尝试连接数据库!");
			con = DriverManager.getConnection(url, user, password);// 获取连接
			System.out.println("连接成功!");

			// 这里根据object构造update语句

			String[] objname = obj.getClass().getName().split("\\.");
			String tablename = objname[objname.length - 1].toUpperCase();
			sql += "insert into " + tablename + " ( ";

			// 反射 找字段
			for (Method md : mts) {
				if (md.getName().startsWith("get")) {
					if (md.getReturnType().equals(String.class)) {// 源为字符串
						value = (String) md.invoke(obj, (Object[]) null);
						if (value == null || value.equals("")) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toString().toUpperCase();
						values += "'" + value + "',";
						sql += getName +",";
						continue;
					}
					if (md.getReturnType().equals(Date.class)) {// 源为字符串
						Date date = (Date) md.invoke(obj, (Object[]) null);
						if (date == null) {
							continue;
						}
						sql += getName +",";
						value = DateUtil.smartFormat(date);// 全部返回19位,日期返回10位,分返回16位(系统可能用到的时间
															// 天 分 秒)
						getName = md.getName().replaceAll("get", "").toUpperCase();
						if (value.length() == 19) {// yyyy-mm-dd hh24:mm:ss
							values +=  "to_date('" + value + "','yyyy-mm-dd hh24:mm:ss'),";
						}
						if (value.length() == 16) {// yyyy-mm-dd hh24:mm
							values +=  "to_date('" + value + "','yyyy-mm-dd hh24:mm'),";
						}
						if (value.length() == 10) {// "yyyy-mm-dd"
							values +=  "to_date('" + value + "','yyyy-mm-dd'),";
						}
						continue;
					}
					if (md.getReturnType().equals(Double.class)) {// 源为Double
						Double db = (Double) md.invoke(obj, (Object[]) null);
						if (db == null) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toUpperCase();
						sql += getName +",";
						values +=  db +",";
						continue;
					}
					if (md.getReturnType().equals(Integer.class)) {// 源为Integer
						Integer it = (Integer) md.invoke(obj, (Object[]) null);
						if (it == null) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toUpperCase();
						sql += getName +",";
						values +=  it +",";
						continue;
					}
					if (md.getReturnType().equals(int.class)) {// 源为int
						// int这里比较特殊-因为理论上object是转不成int的
						Object its = md.invoke(obj, (Object[]) null);
						if (its == null) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toUpperCase();
						sql += getName +",";
						values +=  its.toString() +",";
						continue;
					}
					// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
					if (md.getReturnType().equals(Long.class)) {// 源为字符串
						Long lg = (Long) md.invoke(obj, (Object[]) null);
						if (lg == null) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toString().toUpperCase();
						sql += getName +",";
						values +=  lg +",";
						continue;
					}
					// -获取他的get方法-看get方法的返回值是啥-是啥就按照啥做set
					if (md.getReturnType().equals(BigDecimal.class)) {// 源为字符串
						BigDecimal bg = (BigDecimal) md.invoke(obj, (Object[]) null);
						if (bg == null) {
							continue;
						}
						getName = md.getName().replaceAll("get", "").toString();
						sql += getName +",";
						values +=  bg.doubleValue() +",";
						continue;
					}

				}
			}
			// 最后把拼接完了的最后一个逗号去掉
			sql = sql.substring(0, sql.length() - 1) +")";
			values = values.substring(0, values.length() - 1) +")";
			// 接下来这里涉及一个id问题--因为这里我们没有hibnate.xml文件的映射-所以这里没办法根据xml的配置来找到哪个字段是id-而且上述办法便利中没有考虑联合id的关系
			// 所以当我们在创建对象的时候-是不允许创建联合id的-但是这个也体现这个方法的一个灵活的地方-就是我指定where 条件的字段
			// 拼接where条件
			sql +=  values;
			System.out.println("执行sql:" + sql);
			pre = con.prepareStatement(sql);// 实例化预编译语句
			result = pre.executeUpdate();
			// 当结果集不为空时
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 逐一将上面的几个对象关闭,因为不关闭的话会影响性能、并且占用资源
				// 注意关闭的顺序,最后使用的最先关闭
				if (pre != null) {
					pre.close();
				}
				if (con != null) {
					con.close();
				}
				System.out.println("数据库连接已关闭!");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}
上面一共有三个方法,执行save或update操作,在update操作的时候,因为我们没有映射数据库的主键的xml所以这里我们要传入一个参数,就是我将以表的哪个字段作为更新条件进行更新-代码中已经给了详细说明。


以上就是对jdbc的一个简单封装,来实现比较轻松的数据库操作。当然比如事物,比如并发等,代码中都没有考虑。所以根据自己实际的项目环境的代码才是最好的代码。

最后,代码看着太累,给一个已经写好的工具类

http://download.csdn.net/download/himly_zhang/9851014



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值