您的位置:首页 > 编程语言 > Java开发

JavaWeb——jdbc与dbcp数据库连接

2017-11-29 23:00 330 查看

一、引言

      最近在学习使用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 block
e.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 block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.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 block
e.printStackTrace();
}
}
}
dbcp.properties
dbcp.driverClassName=com.mysql.jdbc.Driver
dbcp.url=jdbc:mysql://localhost:3306/flkt
dbcp.username=root
dbcp.password=1234
dbcp.initialSize=1
dbcp.minIdle=1
dbcp.maxIdle=10
dbcp.maxWait=1000
dbcp.maxActive=30

属性说明:

属性名属性描述属性值
driverClassName使用的JDBC的完整的有

效的java类名称
com.mysql.jdbc.Driver
url传递给JDBC驱动的用于建立连接的urljdbc:mysql://localhost:3306/test?

useUnicode=true&characterEncoding=UTF-8
username传递给JDBC驱动用于建立连接的用户名myoracle
password传递给JDBC驱动用于建立连接的密码myoracle
maxActive最大活动连接数:连接池在同一时间能够

分配的最大活动连接的数量,

如果设置为非正数,则表示不受限制
30
maxIdle最大空闲连接数:连接池中容许保持最大

空闲状态的最大链接数量,操作的空闲连接将被释放,

如果设置为负数表示不受限制
10
minIdle最小空闲连接数:连接池中容许保持最小

空闲状态的最大链接数量,操作的空闲连接将被释放,

如果设置为负数表示不受限制
1
maxWait最大等待时间:当没有可用连接时,连接池等待

连接被归还的最大(以毫秒计数),超过时间则抛出异常,

如果设置为-1则表示无限等待
1000
initialSize初始连接:池启动时创建的连接数量1
logAbandoned连接被泄露时是否打印true
removeAbandoned是否自动回收超时连接true
removeAbandoned Timeout超时时间(以秒数为单位)10
timeBetweenEvictionRunsMillis在空闲连接回收器线程运行期间休眠的时间值,

以毫秒为单位
1000
numTestsPerEvictionRun在每次空闲连接回收器线程(如果有)运行时检查的连接数量10
minEvictableIdleTimeMillis连接在池中保持空闲而不被空闲连接回收器线程10000

四、一些问题

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

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

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

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

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

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

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

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

五、总结

jdbc连接数据库

dbcp连接数据库

jdbc连接数据库的问题

附加下载地址:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: