日期:2014-05-16  浏览次数:20541 次

自己动手模仿Hibernate写数据库框架
自己动手模仿Hibernate写数据库框架

最近项目有点儿停滞,论文看的也比较浮躁,于是就打算重写下后台的框架,数据库部分模仿Hibernate随手写个小程序,当然还没有写完,不过最简单的功能已经能有了,打算把代码贴上来,后续不断的更新。
简单介绍下这个框架:采用DBCP连接池,然后实现了类似Hibernate的按对象插入、更新、删除等。当然还没有写生命周期、延迟加载这些,不过后续会慢慢的加上去,否则就太小儿科了不是么。这个框架是建立在我原有的一个BDUtil的小项目上的,当时做插入这些操作需要传SQL语句和参数,现在把这步也省略了,当然最大的好处就是不用写SQL。
下面就上代码:
Commons.java: DBCP连接池,返回Connection对象。
package org.gfg.dbutil.common;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

@SuppressWarnings("static-access")
public class Commons {

	private static DataSource dataSource;
	static {
		try {
			Properties prop = new Properties();
			prop.load(Commons.class.getClassLoader().getResourceAsStream(
					"dbcpconfig.properties"));
			BasicDataSourceFactory factory = new BasicDataSourceFactory();
			dataSource = factory.createDataSource(prop);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static Connection getConnection() throws SQLException {
		return dataSource.getConnection();
	}

	public static void close(ResultSet rs, PreparedStatement ps, Connection conn) {
		try {
			if (rs != null) {

				rs.close();
			}
			if (ps != null) {
				ps.close();
			}
			if (conn != null) {
				conn.close();
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}


DbUtils.java:主要封装了最基本的CRUD操作。注意在query方法的参数中传入了IResultSetHandler,这个接口的主要功能是对返回的结果集做封装。
package org.gfg.dbutil.common;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.gfg.dbutil.handler.BeanHandler;
import org.gfg.dbutil.handler.IResultSetHandler;

public class DbUtils {

	public static void insert(String sql, Object[] params) throws SQLException {// insert
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = Commons.getConnection();
			ps = conn.prepareStatement(sql);

			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			
			ps.executeUpdate();
		} finally {
			Commons.close(rs, ps, conn);
		}
	}

	public static void update(String sql, Object[] params) throws SQLException {// update
		DbUtils.insert(sql, params);
	}

	public static void delete(String sql, Object[] params) throws SQLException {// delete
		DbUtils.insert(sql, params);
	}

	public static Object query(String sql, Object[] params,
			IResultSetHandler rsh) throws SQLException {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = Commons.getConnection();
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			rs = ps.executeQuery();
			return rsh.handler(rs);
		} finally {
			Commons.close(rs, ps, conn);
		}
	}

	public static Object load(String sql, Object[] params,Class<?> clazz) {
		IResultSetHandler rsh=new BeanHandler(clazz);
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = Commons.getConnection();
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			rs = ps.executeQuery();
			return rsh.handler(rs);			
		} catch (SQLException e) {
			
			e.printStackTrace();
		} finally {
			Commons.close(rs, ps, conn);
		}
		return null;
	}
}


IResultSetHandler.java:接口,加工ResultSet结果,可以返回Model,List等,这个可以自行扩展。
package org.gfg.dbutil.handler;

import java.sql.ResultSe