【JAVA高级】——Druid连接池和Apache的DBUtils使用

在这里插入图片描述

💖 Druid连接池

【1】连接池思想

  在程序初始化时提前创建好指定数量的数据库连接对象存储在“池子”中这个池子称为“连接池”当需要连接数据库的时候从这个“池子”中取出一个连接对象使用使用完毕后不会将这个连接对象关闭而是将这个连接对象放回“池子”中实现复用节省资源。

【2】Druid连接池使用步骤

 2.1 引入相关jar包

  在lib文件夹中引入druid-1.1.5.jar文件和mysql-connector-java-5.1.0-bin.jar文件并将两个jar文件配置到项目中。

 2.2 创建database.properties配置文件

在src文件夹下创建database.properties配置文件配置文件中内容如下
连接设置
初始化连接连接池连接对象数量
最大连接数
最小空闲连接
超时等待时间毫秒为单位
# 连接设置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdatabase
username=root
password=123456

# 初始化连接连接池连接对象数量
initialSize=10

#最大连接数
maxActive=30

#最小空闲连接
maxIdle=5

#超时等待时间毫秒为单位
maxWait=3000

 2.3 编写连接池工具类

  声明一个连接池对象

实例化配置文件对象
加载配置文件内容
创建连接池
获取连接对象
通过连接池获得连接对象
释放资源将连接对象放入连接池中
使用完连接对象后将连接对象还给连接池,这里的close()方法是DruidPooledConnection实现类里的close()方法将connection连接对象还给连接池
package com.cxyzxc.www.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

public class DBUtils {

	// 声明一个连接池对象
	private static DruidDataSource druidDataSource;

	static {
		// 实例化配置文件对象
		Properties properties = new Properties();

		try {
			// 加载配置文件内容
			InputStream is = DBUtils.class
					.getResourceAsStream("/database.properties");
			properties.load(is);
			// 创建连接池
			druidDataSource = (DruidDataSource) DruidDataSourceFactory
					.createDataSource(properties);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 获取连接对象
	public static Connection getConnection() {
		try {
			// 通过连接池获得连接对象
			return druidDataSource.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	// 释放资源将连接对象放入连接池中
	public static void closeAll(Connection connection, Statement statement,
			ResultSet resultSet) {
		try {
			if (resultSet != null) {
				resultSet.close();
			}
			if (statement != null) {
				statement.close();
			}

			if (connection != null) {
				// 使用完连接对象后将连接对象还给连接池,这里的close()方法是DruidPooledConnection实现类里的close()方法将connection连接对象还给连接池
				connection.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

}

【3】Druid连接池测试

package com.cxyzxc.www.utils;

import java.sql.Connection;

public class Test {

	public static void main(String[] args) {

		// 获取20个连接对象输出连接对象地址值不同
		for (int i = 1; i <= 20; i++) {
			Connection connection = DBUtils.getConnection();
			System.out.println(connection);

			// 调用关闭连接对象的方法后发现获取的20个连接对象地址值是同一个说明每次从连接池中取出的连接对象是同一个
			// DBUtils.closeAll(connection, null, null);
		}
	}
}

💖 Apache的DBUtils使用

  前面的DBUtils工具类是我们经过千难万阻自己封装的也有一些组织给我们封装DBUtils工具类比如Apache组织提供了一个对JDBC进行简单封装的开源工具类库Commons DbUtils类使用它能够简化JDBC应用程序的开发同时也不影响程序的性能。

【1】Apache DBUtils介绍

 1.1 Apache DBUtils特征

Apache DBUtils是java编程中的数据库操作实用工具小巧简单实用主要特征有
1对于数据表的读操作他可以把结果转换成ListArraySet等java集合便于程序员操作
2对于数据表的写操作也变得很简单只需写sql语句
3可以使用数据源使用JNDI数据库连接池等技术来优化性能–重用已经构建好的数据库连接对象而不像phpasp那样费时费力的不断重复的构建和析构这样的对象。

 1.2 Apache DbUtils主要组成

1ResultSetHandler接口转换类型接口
BeanHandler类实现类把一条记录转换成对象。
BeanListHandler类实现类把多条记录转换成List集合。
ScalarHandler类实现类适合获取一行一列的数据。
2QueryRunner类执行SQL语句的类
update()方法增、删、改
query()方法查询

 1.3 Apache DbUtils使用步骤

1创建lib文件夹导入需要的jar包并将其配置到项目中
mysql-connector-java-5.1.0-bin.jar
druid-1.1.5.jar
commons-dbutils-1.7.jar
2在src文件夹下创建database.properties配置文件配置文件中内容如下
连接设置
初始化连接连接池连接对象数量
最大连接数
最小空闲连接
超时等待时间毫秒为单位
# 连接设置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdatabase
username=root
password=123456

# 初始化连接连接池连接对象数量
initialSize=10

#最大连接数
maxActive=30

#最小空闲连接
maxIdle=5

#超时等待时间毫秒为单位
maxWait=3000

3编写DBUtils连接池工具类

  声明一个连接池对象

实例化配置文件对象
加载配置文件内容
创建连接池

  返回一个数据源

package com.cxyzxc.www.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

public class DBUtils {

	// 声明一个连接池对象
	private static DruidDataSource druidDataSource;

	static {
		// 实例化配置文件对象
		Properties properties = new Properties();

		try {
			// 加载配置文件内容
			InputStream is = DBUtils.class
					.getResourceAsStream("/database.properties");
			properties.load(is);
			// 创建连接池
			druidDataSource = (DruidDataSource) DruidDataSourceFactory
					.createDataSource(properties);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//返回一个数据源
	public static DataSource getDataSource(){
		return druidDataSource;
	}

}

【2】综合案例

2.1 创建product表

CREATE TABLE IF NOT EXISTS `product` (
`pid` INT PRIMARY KEY AUTO_INCREMENT COMMENT '产品编号',
`pname` VARCHAR(20) NOT NULL COMMENT '产品名称',
`price` DOUBLE NOT NULL COMMENT '产品价格',
`birthday` DATE NOT NULL COMMENT '产品生产日期'
);

2.2 向表中添加数据

INSERT INTO `product`(`pid`,`pname`,`price`,`birthday`)VALUES(1001,'虎皮凤爪',20.5,'2022-06-12');

INSERT INTO `product`(`pid`,`pname`,`price`,`birthday`)VALUES(1002,'卧龙锅巴',18.5,'2022-09-22');

2.3 创建实体类Product

  • 添加实体类的私有变量
  • 添加有参无参构造方法
  • 添加get/set方法
  • 重写toString()方法
package com.cxyzxc.www.entity;

import java.util.Date;

public class Product {

	private int pid;

	private String pname;

	private double price;

	private Date birthday;

	public Product() {
		super();
	}

	public Product(String pname, double price, Date birthday) {
		super();
		this.pname = pname;
		this.price = price;
		this.birthday = birthday;
	}

	public Product(int pid, String pname, double price, Date birthday) {
		super();
		this.pid = pid;
		this.pname = pname;
		this.price = price;
		this.birthday = birthday;
	}

	public int getPid() {
		return pid;
	}

	public void setPid(int pid) {
		this.pid = pid;
	}

	public String getPname() {
		return pname;
	}

	public void setPname(String pname) {
		this.pname = pname;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	@Override
	public String toString() {
		return "Product [pid=" + pid + ", pname=" + pname + ", price=" + price
				+ ", birthday=" + birthday + "]";
	}

}

2.4 创建ProductDao接口

创建ProductDao接口实现增删改查方法名的统一。

package com.cxyzxc.www.dao;

import java.util.List;

import com.cxyzxc.www.entity.Product;

public interface ProductDao {
	
	//添加
	int insert(Product product);
	
	//删除
	int delete(int pid);
	
	//修改
	int update(Product product);
	
	//查询单个
	Product selectOne(int pid);
	
	//查询所有
	List<Product> selectAll();

}

2.5 创建ProductDaoImpl实现类

创建ProductDaoImpl实现类来实现ProductDao接口在重新方法中编写具体的逻辑代码。

package com.cxyzxc.www.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import com.cxyzxc.www.dao.ProductDao;
import com.cxyzxc.www.entity.Product;
import com.cxyzxc.www.utils.DBUtils;
import com.cxyzxc.www.utils.DateUtils;

public class ProductDaoImpl implements ProductDao {
	// 创建QueryRunner对象并传递一个数据源对象
	private QueryRunner queryRunner = new QueryRunner(DBUtils.getDataSource());

	@Override
	public int insert(Product product) {

		String sql = "INSERT INTO `product`(`pname`,`price`,`birthday`)VALUES(?,?,?);";
		Object[] args = { product.getPname(), product.getPrice(),
				DateUtils.utilDateToSqlDate(product.getBirthday()) };

		try {
			return queryRunner.update(sql, args);
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return 0;
	}

	@Override
	public int delete(int pid) {
		String sql = "DELETE FROM `product` WHERE `pid` = ?;";
		try {
			return queryRunner.update(sql, pid);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return 0;
	}

	@Override
	public int update(Product product) {

		String sql = "UPDATE `product` SET `pname` = ?,`price`=?,`birthday`=? WHERE `pid`=?;";

		Object[] args = { product.getPname(), product.getPrice(),
				DateUtils.utilDateToSqlDate(product.getBirthday()),
				product.getPid() };

		try {
			return queryRunner.update(sql, args);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return 0;
	}

	@Override
	public Product selectOne(int pid) {
		// 查询一个数据使用BeanHandler将记录转换为对象
		BeanHandler<Product> product = new BeanHandler<Product>(Product.class);
		String sql = "SELECT * FROM `product` WHERE `pid`=?;";
		try {
			return queryRunner.query(sql, product, pid);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public List<Product> selectAll() {
		// 查询一个数据使用BeanHandler将记录转换为对象
		BeanListHandler<Product> productList = new BeanListHandler<Product>(Product.class);
		String sql = "SELECT * FROM `product`;";
		try {
			return queryRunner.query(sql, productList);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

}

2.6 创建ProductService接口

创建ProductService接口来实现业务层增删改查方法名的统一。

package com.cxyzxc.service;

import java.util.List;

import com.cxyzxc.www.entity.Product;

public interface ProductService {
	//增加
	int addProduct(Product product);
	
	//删除
	int deleteProduct(int pid);
	
	//修改
	int updateProduct(Product product);
	
	//查询单个
	Product selectOneProduct(int pid);
	
	//查询所有
	List<Product> selectAllProduct();
	

}

2.7 创建ProductServiceImpl实现类

创建ProductServiceImpl实现类来实现ProductService接口。

package com.cxyzxc.service.impl;

import java.util.List;

import com.cxyzxc.service.ProductService;
import com.cxyzxc.www.dao.ProductDao;
import com.cxyzxc.www.dao.impl.ProductDaoImpl;
import com.cxyzxc.www.entity.Product;

public class ProductServiceImpl implements ProductService {
	ProductDao productDao = new ProductDaoImpl();

	@Override
	public int addProduct(Product product) {
		// 查询添加的商品是否存在
		Product pd = productDao.selectOne(product.getPid());
		if (pd == null) {
			return productDao.insert(product);
		} else {
			System.out.println("商品已经存在不能重复添加");
		}

		return 0;
	}

	@Override
	public int deleteProduct(int pid) {
		// 查询添加的商品是否存在
		Product pd = productDao.selectOne(pid);
		if (pd != null) {
			return productDao.delete(pid);
		} else {
			System.out.println("商品不存在不能删除");
		}
		return 0;
	}

	@Override
	public int updateProduct(Product product) {
		// 查询添加的商品是否存在
		Product pd = productDao.selectOne(product.getPid());
		if (pd!= null) {
			return productDao.update(product);
		} else {
			System.out.println("商品不存在不能修改");
		}
		return 0;
	}

	@Override
	public Product selectOneProduct(int pid) {
		Product product =productDao.selectOne(pid);
		if(product!=null){
			return product;
		}else{
			System.out.println("没有你要查找产品查找失败");
		}
		return null;
	}

	@Override
	public List<Product> selectAllProduct() {
		 List<Product> productList = productDao.selectAll();
		 if(productList.size()!=0){
			 return productList;
		 }else{
			 System.out.println("数据库为空没有产品");
		 }
		return null;
	}

}

2.8 创建测试类

2.8.1 测试插入数据

package com.cxyzxc.www.view;

import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;
import com.cxyzxc.www.utils.DateUtils;

public class Test01InsertProduct {

	public static void main(String[] args) {
		//创建ProductService引用指向ProductServiceImpl实现类
		ProductService productService = new ProductServiceImpl();

		//增加产品
		 Product product = new Product(1003,"流心威化饼干", 13.5, DateUtils.strDateToUtilDate("2022-11-10"));
		 
		 int result = productService.addProduct(product);
		 
		 String str = result==1?"商品添加成功":"商品添加失败";
		 System.out.println(str);

	}

}

2.8.2 测试删除数据

package com.cxyzxc.www.view;

import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;

public class Test02DeleteProduct {

	public static void main(String[] args) {
		// 创建ProductService引用指向ProductServiceImpl实现类
		ProductService productService = new ProductServiceImpl();

		int result = productService.deleteProduct(1003);

		String str = result == 1 ? "删除成功" : "删除失败";
		System.out.println(str);

	}

}

2.8.3 测试修改数据

package com.cxyzxc.www.view;

import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;
import com.cxyzxc.www.utils.DateUtils;

public class Test03UpdateProduct {

	public static void main(String[] args) {
		// 创建ProductService引用指向ProductServiceImpl实现类
		ProductService productService = new ProductServiceImpl();

		// 增加产品
		Product product = new Product(1002, "流心威化饼干", 13.5,
				DateUtils.strDateToUtilDate("2022-11-10"));

		int result = productService.updateProduct(product);
		String str = result == 1 ? "修改成功" : "修改失败";
		System.out.println(str);

	}

}

2.8.4 测试查询一条数据

package com.cxyzxc.www.view;

import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;

public class Test04SelectOneProduct {

	public static void main(String[] args) {
		// 创建ProductService引用指向ProductServiceImpl实现类
		ProductService productService = new ProductServiceImpl();

		Product product = productService.selectOneProduct(1003);

		if (product != null) {
			System.out.println(product);
		} else {
			System.out.println("你要查询的商品不存在");
		}

	}

}

2.8.5 测试查询所有数据

package com.cxyzxc.www.view;

import java.util.List;

import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;

public class Test05SelectAllProduct {

	public static void main(String[] args) {
		// 创建ProductService引用指向ProductServiceImpl实现类
		ProductService productService = new ProductServiceImpl();

		List<Product> productList = productService.selectAllProduct();
		for (int i = 0; i < productList.size(); i++) {
			System.out.println(productList.get(i));
		}
	}
}

💖 投票传送门

在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java