您的位置:首页 > 数据库

简单建立数据库连接池并包装查询代码

2014-04-03 17:10 260 查看
前言:最近要找工作,忙着复习,好久没用JDBC了,所以简单的回顾下:JDBC、JDK自带日志。

一:准备Jar包

ojdbc14.jar:oracle数据库驱动

commons-lang-2.6.jar:工具包

二:日志工具类

1:建立数据库链接配置文件db.properties(保存在src下):

jdbc.url=jdbc:oracle:thin:@xx.xx.xx.xx:1521:YY
jdbc.driverClass=oracle.jdbc.driver.OracleDriver
jdbc.userName=root
jdbc.password=root
jdbc.initPoolsSize=4

2:建立DBUtil.java及QueryBuilder.java:

这里还有很多考虑不足的地方,比如:需要建立一个定时任务,定时进行查询来防止链接超时。

public class DBUtil {

	private static String url = null;
	private static String driverClass = null;
	private static String userName = null;
	private static String password = null;
	private static int initPoolsSize = 2;
	private static int poolIndex = 0;//当前已使用的链接数量
	private static Object locked = new Object();//lock对象
	private static List<Connection> connPools = new ArrayList<Connection>();
	
	/**
	 * 静态初始化
	 */
	static {
		InputStream in = DBUtil.class.getClassLoader().getResourceAsStream("db.properties");
		Properties p = new Properties();
		try {
			p.load(in);
			url = p.getProperty("jdbc.url");
			driverClass = p.getProperty("jdbc.driverClass");
			userName = p.getProperty("jdbc.userName");
			password = p.getProperty("jdbc.password");
			initPoolsSize = Integer.parseInt(p.getProperty("jdbc.initPoolsSize"));
		} catch (IOException e) {
			WebLogger.showWarning("数据库链接属性文件读取失败:"+e.getCause());
		}
		try {
			Class.forName(driverClass);
		} catch (ClassNotFoundException e) {
			WebLogger.showWarning("驱动加载失败:"+e.getCause());
		}
		initConnPools(initPoolsSize);
	}
	
	/**
	 * 初始化数据库连接池
	 */
	private static boolean initConnPools(int poolSize){
		boolean flag = false;
		try {
			for(int i=0;i<poolSize;i++){
				connPools.add(DriverManager.getConnection(url,userName,password));
			}
			flag = true;
		} catch (SQLException e) {
			WebLogger.showWarning("初始化化数据库连接池失败:"+e.getCause());
		}
		return flag;
	}
	
	/**
	 * 获取数据库连接池中的链接
	 * @return
	 */
	public static Connection getConnection(){
		Connection conn = null;
		synchronized(locked){
			if(poolIndex==connPools.size()){
				initConnPools(1);
			}
			conn = connPools.get(poolIndex++);
		}
		return conn;
	}
	
	/**
	 * 释放链接
	 * @param conn
	 * @param stat
	 * @param rs
	 */
	public static void closeConnection(Connection conn,Statement stat,ResultSet rs){
		if(conn!=null){
			synchronized (locked) {
				poolIndex--;//占用的连接数量减少
			}
		}
		if(stat!=null){
			try {
				stat.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}finally{
				if(rs!=null){
					try {
						rs.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	/**
	 * 查询工具方法
	 * @param <T>
	 * @param <T>
	 * @param conn
	 * @param sql
	 * @param params
	 */
	public static <T> T query(QueryBuilder<T> qb){
		T obj = null;
		Connection conn = getConnection();
		if(conn==null){
			return obj;
		}
		try {
			PreparedStatement ps = conn.prepareStatement(qb.getPrepareSQL());
			Object[] params = qb.getPrepareParams();
			if(params.length>0){
				qb.setParams(ps,params);
			}
			ResultSet rs = ps.executeQuery();
			obj = qb.execute(rs);
			String sqlMsg = "执行SQL:["+qb.getPrepareSQL();
			if(params.length>0){
				sqlMsg += ArrayUtils.toString(params);
			}
			sqlMsg += "]";
			WebLogger.showInfo(sqlMsg);
			closeConnection(conn,ps,rs);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}
	
}


QueryBuilder中运用泛型来返回对象,参数预处理的方法是可选的,如果需要处理就需要重写setParams方法。

public abstract class QueryBuilder<T> {
	
	private String sql = null;
	private Object[] params = null;
	
	public QueryBuilder(String sql,Object...params){
		this.sql = sql;
		this.params = params;
	}
	
	public String getPrepareSQL(){
		return this.sql;
	}
	
	public Object[] getPrepareParams(){
		return this.params;
	}
	
	/**
	 * 参数预处理
	 * @param ps
	 * @param params
	 */
	public void setParams(PreparedStatement ps,Object... params) throws Exception{};
	
	/**
	 * 处理查询出来的数据
	 * @param rs
	 * @return
	 */
	public abstract T execute(ResultSet rs) throws Exception;
	
}


日志工具类:

/**
 * @author WJL
 * @date 2014-1-22
 * @email wjl@zving.com
 */
public class WebLogger {

	private static Logger logger = Logger.getLogger(WebLogger.class.getName());
	static{
		try {
			FileHandler fileHandler = new FileHandler("D:\\log_"+System.currentTimeMillis()+".log");
			final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			fileHandler.setFormatter(new Formatter() {
				@Override
				public String format(LogRecord arg0) {
					return String.format("%-8s",arg0.getLevel().getLocalizedName())+sdf.format(new Date(arg0.getMillis()) )+"  : "+ arg0.getMessage()+"\n";
				}
			});
			logger.addHandler(fileHandler);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public static void showWarning(String message){
		logger.log(Level.WARNING, message);
	}
	public static void showInfo(String message){
		logger.info(message);
	}
	public static void main(String[] args) {
		WebLogger.showInfo("Hello World");
	}
}


三:建立Dao层代码:

public interface UserDao {

	/**
	 * 列出用户名
	 * @return
	 */
	public List<String> listUserName();
	
	/**
	 * 根据邮箱查出用户信息
	 * @param name
	 * @param email
	 * @return
	 */
	public List<User> findUser(String email);
}


public class UserDaoImp implements UserDao{

	@Override
	public List<String> listUserName() {
		return DBUtil.query(new QueryBuilder<List<String>>("Select UserName from ZDUser"){
			@Override
			public List<String> execute(ResultSet rs) throws SQLException {
				List<String> names = new ArrayList<String>();
				while(rs.next()){
					names.add(rs.getString("UserName"));
				}
				return names;
			}
		});
	}

	@Override
	public List<User> findUser(String email) {
		return DBUtil.query(new QueryBuilder<List<User>>("Select * from ZDUser where email like ? ","%"+email+"%"){
			@Override
			public void setParams(PreparedStatement ps, Object... params) throws SQLException{
				ps.setString(1, params[0].toString());
			}
			@Override
			public List<User> execute(ResultSet rs) throws SQLException {
				List<User> users = new ArrayList<User>();
				User user = null;
				while(rs.next()){
					user = new User();
					user.setEmail(rs.getString("Email"));
					user.setLastLoginTime(rs.getDate("LastLoginTime"));
					user.setName(rs.getString("UserName"));
					user.setStatus(rs.getString("Status"));
					users.add(user);
				}
				return users;
			}
		});
	}
}


四:Bean对象及Service层
public class User {

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getStatus() {
		return status;
	}
	public void setStatus(String status) {
		this.status = status;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Date getLastLoginTime() {
		return lastLoginTime;
	}
	public void setLastLoginTime(Date lastLoginTime) {
		this.lastLoginTime = lastLoginTime;
	}
	@Override
	public String toString() {
		return "User [name=" + name + ", status=" + status + ", email=" + email
				+ ", lastLoginTime=" + lastLoginTime + "]";
	}
	private String name = null;
	private String status = null;
	private String email = null;
	private Date lastLoginTime = null;
	
}


public interface UserService {

	/**
	 * 列出用户名
	 * @return
	 */
	public List<String> listUserName();
	
	/**
	 * 根据邮箱查出用户信息
	 * @param name
	 * @param email
	 * @return
	 */
	public List<User> findUser(String email);
}


public class UserServiceImp implements UserService{

	@Override
	public List<String> listUserName() {
		return  new UserDaoImp().listUserName();
	}

	@Override
	public List<User> findUser(String email) {
		return new UserDaoImp().findUser(email);
	}

}


五:建立测试代码,调用及结果

public class Test {

	public static void main(String[] args) {
		UserService userService = new UserServiceImp();
		for(User user : userService.findUser("wang")){
			System.out.println(user);
		}
	}
}



注:数据库表结构请根据User对象自行设计

改工程代码可以到源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: