JavaWeb——jdbc与dbcp数据库连接

来源:互联网 发布:js注释 编辑:程序博客网 时间:2024/05/16 15:40

一、引言


      最近在学习使用mybatis调用数据库,顺便总结了下java连接数据库的历史发展。从非常传统的jdbc连接,到数据库连接池(dbcp、c3p0)封装后的jdbc连接,再到各种框架对数据库连接池的封装使用,在这个过程中无不透漏着前人的智慧,我们不仅仅限于享受着现有的便利,应该把这些过程都亲自走一遍,体会其中的过程演化==



二、jdbc数据库连接


      jdbc相信大家都比较清楚了,是java也就是oracle公司为各大数据库制订了一个类似抽象类或者接口的规范,然后mysql、oracle、postsql等数据库按照这个规范写的实现类。jdbc是最原始的数据库连接方式,也是用户控制程度最高的方式。使用的时候只需到该数据库官网下载对应的jdbc一个包就可以了。


代码:

JDBCTest类

import java.sql.Connection;import java.sql.Date;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class JDBCTest {    public static Connection getConnection() throws SQLException,ClassNotFoundException {        /**         * 在加载这个类的时候,会执行静态代码块中的代码,将自己注册到DriverManager类中         */        Class.forName("com.mysql.jdbc.Driver");        String url = "jdbc:mysql://localhost:3306/flkt";        String username="root";        String password = "1234";        Connection conn = DriverManager.getConnection(url,username,password);        return conn;    }    public static void main(String[] args) {        try {            Connection conn = getConnection();            Statement sqlStatement = conn.createStatement();            String query = "select * from t_info";            ResultSet result = sqlStatement.executeQuery(query);            while(result.next()) {            Integer f_id = result.getInt("f_id");                String f_name = result.getString("f_name");                String f_blz = result.getString("f_blz");                System.out.println("f_id="+f_id+" f_name="+f_name+" f_blz="+f_blz);            }        } catch (SQLException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }}



三、dbcp数据库连接


      数据库是一种重要的资源,我们普通的做法是使用直连方法连接数据库,使用完毕后关闭连接。 一旦数据库链接频繁,这样的数据库连接方式会给数据库很大的压力,这样很容易导致数据库崩溃,然后项目网站也就瘫痪了。 正是针对这样的问题,出现了数据库连接池技术。

      先在数据库连接池中创建一定数量的connection等待连接,一旦有需要连接直接从里面取出,当connection释放重新将其放回到池里,当总连接数大于连接池中的connection时用户需要等待。


      以dbcp为例,使用的时候需要以下jar包

 



代码:

DBCPTest类

import java.io.FileInputStream;import java.io.IOException;import java.sql.Connection;import java.sql.Date;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;import javax.sql.DataSource;import org.apache.commons.dbcp.BasicDataSource;public class DBCPTest {private static DataSource dataSource;private static Connection con;public DBCPTest() {}public static Connection getConnection() {if (dataSource == null) {initDataSource();}try {con = dataSource.getConnection();print();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}return con;}public static void initDataSource() {FileInputStream is = null;Properties p = new Properties();String driverClassName = null;String url = null;String username = null;String password = null;int initialSize = 0;int minIdle = 0;int maxIdle = 0;int maxWait = 0;int maxActive = 0;try {String path = DBCPTest.class.getClass().getResource("/").getPath();is = new FileInputStream(path + "dbcp.properties");p.load(is);driverClassName = p.getProperty("dbcp.driverClassName");url = p.getProperty("dbcp.url");username = p.getProperty("dbcp.username");password = p.getProperty("dbcp.password");initialSize = Integer.parseInt(p.getProperty("dbcp.initialSize"));minIdle = Integer.parseInt(p.getProperty("dbcp.minIdle"));maxIdle = Integer.parseInt(p.getProperty("dbcp.maxIdle"));maxWait = Integer.parseInt(p.getProperty("dbcp.maxWait"));maxActive = Integer.parseInt(p.getProperty("dbcp.maxActive"));} catch (NumberFormatException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {try {is.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}BasicDataSource ds = new BasicDataSource();ds.setUrl(url);ds.setDriverClassName(driverClassName);ds.setUsername(username);ds.setPassword(password);ds.setInitialSize(initialSize); // 初始的连接数;ds.setMaxActive(maxActive);ds.setMinIdle(minIdle);ds.setMaxIdle(maxIdle);ds.setMaxWait(maxWait);ds.setRemoveAbandoned(true);ds.setRemoveAbandonedTimeout(2000);dataSource = ds;}/* 用于测试连接状态的方法 */public static void print() {BasicDataSource ds = (BasicDataSource) dataSource;System.out.println(ds.getInitialSize());System.out.println(ds.getNumActive());System.out.println(ds.getNumIdle());System.out.println(ds.getDefaultAutoCommit());}public static void main(String[] args) {Connection con;try {con = DBCPTest.getConnection();            Statement sqlStatement = con.createStatement();            String query = "select * from t_info";            ResultSet result = sqlStatement.executeQuery(query);            while(result.next()) {            Integer f_id = result.getInt("f_id");                String f_name = result.getString("f_name");                String f_blz = result.getString("f_blz");                System.out.println("f_id="+f_id+" f_name="+f_name+" f_blz="+f_blz);            }} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

dbcp.properties

dbcp.driverClassName=com.mysql.jdbc.Driverdbcp.url=jdbc:mysql://localhost:3306/flktdbcp.username=rootdbcp.password=1234dbcp.initialSize=1dbcp.minIdle=1dbcp.maxIdle=10dbcp.maxWait=1000dbcp.maxActive=30


属性说明:


属性名属性描述属性值driverClassName使用的JDBC的完整的有
效的java类名称
com.mysql.jdbc.Driverurl传递给JDBC驱动的用于建立连接的urljdbc:mysql://localhost:3306/test?
useUnicode=true&characterEncoding=UTF-8
username传递给JDBC驱动用于建立连接的用户名myoraclepassword传递给JDBC驱动用于建立连接的密码myoraclemaxActive最大活动连接数:连接池在同一时间能够
分配的最大活动连接的数量,
如果设置为非正数,则表示不受限制
30maxIdle最大空闲连接数:连接池中容许保持最大
空闲状态的最大链接数量,操作的空闲连接将被释放,
如果设置为负数表示不受限制
10minIdle最小空闲连接数:连接池中容许保持最小
空闲状态的最大链接数量,操作的空闲连接将被释放,
如果设置为负数表示不受限制
1maxWait最大等待时间:当没有可用连接时,连接池等待
连接被归还的最大(以毫秒计数),超过时间则抛出异常,
如果设置为-1则表示无限等待
1000initialSize初始连接:池启动时创建的连接数量1logAbandoned连接被泄露时是否打印trueremoveAbandoned是否自动回收超时连接trueremoveAbandoned Timeout超时时间(以秒数为单位)10timeBetweenEvictionRunsMillis在空闲连接回收器线程运行期间休眠的时间值,
以毫秒为单位
1000numTestsPerEvictionRun在每次空闲连接回收器线程(如果有)运行时检查的连接数量10minEvictableIdleTimeMillis连接在池中保持空闲而不被空闲连接回收器线程10000


四、一些问题


      mybatis为了解决jdbc的一些问题进行了一下处理

1、将sql语句硬编码到java代码中,如果修改sql语句,需要修改java代码,重新编译。系统可维护性不高。

设想如何解决?(将sql单独 配置在配置文件中)

2、数据库连接频繁开启和释放,对数据库的资源是一种浪费。

设想如何解决?(使用数据库连接池管理数据库连接)

3、向preparedStatement中占位符的位置设置参数时,存在硬编码(占位符的位置,设置的变量值)

设想如何解决?(能否也通过配置的方式,配置设置的参数,自动进行设置参数)

4、解析结果集时存在硬编码(表的字段名、字段的类型)




五、总结


  • jdbc连接数据库

  • dbcp连接数据库

  • jdbc连接数据库的问题


附加下载地址:点击打开链接