简易高重用的jdbcutils工具封装实现类以及简易连接池实现

由于现在发现做个小项目都是导入n多的依赖包,很烦琐,只想快点开发完一个个的小需求项目,这个时候真心不想用框架,只能自己写个jdbcutils,虽然网上有很多有apache的,阿里的,但是感觉用过后都不怎么顺手,然后自己花了点时间写个新的,不喜勿喷

1.我们要写个resultset集合转成bean的回调接口,这个用过spring jdbc的人都知道这玩意

package org.framework.mvc.jdbc.bean;

import java.sql.ResultSet;
import java.sql.SQLException;

public interface RowMapper<T> {

	public abstract T mapRow(ResultSet rs) throws SQLException;

}

2.先来个基本的jdbc操作接口吧,这样好规范点

package org.framework.mvc.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.framework.mvc.jdbc.bean.RowMapper;

public interface JdbcOperation {

	/**
	 * update或delete功能
	 *
	 * @param sql
	 * @param params
	 * @return 变更记录数
	 * @throws SQLException
	 */
	public abstract int execute(String sql, Object[] params) throws SQLException;

	/**
	 * update或delete功能
	 *
	 * @param sql
	 * @return 变更记录数
	 * @throws SQLException
	 */
	public abstract int execute(String sql) throws SQLException;

	/**
	 * 批处理update或delete功能
	 *
	 * @param sql
	 * @param params
	 * @return 变更记录数
	 * @throws SQLException
	 */
	public abstract int executeBatch(String sql, List<Object[]> params) throws SQLException;

	/**
	 * 批处理update或delete功能
	 *
	 * @param sql
	 * @param params
	 * @return 变更记录数
	 * @throws SQLException
	 */
	public abstract int executeBatch(String sql) throws SQLException;

	/**
	 * select功能
	 *
	 * @param sql
	 * @param params
	 * @return 原生ResultSet数据集合
	 * @throws SQLException
	 */
	public abstract ResultSet queryForResultSet(String sql, Object[] params) throws SQLException;

	/**
	 * select功能
	 *
	 * @param sql
	 * @return 原生ResultSet数据集合
	 * @throws SQLException
	 */
	public abstract ResultSet queryForResultSet(String sql) throws SQLException;

	/**
	 * select功能
	 *
	 * @param sql
	 * @param params
	 * @return List<?>数据集合
	 * @throws SQLException
	 */
	public abstract List<?> queryForBean(String sql, Object[] params, RowMapper<?> mapper) throws SQLException;

	/**
	 * select功能
	 *
	 * @param sql
	 * @param params
	 * @return List<?>数据集合
	 * @throws SQLException
	 */
	public abstract List<?> queryForBean(String sql, RowMapper<?> mapper) throws SQLException;

	/**
	 * select功能
	 *
	 * @param sql
	 * @param params
	 * @return List<Map<String, Object>>数据集合
	 * @throws SQLException
	 */
	public abstract List<Map<String, Object>> queryForMap(String sql, Object[] params) throws SQLException;

	/**
	 * select功能
	 *
	 * @param sql
	 * @param params
	 * @return List<Map<String, Object>>数据集合
	 * @throws SQLException
	 */
	public abstract List<Map<String, Object>> queryForMap(String sql) throws SQLException;

	/**
	 * select功能
	 *
	 * @param sql
	 * @return 统计单列记录数
	 * @throws SQLException
	 */
	public abstract int queryForInt(String sql, Object[] params) throws SQLException;

	/**
	 * select功能
	 *
	 * @param sql
	 * @return 统计单列记录数
	 * @throws SQLException
	 */
	public abstract int queryForInt(String sql) throws SQLException;

	/**
	 * 释放Connection资源
	 *
	 * @param x
	 */
	public abstract void free(Connection x);

	/**
	 * 释放Statement资源
	 *
	 * @param x
	 */
	public abstract void free(Statement x);

	/**
	 * 释放PreparedStatement资源
	 *
	 * @param x
	 */
	public abstract void free(PreparedStatement x);

	/**
	 * 释放ResultSet资源
	 *
	 * @param x
	 */
	public abstract void free(ResultSet x);

	/**
	 * 设置数据源
	 *
	 * @param dataSource
	 */
	public abstract void setDataSource(DataSource dataSource);

	/**
	 * 获取数据库链接
	 *
	 * @return Connection
	 */
	public abstract Connection getConnection();

	/**
	 * 获取数据库链接
	 *
	 * @param autoCommit
	 * @return Connection
	 */
	public Connection getConnection(boolean autoCommit);

}

3.实现我们接口里面的方法

package org.framework.mvc.jdbc.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.framework.mvc.jdbc.JdbcOperation;
import org.framework.mvc.jdbc.bean.RowMapper;

/**
 * 简易JDBC实现类
 *
 * @author shadow
 *
 */
public class SimpleJdbc implements JdbcOperation {

	private static final boolean AUTO_COMMIT = true;

	private DataSource dataSource;

	public SimpleJdbc() {

	}

	public SimpleJdbc(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	public Connection getConnection() {
		return getConnection(AUTO_COMMIT);
	}

	public Connection getConnection(boolean autoCommit) {
		try {
			Connection conn = dataSource.getConnection();
			if (!autoCommit)
				conn.setAutoCommit(autoCommit);
			return conn;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public int execute(String sql, Object[] params) throws SQLException {
		Connection conn = getConnection(false);
		PreparedStatement stmt = null;
		int result = -1;
		try {
			stmt = createPreparedStatement(conn, sql, params);
			stmt.execute();
			conn.commit();
		} catch (Exception e) {
			conn.rollback();
			e.printStackTrace();
		} finally {
			free(stmt);
			free(conn);
		}
		return result;
	}

	@Override
	public int execute(String sql) throws SQLException {
		return execute(sql, new Object[] {});
	}

	@Override
	public ResultSet queryForResultSet(String sql, Object[] params) throws SQLException {
		Connection conn = getConnection();
		PreparedStatement stmt = null;
		try {
			stmt = createPreparedStatement(conn, sql, params);
			return stmt.executeQuery();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			free(stmt);
			free(conn);
		}
		return null;
	}

	@Override
	public ResultSet queryForResultSet(String sql) throws SQLException {
		return queryForResultSet(sql, new Object[] {});
	}

	@Override
	public int queryForInt(String sql, Object[] params) throws SQLException {
		Connection conn = getConnection();
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			stmt = createPreparedStatement(conn, sql, params);
			rs = stmt.executeQuery();
			while (rs.next()) {
				return rs.getInt(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			free(rs);
			free(stmt);
			free(conn);
		}
		return 0;
	}

	@Override
	public int queryForInt(String sql) throws SQLException {
		return queryForInt(sql, new Object[] {});
	}

	@Override
	public List<?> queryForBean(String sql, Object[] params, RowMapper<?> mapper) throws SQLException {
		Connection conn = getConnection();
		PreparedStatement stmt = null;
		ResultSet rs = null;
		List<Object> list = null;
		try {
			stmt = createPreparedStatement(conn, sql, params);
			rs = stmt.executeQuery();
			list = new ArrayList<Object>();
			while (rs.next()) {
				list.add(mapper.mapRow(rs));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			free(rs);
			free(stmt);
			free(conn);
		}
		return list;
	}

	@Override
	public List<?> queryForBean(String sql, RowMapper<?> mapper) throws SQLException {
		return queryForBean(sql, new Object[] {}, mapper);
	}

	@Override
	public List<Map<String, Object>> queryForMap(String sql, Object[] params) throws SQLException {
		Connection conn = getConnection();
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			stmt = createPreparedStatement(conn, sql, params);
			rs = stmt.executeQuery();

			List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
			Map<String, Object> map = null;
			ResultSetMetaData rsd = rs.getMetaData();
			int columnCount = rsd.getColumnCount();

			while (rs.next()) {
				map = new HashMap<String, Object>(columnCount);
				for (int i = 1; i < columnCount; i++) {
					map.put(rsd.getColumnName(i), rs.getObject(i));
				}
				list.add(map);
			}

			return list;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			free(rs);
			free(stmt);
			free(conn);
		}
		return null;
	}

	@Override
	public List<Map<String, Object>> queryForMap(String sql) throws SQLException {
		return queryForMap(sql, new Object[] {});
	}

	@Override
	public int executeBatch(String sql, List<Object[]> params) throws SQLException {
		int result = 0;
		Connection conn = getConnection(false);
		PreparedStatement stmt = null;
		try {
			stmt = conn.prepareStatement(sql);
			for (int i = 0; i < params.size(); i++) {
				Object[] param = params.get(i);
				for (int j = 0; j < param.length; j++)
					stmt.setObject(j + 1, param[j]);
				stmt.addBatch();
				if (i % 1000 == 0) {
					stmt.executeBatch();
					stmt.clearBatch();
				}
			}
			stmt.executeBatch();
			conn.commit();
			result = params.size();
		} catch (Exception e) {
			conn.rollback();
			e.printStackTrace();
		} finally {
			free(stmt);
			free(conn);
		}
		return result;
	}

	@Override
	public int executeBatch(String sql) throws SQLException {
		return executeBatch(sql, new ArrayList<Object[]>());
	}

	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	@Override
	public void free(Connection x) {
		if (x != null)
			try {
				x.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
	}

	@Override
	public void free(Statement x) {
		if (x != null)
			try {
				x.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
	}

	@Override
	public void free(PreparedStatement x) {
		if (x != null)
			try {
				x.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
	}

	@Override
	public void free(ResultSet x) {
		if (x != null)
			try {
				x.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
	}

	private PreparedStatement createPreparedStatement(Connection conn, String sql, Object[] params) throws SQLException {
		PreparedStatement stmt = conn.prepareStatement(sql);
		for (int i = 0; i < params.length; i++)
			stmt.setObject(i + 1, params[i]);
		return stmt;
	}

}

4.然后实现我们一个连接池吧,不喜欢dbcp,c3p0的话,那些要依赖包的导致项目重量上去了

package org.framework.mvc.jdbc.source;

import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

import javax.sql.DataSource;

/**
 * 简易连接池实现类
 *
 * @author shadow
 *
 */
public class SimpleDataSource implements DataSource {

	private int poolSize = 5;// 默认为5个

	private LinkedList<Connection> pool = new LinkedList<Connection>();

	public SimpleDataSource(String driver, String url, String name, String pwd) {
		this(driver, url, name, pwd, 5);
	}

	public SimpleDataSource(String driver, String url) {
		this(driver, url, "", "", 5);
	}

	public SimpleDataSource(String driver, String url, String name, String pwd, int poolSize) {
		try {
			Class.forName(driver);
			this.poolSize = poolSize;
			if (poolSize <= 0) {
				throw new RuntimeException("初始化池大小失败: " + poolSize);
			}

			for (int i = 0; i < poolSize; i++) {
				Connection con = DriverManager.getConnection(url, name, pwd);
				con = ConnectionProxy.getProxy(con, pool);// 获取被代理的对象
				pool.add(con);// 添加被代理的对象
			}
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}

	}

	/** 获取池大小 */
	public int getPoolSize() {
		return poolSize;

	}

	/** 不支持日志操作 */
	public PrintWriter getLogWriter() throws SQLException {
		throw new RuntimeException("Unsupport Operation.");
	}

	public void setLogWriter(PrintWriter out) throws SQLException {
		throw new RuntimeException("Unsupport operation.");
	}

	/** 不支持超时操作 */
	public void setLoginTimeout(int seconds) throws SQLException {
		throw new RuntimeException("Unsupport operation.");
	}

	public int getLoginTimeout() throws SQLException {
		return 0;
	}

	@SuppressWarnings("unchecked")
	public <T> T unwrap(Class<T> iface) throws SQLException {
		return (T) this;
	}

	public boolean isWrapperFor(Class<?> iface) throws SQLException {
		return DataSource.class.equals(iface);
	}

	/** 从池中取一个连接对象,使用了同步和线程调度 */
	public Connection getConnection() throws SQLException {
		synchronized (pool) {
			if (pool.size() == 0) {
				try {
					pool.wait();
				} catch (InterruptedException e) {
					throw new RuntimeException(e.getMessage(), e);
				}
				return getConnection();
			} else {
				return pool.removeFirst();
			}
		}
	}

	public Connection getConnection(String username, String password) throws SQLException {
		throw new RuntimeException("不支持接收用户名和密码的操作");
	}

	/** 实现对Connection的动态代理 */
	static class ConnectionProxy implements InvocationHandler {

		private Object obj;
		private LinkedList<Connection> pool;

		private ConnectionProxy(Object obj, LinkedList<Connection> pool) {
			this.obj = obj;
			this.pool = pool;
		}

		public static Connection getProxy(Object o, LinkedList<Connection> pool) {
			Object proxed = Proxy.newProxyInstance(o.getClass().getClassLoader(), new Class[] { Connection.class },
					new ConnectionProxy(o, pool));
			return (Connection) proxed;
		}

		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			if (method.getName().equals("close")) {
				synchronized (pool) {
					pool.add((Connection) proxy);
					pool.notify();
				}
				return null;
			} else {
				return method.invoke(obj, args);
			}
		}

	}

}

5.开始测试下我们刚刚写的玩意,simplejdbc主要是有datasource提供给他就可以了,其他的一律无视,测试里面的user对象我就不提供,里面就是两个属性,id和username,然后生成set和get方法即可,当然这个是演示resultset转成bean的,当然也可以直接使用queryForMap直接查询出map集合,我想接口提供的方法已经足够使用了

public static void main(String[] args) throws SQLException {
		SimpleDataSource dataSource = new SimpleDataSource("org.sqlite.JDBC", "jdbc:sqlite:/E:p1010.db");
		SimpleJdbc jdbc = new SimpleJdbc(dataSource);
		List<User> list = (List<User>) jdbc.queryForBean("select * from t_user", new RowMapper<User>() {
			User user = null;

			@Override
			public User mapRow(ResultSet rs) throws SQLException {
				user = new User();
				user.setId(rs.getInt("id"));
				user.setUsername(rs.getString("username"));
				return user;
			}
		});
		for (User user : list) {
			System.out.println(user.getId() + "---" + user.getUsername());
		}
	}

简易高重用的jdbcutils工具封装实现类以及简易连接池实现,布布扣,bubuko.com

时间: 2024-10-12 20:03:49

简易高重用的jdbcutils工具封装实现类以及简易连接池实现的相关文章

day17(JDBC入门&jdbcUtils工具介绍)

day17 JDBC整体思维导图 JDBC入门 导jar包:驱动! 加载驱动类:Class.forName("类名"); 给出url.username.password,其中url背下来! 使用DriverManager类来得到Connection对象! ? ? ? 1 什么是JDBC JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库.原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java

能做事务的JdbcUtils工具

JdbcUtils工具类的封装 package cn.wht.utils; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class JdbcUtils { private static DataSource dataSource=null; //数据源 p

通过jdbc完成单表的curd操作以及对JDBCUtils的封装

概述:jdbc是oracle公司制定的一套规范(一套接口),驱动是jdbc的实现类,由数据库厂商提供.所以我们可以通过一套规范实现对不同的数据库操作(多态) jdbc的作用:连接数据库,发送sql语句,处理结果 curd操作:它代表创建(Create).更新(Update).读取(Retrieve)和删除(Delete)操作 jdbc操作步骤: 1.数据库和表 在这里,用exercise数据库下的student表. 2.创建一个项目 由于是在javase版本的ecplise下创建的,lib文件夹

JDBC:编写通用的 JDBCUtils工具类

基本上已经可以应付常用方法 1.为JDBCUtils 添加事务处理方法 2.处理多线程并发访问问题 package cn.cil.Utls; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; /** * 编写通用的 JDB

自己编写高负荷测试的工具

最近一个项目,客户要求进行高负荷测试:所谓高负荷测试时看系统在CPU占用或MEM占用率极高情况下的表现. 在第一轮测试时,我们通过在LINUX操作系统上,用压缩和解压缩的方法去占用CPU,这样的方法有个弊端,就是比较耗时而且不可控. 在这样的测试情况下,客户非常不满意.提出了很多的问题. 还要客户给了第二轮测试的机会,然后我就通过百度或谷歌,寻找高负荷测试的工具.结果一无所获.我后来想做为一个程序员,是否可以自己动手写一个这样的程序呢? 通过分析原理,占用CPU,就是让CPU可劲的进行运算:占用

JavaWeb基础之JdbcUtils工具类2.0

使用c3p0连接池来改版JdbcUtils工具 1. 使用c3p0连接池获取连接,使代码更加简单 1 /** 2 * 使用c3p0连接池做小工具 3 * JdbcUtils v2.0 4 * @author hui.zhang 5 * 6 */ 7 public class JdbcUtils { 8 // 配置文件的默认配置,必须给出c3p0-config.xml 9 private static ComboPooledDataSource dataSource = new ComboPool

Java IO流 之 File 工具封装 FileUtil

http://www.verejava.com/?id=17160016947046 public class Test2 { public static void main(String[] args) { FileUtil.createFile("test2.txt"); FileUtil.renameFile("test2.txt", "newTest2.txt"); FileUtil.deleteFile("newTest2.t

MySQL高可用复制管理工具 —— Orchestrator介绍

背景 在MySQL高可用架构中,目前使用比较多的是Percona的PXC,Galera以及MySQL 5.7之后的MGR等,其他的还有的MHA,今天介绍另一个比较好用的MySQL高可用复制管理工具:Orchestrator(orch). Orchestrator(orch):go编写的MySQL高可用性和复制拓扑管理工具,支持复制拓扑结构的调整,自动故障转移和手动主从切换等.后端数据库用MySQL或SQLite存储元数据,并提供Web界面展示MySQL复制的拓扑关系及状态,通过Web可更改MyS

二次封装Response类、views:视图 generics:工具视图 mixins:视图工具集 viewsets:视图集

## 二次封装Response类 Response({ 'status': 0, 'msg': 'ok', 'results': [], 'token': '' # 有这样的额外的key-value数据结果 },status=http_status,headers=headers,exception=True|False) APIResponse() => Response({'status': 0,'msg': 'ok'}) """ ``` from rest_fra