本文共 8495 字,大约阅读时间需要 28 分钟。
#(Notice:以下所有经验也是我根据网上的经验整理的,如有侵权可以联系我删除,Wx:IT_Ezra,QQ 654303408。 有问题讨论也可联系我,QQ同上。)
#(PS:为什么要用到JDBC原生态写法。首先,对于大多数项目来说,现在基本上都是用市面上封装好的开源框架,但是我们仍然需要了解JDBC,因为JDBC是基础,所有的开源框架都是基于最原始的JDBC封装加强的,而对于JDBC的使用场景,还是有一席之地的,因为线程池的存在。首先我们知道,事务是具有离子型,所以要保持线程安全,而通过线程池加上原生态的JDBC可以保证一定程度上的并发以及线程安全。)#项目结构图
#新建一个properites文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbctest username=root password=root jdbcPoolInitSize=10
#新建jdbc连接池工具类JdbcPool
>package com.test.util;import java.io.InputStream;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.sql.SQLFeatureNotSupportedException;import java.util.LinkedList;import java.util.Properties;import java.util.logging.Logger;import javax.sql.DataSource;//原生的jdbc连接池,加载jdbc.properties文件public class JdbcPool implements DataSource { /** * * @Field: listConnections 使用LinkedList集合来存放数据库链接, * 由于要频繁读写List集合,所以这里使用LinkedList存储数据库连接比较合适 */ private static LinkedListlistConnections = new LinkedList (); private static Connection conn; // 在静态代码块中加载src/jdbc.properties数据库配置文件 static { InputStream in = JdbcPool.class.getResourceAsStream("/jdbc.properties"); Properties prop = new Properties(); try { prop.load(in); String driver = prop.getProperty("driver"); String url = prop.getProperty("url"); String username = prop.getProperty("username"); String password = prop.getProperty("password");// 数据库连接池的初始化连接数大小 int jdbcPoolInitSize = Integer.parseInt(prop.getProperty("jdbcPoolInitSize"));// 加载数据库驱动 Class.forName(driver); for (int i = 0; i < jdbcPoolInitSize; i++) { conn = DriverManager.getConnection(url, username, password);// System.out.println("获取到了连接" + conn);// 将获取到的数据库连接加入到listConnections集合中,listConnections集合此时就是一个存放了数据库连接的连接池 listConnections.add(conn); } } catch (Exception e) { throw new ExceptionInInitializerError(e); } } /* * * 获取数据库连接 */ @Override public Connection getConnection() throws SQLException {//如果集合中没有数据库连接对象了,且创建的数据库连接对象没有达到最大连接数量,可以再创建一组数据库连接对象以备使用 if(linkedlist1.size()==0&&max<=5){ try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i=0;i 0){ //从linkedlist集合中取出一个数据库链接对象Connection使用 Connection conn1=linkedlist1.removeFirst(); System.out.println("linkedlist1数据库连接池大小是" + linkedlist1.size()); /*返回一个Connection对象,并且设置Connection对象方法调用的限制, *当调用connection类对象的close()方法时会将Connection对象重新收集放入linkedlist集合中。 */ return (Connection) Proxy.newProxyInstance(conn1.getClass().getClassLoader(),//这里换成JdbcConnectionsPool.class.getClassLoader();也行 conn1.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(!method.getName().equalsIgnoreCase("close")){ return method.invoke(conn1, args); }else{ linkedlist1.add(conn1); System.out.println(conn1+"对象被释放,重新放回linkedlist集合中!"); System.out.println("此时Linkedlist集合中有"+linkedlist1.size()+"个数据库连接对象!"); return null; } } }); }else{ System.out.println("连接数据库失败!"); } return null; } //省略@Override方法 @Override public PrintWriter getLogWriter() throws SQLException { // TODO Auto-generated method stub return null; } @Override public void setLogWriter(PrintWriter out) throws SQLException { // TODO Auto-generated method stub } @Override public void setLoginTimeout(int seconds) throws SQLException { // TODO Auto-generated method stub } @Override public int getLoginTimeout() throws SQLException { // TODO Auto-generated method stub return 0; } @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { // TODO Auto-generated method stub return null; } @Override public T unwrap(Class iface) throws SQLException { // TODO Auto-generated method stub return null; } @Override public boolean isWrapperFor(Class iface) throws SQLException { // TODO Auto-generated method stub return false; } @Override public Connection getConnection(String username, String password) throws SQLException { // TODO Auto-generated method stub return null; }}
#新建JDBCUtil工具类
package com.test.util; import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class JDBCUtil { private static JdbcPool pool = new JdbcPool(); /** * * 获取资源 */ public static Connection getConnection() throws SQLException { return pool.getConnection(); } /** * * 关闭资源 * * @param resultSet 查询返回的结果集,没有为空 * * @param statement * * @param connection */ public static void close(ResultSet resultSet, Statement statement, Connection connection) { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { throw new RuntimeException(e); } resultSet = null; } if (statement != null) { try { statement.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { throw new RuntimeException(e); } } }}#数据库操作package com.test.dao;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.test.util.JDBCUtil;public class JDBCDao { /** * * 增加,删除,修改 */ public static void insertOrDeleteOrUpdate(String sql) { try { Connection connection = JDBCUtil.getConnection(); PreparedStatement pst = connection.prepareStatement(sql); int execute = pst.executeUpdate(); System.out.println("执行语句:" + sql + "," + execute + "行数据受影响"); JDBCUtil.close(null, pst, connection); } catch (SQLException e) { System.out.println("异常提醒:" + e); } } /** * * 查询,返回结果集 */ public static List
java.lang.ClassCastException: com.sun.proxy.$Proxy4 cannot be cast to java.sql.Connection
转载地址:http://ovcii.baihongyu.com/