在JDBC(2)中,我们连接数据库,得到数据库连接,都需要建一个Connection类,编写方法去得到连接。
用户的每一次访问,我们都创建一个连接,用完后就关闭它,使用频率不高的这样也是能够接受的,但是对于一个运行系统来说是有点负担的,因为运行系统对数据的操作比较频繁,频繁开启,关闭 数据库连接,会极大的降低系统的性能,从而引发一些潜在的问题。
数据库连接池是什么?
数据库连接池的基本原理是在内部对象池中维护一定数量的数据库连接,并对外暴露数据库连接获取和返回的方法。
这样做的好处:连接复用【数据库连接池提供了一套高效的连接分配.使用策略. 最终实现连接的高效】,更快的响应速度,统一的连接管理,避免数据库连接泄露。
1. 通过JDBC使用C3P0连接池
(1)创建数据库表,一样
(2)创建java项目,导入C3PO依赖包
在此之前数据库驱动mysql-connector-java-5.1.38-bin.jar这个还是要导入到lib文件夹,这个操作和之前一样。
(3)在src下创建c3p0的配置文件【c3p0-config.xml】
配置文件写入代码:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- c3p0的默认配置项 -->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
<!-- 定义的数据库配置 -->
<named-config name="test">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">25</property>
<property name="maxPoolSize">200</property>
</named-config>
</c3p0-config>
(4)创建学生类
public class Student {
private int stuid;
private String stuname;
private int age;
private String stuaddress;
public int getStuid() {
return stuid;
}
public void setStuid(int stuid) {
this.stuid = stuid;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getStuaddress() {
return stuaddress;
}
public void setStuaddress(String stuaddress) {
this.stuaddress = stuaddress;
}
}
(5)创建数据库访问类
import java.sql.Connection;
import java.sql.PreparedStatement;
import com.mchange.v2.c3p0.ComboPooledDataSource;
//用户信息访问类
public class StudentDao {
private ComboPooledDataSource dataSource=null;
public StudentDao(){
//加载c3p0-config.xml
dataSource = new ComboPooledDataSource();
}
//添加操作
public boolean insertStudent(Student student){
boolean falg=false;
try{
Connection conn = dataSource.getConnection();
String sql="insert into t_student values(null,?,?,?);";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, student.getStuname());
ps.setInt(2, student.getAge());
ps.setString(3, student.getStuaddress());
int executeUpdate = ps.executeUpdate();
if(executeUpdate>0){
falg=true;
}
ps.close();
conn.close();
}catch(Exception e ){
e.printStackTrace();
}
return falg;
}
}
//测试类
public class Main {
public static void main(String[] args) {
StudentDao studentDao = new StudentDao();
Student student=new Student();
student.setStuname("zhangsan");
student.setAge(23);
student.setStuaddress("xian");
boolean flag = studentDao.insertStudent(student);
if(flag){
System.out.println("添加成功");
}
}
}
优点:不用手动编写创建数据库连接对象的操作,因为c3p0的数据库连接池的配置中已经配置初始化成功。提高程序的执行效率。 日后切换数据库的时候不需要修改源代码,只需要修改c3p0的数据库连接池的配置。
2. 通过JDBC使用dbcp连接池
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
(1)创建数据库表
(2)创建java项目导入dbcp的jar包
【commons-dbcp-1.4.jar
commons-dbutils-1.6.jar
commons-pool-1.6.jar】
(3)在src下创建数据库连接配置文件【xxxxxxxx.properties】
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
username=root
password=123456
maxActive=50
maxIdle=20
maxWait=60000
(4)创建数据库访问类
public class StudentDao {
private DataSource dataSource = null;
public StudentDao() {
try{
Properties pro=new Properties();
InputStream inStream=this.getClass().getResourceAsStream("/mydata.properties");
pro.load(inStream);
dataSource=BasicDataSourceFactory.createDataSource(pro);
}catch(Exception e){
e.printStackTrace();
}
}
其余添加删除等操作一样不变
3. JDBC访问Druid
Druid首先是一个数据库连接池。Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。Druid是阿里巴巴开发的号称为监控而生的数据库连接池!
同时Druid不仅仅是一个数据库连接池,它包括四个部分:
Druid是一个JDBC组件,它包括三个部分:
基于Filter-Chain模式的插件体系。
DruidDataSource 高效可管理的数据库连接池。
SQLParser
Druid的功能
1、替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。
2、可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。
3、数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。
4、SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。
5、扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。
所以Druid可以:
1、充当数据库连接池。
2、可以监控数据库访问性能
3、获得SQL执行日志
例:
1.创建数据库表
2.创建java项目,导入jar包【druid-1.1.10.jar】
3.在src下创建数据库连接配置文件【xxxxxxxx.properties】
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
initialSize=100
maxActive=300
maxWait=60000
Druid配置详解
DRUID连接池的实用 配置详解_zhangjinwei417的博客-优快云博客_druid连接池配置
4.创建javabean
5.创建数据库访问类
public class StudentDao {
private DataSource dataSource = null;
public StudentDao() {
try{
Properties pro=new Properties();
InputStream inStream=this.getClass().getResourceAsStream("/mydata.properties");
pro.load(inStream);
dataSource=DruidDataSourceFactory.createDataSource(pro);
}catch(Exception e){
e.printStackTrace();
}
}
相比于dbcp只改变了一个地方
dataSource=DruidDataSourceFactory.createDataSource(pro);
// 添加操作
public boolean insertStudent(Student student) {
boolean falg = false;
try {
Connection conn = dataSource.getConnection();
String sql = "insert into t_student values(null,?,?,?);";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, student.getStuname());
ps.setInt(2, student.getAge());
ps.setString(3, student.getStuaddress());
int executeUpdate = ps.executeUpdate();
if (executeUpdate > 0) {
falg = true;
}
ps.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
return falg;
}
//修改
public boolean updateStudent(Student student){
boolean flag=false;
try{
Connection conn=dataSource.getConnection();
String sql="update t_student set stu_namr=?,stu_age=?,stu_address=? where stu_id=?;";
PreparedStatement ps=conn.prepareStatement(sql);
ps.setString(1,student.getStuname());
ps.setInt(2,student.getAge());
ps.setString(3,student.getStuaddress());
ps.setInt(4,student.getStuid());
int temp=ps.executeUpdate();
if(temp>0){flag=true;}
ps.close();
conn.close();
}catch(Exception e){
e.printStackTrace();
}
return flag;
}
//删除操作
public boolean deleteStudent(int stuid){
boolean flag=false;
try{
Connection conn=dataSource.getConnection();
String sql="delete from t_student where stu_id=?;";
PreparedStatement ps=conn.prepareStatement(sql);
ps.setInt(1,stuid);
int temp=ps.executeUpdate();
if(temp>0){flag=true;}
ps.close();
conn.close();
}catch(Exception e){
e.printStackTrace();
}
return flag;
}
}